电商系统系统笔记之分布式搜索solrcloud

前言:

笔者曾经搭建过solr单机版服务,其实很多服务都有单机版,master-slave版,cloud版本。redis也是这样。

此文不讨论solr的环境搭建,主要是讨论solrcloud的应用场景,原理以及架构设计。


1. 什么是solr

Solr是以Lucene为基础实现的文本检索应用服务。Solr部署方式有单机方式、多机Master-Slaver方式、Cloud方式。

SolrCloud是基于Solr和Zookeeper的分布式搜索方案。当索引越来越大,一个单一的系统无法满足磁盘需求,查询速度缓慢,此时就需要分布式索引。在分布式索引中,原来的大索引,将会分成多个小索引,solr可以将这些小索引返回的结果合并,然后返回给客户端

2. Solr cloud 架构

solr cloud 逻辑结构:

* shard可以跨机器,redis分片的shard不夸机器,而是按照key crc16,求mod后存储在某个slot上。

*redis分布式架构中,每个机器都有副本,但是slor cloud是每个shard都有副本,每个副本集中仅有一个leader。

* Collection是统一的入口

工作模式


* core在一个集群里统一配置,core有两个角色:replica和leader,由zookeeper选举产生

* 接受到document后,根据hash计算发送到哪个shard。每一个shard都有一个hash区间每个shard下面的每个core其实存储的内容是一样的,无非角色不同。hash算法有一下两个要求:

1、hash计算速度必须快,因为hash计算是分布式建索引的第一步。

2、 hash值必须能均匀的分布于每一个shard,如果有一个shard的document数量大于另一个shard,那么在查询的时候前一个shard所花的时间就会大于后一个,SolrCloud的查询是先分后汇总的过程,也就是说最后每一个shard查询完毕才算完毕,所以SolrCloud的查询速度是由最慢的shard的查询速度决定的。

基于以上两点,SolrCloud采用了MurmurHash 算法以提高hash计算速度和hash值的均匀分布。

3. 创建索引

1、用户可以把新建文档提交给任意一个Replica(Solr Core)。

2、如果它不是leader,它会把请求转给和自己同Shard的Leader。

3、Leader把文档路由给本Shard的每个Replica。

III、如果文档基于路由规则(如取hash值)并不属于当前的Shard,leader会把它转交给对应Shard的Leader。

VI、对应Leader会把文档路由给本Shard的每个Replica。

需要注意的是,添加索引时,单个document的路由非常简单,但是SolrCloud支持批量添加索引,也就是说正常情况下可对N个document同时进行路由。这时SolrCloud会根据document路由的去向分开存放document,即对document进行分类,然后进行并发发送至相应的shard,这就需要较高的并发能力。


* 对请求的document进行hash,确定core,如果是自己负责的,转发请求(必须是leader,如果不是leader,转发给leader)到同一个shard的core。如果不是,转发给相应shard的leader。

举例来说当Solr Shard建立时候,Solr会给每一个shard分配32bit的hash值的区间,比如SolrCloud有两个shard分别为A,B,那么A的hash值区间就为80000000-ffffffff,B的hash值区间为0-7fffffff。默认的CompositeIdRouter hash策略会根据document ID计算出唯一的Hash值,并判断该值在哪个shard的hash区间内


4. 更新索引

1、 Leader接受到update请求后,先将update信息存放到本地的update log,同时Leader还会给document分配新的version,对于已存在的document,如果新的版本高就会抛弃旧版本,最后发送至replica。

2、一旦document经过验证以及加入version后,就会并行的被转发至所有上线的replica。SolrCloud并不会关注那些已经下线的replica,因为当他们上线时候会有recovery进程对他们进行恢复。如果转发的replica处于recovering状态,那么这个replica就会把update放入updatetransaction 日志。

3、当leader接受到所有的replica的反馈成功后,它才会反馈客户端成功。只要shard中有一个replica是active的,Solr就会继续接受update请求。这一策略其实是牺牲了一致性换取了写入的有效性。这其中有一个重要参数:leaderVoteWait参数,它表示当只有一个replica时候,这个replica会进入recovering状态并持续一段时间等待leader的重新上线。如果在这段时间内leader没有上线,那么他就会转成leader,其中可能会有一些document丢失。当然可以使用majority quorum来避免这个情况,这跟Zookeeper的leader选举策略一样,比如当多数的replica下线了,那么客户端的write就会失败。

4、索引的commit有两种,一种是softcommit,即在内存中生成segment,document是可见的(可查询到)但是没写入磁盘,断电后数据会丢失。另一种是hardcommit,直接将数据写入磁盘且数据可见

5. 查询



在创建好索引的基础上,SolrCloud检索索引相对就比较简单了:

1、用户的一个查询,可以发送到含有该Collection的任意Solr的Server,Solr内部处理的逻辑会转到一个Replica。

2、此Replica会基于查询索引的方式,启动分布式查询,基于索引的Shard的个数,把查询转为多个子查询,并把每个子查询定位到对应Shard的任意一个Replica。

3、每个子查询返回查询结果。

4、最初的Replica合并子查询,并把最终结果返回给用户

*导入一个document,生成的索引存储在一个shard?几个shard?  应是多个,进行并行查询,然后把查询结果进行合并

*如果1的理解正确,那么导入一个document是如果分shard的?不是整个document进行hash然后选择shard存储?而是按照内容分开存储?

*上面两点都对,如果有大量文档需要存储,需要查询,那么这些文档必然存储在不同的shard上,当 需要检索当时候,就需要分shard进行子查询,最后合并查询结果。

5. 实时性

SolrCloud中提供NRT近实时搜索:

SolrCloud支持近实时搜索,所谓的近实时搜索即在较短的时间内使得新添加的document可见可查,这主要基于softcommit机制(注意:Lucene是没有softcommit的,只有hardcommit)。上面提到Solr建索引时的数据是在提交时写入磁盘的,这是硬提交,硬提交确保了即便是停电也不会丢失数据;为了提供更实时的检索能力,Solr提供了一种软提交方式。软提交(soft commit)指的是仅把数据提交到内存,index可见,此时没有写入到磁盘索引文件中。在设计中一个通常的做法是:每1-10分钟自动触发硬提交,每秒钟自动触发软提交,当进行softcommit时候,Solr会打开新的Searcher从而使得新的document可见,同时Solr还会进行预热缓存及查询以使得缓存的数据也是可见的,这就必须保证预热缓存以及预热查询的执行时间必须短于commit的频率,否则就会由于打开太多的searcher而造成commit失败。

最后说说在项目中近实时搜索的感受吧,近实时搜索是相对的,对于有客户需求,1分钟就是近实时了,而有些需求3分钟就是近实时了。对于Solr来说,softcommit越频繁实时性更高,而softcommit越频繁则Solr的负荷越大(commit越频繁越会生成小且多的segment,于是Solr merge出现的更频繁)。目前我们项目中的softcommit频率是3分钟,之前设置过1分钟而使得Solr在Index所占资源过多,从而大大影响了查询。所以近实时蛮困扰着我们的,因为客户会不停的要求你更加实时,目前项目中我们采用加入缓存机制来弥补这个实时性

6. 优点及特性

通过以上的介绍,可看出SolrCloud相比Solr而言,有了很多的新特性,保证了整个Solr应用的High Availability。

1、集中式的配置信息

使用ZK进行集中配置。启动时可以指定把Solr的相关配置文件上传Zookeeper,多机器共用。这些ZK中的配置不会再拿到本地缓存,Solr直接读取ZK中的配置信息。另外配置文件的变动,所有机器都可以感知到, Solr的一些任务也是通过ZK作为媒介发布的,目的是为了容错,这使得Solr接收到任务,但在执行任务时崩溃的机器,在重启后,或者集群选出候选者时,可以再次执行这个未完成的任务。

2、SolrCloud对索引分片,并对每个分片创建多个Replication。每个Replication都可以对外提供服务。一个Replication挂掉不会影响索引服务,更强大的是,SolrCloud还能自动的在其它机器上帮你把失败机器上的索引Replication重建并投入使用。

3、近实时搜索:立即推送式的replication(也支持慢推送),可以在秒内检索到新加入索引。

4、查询时自动负载均衡:SolrCloud索引的多个Replication可以分布在多台机器上,均衡查询压力,如果查询压力大,可以通过扩展机器,增加Replication来减缓。

5、自动分发的索引和索引分片:发送文档到任何节点,SolrCloud都会转发到正确节点。

6、事务日志:事务日志确保更新无丢失,即使文档没有索引到磁盘。

除此之外,SolrCloud中还提供了其它一些特色功能:

1、可将索引存储在HDFS上

2、通过MR批量创建索引

3、强大的RESTful API

优秀的管理界面:主要信息一目了然,可以清晰的以图形化方式看到SolrCloud的部署分布,当然还有不可或缺的Debug功能

7. 实践环境理解

环境配置





启动4个solr服务,端口分别是8280,8380,8480,8580.



可以通过rest api操作solr,进行collection的增加,删除,修改,指定分片和副本因子

连接mysql数据库

配置连接mysql数据库,导入数据,创建索引。

配置数据更新:

  • 新增jar包 
    新增solr-dataimport-scheduler.jar到tomcat\webapps\下solr项目的WEB-INF\lib下
  • 修改配置 
    修改tomcat下的solr的web.xml增加如下配置
  <listener>  
   <listener-class>  
     org.apache.solr.handler.dataimport.scheduler.ApplicationListener  
   </listener-class>  
 </listener>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 新增配置 
    mkdir –p /app/solrhome/conf 
    新增dataimport.properties文件
syncEnabled=1
syncCores=address
server=10.202.39.184
port=8080
webapp=solr
params=/dataimport?command=delta-import&clean=false&commit=true
interval=5
#reBuildIndexInterval=7200
#reBuildIndexBeginTime=03:10:00
#reBuildIndexParams=/dataimport?command=full-import&clean=true&commit=true

https://blog.csdn.net/u012965107/article/details/54930804



参考:

https://www.cnblogs.com/saratearing/p/5690476.html



猜你喜欢

转载自blog.csdn.net/hanruikai/article/details/80049687