- 浏览: 74429 次
- 性别:
- 来自: 富安
最新评论
-
simpledev:
...
10步让你成为更优秀的程序员 -
bavnnsym:
像三楼说的那样,,是可以的,,我之前也碰到这个问题,,也是在d ...
IE6层不能遮挡住下拉框问题解决 -
suko:
yukaizhao 写道一句话的事情,就是创建一个和层一样大小 ...
IE6层不能遮挡住下拉框问题解决 -
yukaizhao:
一句话的事情,就是创建一个和层一样大小,一样位置的iframe ...
IE6层不能遮挡住下拉框问题解决 -
kaipingk:
andyyehoo 写道可以参考一下Struts2的日历控件的 ...
IE6层不能遮挡住下拉框问题解决
一.简介
SolrCloud是Solr4.0版本以后基于Solr和Zookeeper的分布式搜索方案。SolrCloud是Solr的基于Zookeeper一种部署方式。Solr可以以多种方式部署,例如单机方式,多机Master-Slaver方式。
二.特色功能
SolrCloud有几个特色功能:
集中式的配置信息
使用ZK进行集中配置。启动时可以指定把Solr的相关配置文件上传Zookeeper,多机器共用。这些ZK中的配置不会再拿到本地缓存,Solr直接读取ZK中的配置信息。配置文件的变动,所有机器都可以感知到。另外,Solr的一些任务也是通过ZK作为媒介发布的。目的是为了容错。接收到任务,但在执行任务时崩溃的机器,在重启后,或者集群选出候选者时,可以再次执行这个未完成的任务。
自动容错
SolrCloud对索引分片,并对每个分片创建多个Replication。每个Replication都可以对外提供服务。一个Replication挂掉不会影响索引服务。更强大的是,它还能自动的在其它机器上帮你把失败机器上的索引Replication重建并投入使用。
近实时搜索
立即推送式的replication(也支持慢推送)。可以在秒内检索到新加入索引。
查询时自动负载均衡
SolrCloud索引的多个Replication可以分布在多台机器上,均衡查询压力。如果查询压力大,可以通过扩展机器,增加Replication来减缓。
自动分发的索引和索引分片
发送文档到任何节点,它都会转发到正确节点。
事务日志
事务日志确保更新无丢失,即使文档没有索引到磁盘。
其它值得一提的功能有:
索引存储在HDFS上
索引的大小通常在G和几十G,上百G的很少,这样的功能或许很难实用。但是,如果你有上亿数据来建索引的话,也是可以考虑一下的。我觉得这个功能最大的好处或许就是和下面这个“通过MR批量创建索引”联合实用。
通过MR批量创建索引
有了这个功能,你还担心创建索引慢吗?
强大的RESTful API
通常你能想到的管理功能,都可以通过此API方式调用。这样写一些维护和管理脚本就方便多了。
优秀的管理界面
主要信息一目了然;可以清晰的以图形化方式看到SolrCloud的部署分布;当然还有不可或缺的Debug功能。
三.概念
Collection:在SolrCloud集群中逻辑意义上的完整的索引。它常常被划分为一个或多个Shard,它们使用相同的Config Set。如果Shard数超过一个,它就是分布式索引,SolrCloud让你通过Collection名称引用它,而不需要关心分布式检索时需要使用的和Shard相关参数。
Config Set:Solr Core提供服务必须的一组配置文件。每个config set有一个名字。最小需要包括solrconfig.xml (SolrConfigXml)和schema.xml (SchemaXml),除此之外,依据这两个文件的配置内容,可能还需要包含其它文件。它存储在Zookeeper中。Config sets可以重新上传或者使用upconfig命令更新,使用Solr的启动参数bootstrap_confdir指定可以初始化或更新它。
Core: 也就是Solr Core,一个Solr中包含一个或者多个Solr Core,每个Solr Core可以独立提供索引和查询功能,每个Solr Core对应一个索引或者Collection的Shard,Solr Core的提出是为了增加管理灵活性和共用资源。在SolrCloud中有个不同点是它使用的配置是在Zookeeper中的,传统的Solr core的配置文件是在磁盘上的配置目录中。
Leader: 赢得选举的Shard replicas。每个Shard有多个Replicas,这几个Replicas需要选举来确定一个Leader。选举可以发生在任何时间,但是通常他们仅在某个Solr实例发生故障时才会触发。当索引documents时,SolrCloud会传递它们到此Shard对应的leader,leader再分发它们到全部Shard的replicas。
Replica: Shard的一个拷贝。每个Replica存在于Solr的一个Core中。一个命名为“test”的collection以numShards=1创建,并且指定replicationFactor设置为2,这会产生2个replicas,也就是对应会有2个Core,每个在不同的机器或者Solr实例。一个会被命名为test_shard1_replica1,另一个命名为test_shard1_replica2。它们中的一个会被选举为Leader。
Shard: Collection的逻辑分片。每个Shard被化成一个或者多个replicas,通过选举确定哪个是Leader。
Zookeeper: Zookeeper提供分布式锁功能,对SolrCloud是必须的。它处理Leader选举。Solr可以以内嵌的Zookeeper运行,但是建议用独立的,并且最好有3个以上的主机。
四.架构图
4.1.索引(collection)的逻辑图
4.2.Solr和索引对照图
4.3.创建索引过程
4.4.分布式查询
4.5.拆分shard
五、Solr Cloud创建索引和更新索引
<一>、不得不知道的索引存储细节
当Solr客户端发送add/update请求给CloudSolrServer,CloudSolrServer会连接至Zookeeper获取当前SolrCloud的集群状态,并会在/clusterstate.json 和/live_nodes中注册watcher,便于监视Zookeeper和SolrCloud,这样做的好处有以下两点:
1、CloudSolrServer获取到SolrCloud的状态后,它可直接将document发往SolrCloud的leader,从而降低网络转发消耗。
2、注册watcher有利于建索引时候的负载均衡,比如如果有个节点leader下线了,那么CloudSolrServer会立马得知,那它就会停止往已下线的leader发送document。
此外,CloudSolrServer 在发送document时候需要知道发往哪个shard?对于建好的SolrCloud集群,每一个shard都会有一个Hash区间,当Document进行update的时候,SolrCloud就会计算这个Document的Hash值,然后根据该值和shard的hash区间来判断这个document应该发往哪个shard,Solr使用document route组件来进行document的分发。目前Solr有两个DocRouter类的子类CompositeIdRouter(Solr默认采用的)类和ImplicitDocRouter类,当然我们也可以通过继承DocRouter来定制化我们的document route组件。
举例来说当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区间内。
SolrCloud对于Hash值的获取提出了以下两个要求:
1、hash计算速度必须快,因为hash计算是分布式建索引的第一步。
2、 hash值必须能均匀的分布于每一个shard,如果有一个shard的document数量大于另一个shard,那么在查询的时候前一个shard所花的时间就会大于后一个,SolrCloud的查询是先分后汇总的过程,也就是说最后每一个shard查询完毕才算完毕,所以SolrCloud的查询速度是由最慢的shard的查询速度决定的。
基于以上两点,SolrCloud采用了MurmurHash 算法以提高hash计算速度和hash值的均匀分布。
<二>、Solr创建索引可以分为5个步骤(如下图所示):
<!--[if !supportLists]-->1、<!--[endif]-->用户可以把新建文档提交给任意一个Replica(Solr Core)。
<!--[if !supportLists]-->2、<!--[endif]-->如果它不是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,这就需要较高的并发能力。
<三>、更新索引的关键点:
1、 Leader接受到update请求后,先将update信息存放到本地的update log,同时Leader还会给document分配新的version,对于已存在的document,如果新的版本高就会抛弃旧版本,最后发送至replica。
2、一旦document经过验证以及加入version后,就会并行的被转发至所有上线的replica。SolrCloud并不会关注那些已经下线的replica,因为当他们上线时候会有recovery进程对他们进行恢复。如果转发的replica处于recovering状态,那么这个replica就会把update放入update transaction 日志。
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,直接将数据写入磁盘且数据可见。
<四>、对Solr更新索引和创建索引的几点总结:
1、leader转发的规则
1)请求来自leader转发:那么就只需要写到本地ulog,不需要转发给leader,也不需要转发给其它replicas。如果replica处于非active状态,就会将update请求接受并写入ulog,但不会写入索引。如果发现重复的更新就会丢弃旧版本的更新。
2)请求不是来自leader,但自己就是leader,那么就需要将请求写到本地,顺便分发给其他的replicas。
3)请求不是来自leader,但自己又不是leader,也就是该更新请求是最原始的更新请求,那么需要将请求写到本地ulog,顺便转发给leader,再由leader分发。每commit一次,就会重新生成一个ulog更新日志,当服务器挂掉,内存数据丢失的时候,数据就可以从ulog中恢复。
2、建索引的时候最好使用CloudSolrServer,因为CloudSolrServer直接向leader发送update请求,从而避免网络开销。
3、批量添加索引的时候,建议在客户端提前做好document的路由,在SolrCloud内进行文档路由,开销较大。
六、Solr Cloud索引的检索
在创建好索引的基础上,SolrCloud检索索引相对就比较简单了:
1、用户的一个查询,可以发送到含有该Collection的任意Solr的Server,Solr内部处理的逻辑会转到一个Replica。
2、此Replica会基于查询索引的方式,启动分布式查询,基于索引的Shard的个数,把查询转为多个子查询,并把每个子查询定位到对应Shard的任意一个Replica。
3、每个子查询返回查询结果。
4、最初的Replica合并子查询,并把最终结果返回给用户。
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所占资源过多,从而大大影响了查询。所以近实时蛮困扰着我们的,因为客户会不停的要求你更加实时,目前项目中我们采用加入缓存机制来弥补这个实时性。
七、Solr Shard Splitting的具体过程
一般情况下,增加Shard和Replica的数量能提升SolrCloud的查询性能和容灾能力,但是我们仍然得根据实际的document的数量,document的大小,以及建索引的并发,查询复杂度,以及索引的增长率来统筹考虑Shard和Replica的数量。Solr依赖Zookeeper实现集群的管理,在Zookeeper中有一个Znode 是/clusterstate.json ,它存储了当前时刻下整个集群的状态。同时在一个集群中有且只会存在一个overseer,如果当前的overseer fail了那么SolrCloud就会选出新的一个overseer,就跟shard leader选取类似。
Shard分割的具体过程(old shard split为newShard1和newShard2)可以描述为:
a、在一个Shard的文档到达阈值,或者接收到用户的API命令,Solr将启动Shard的分裂过程。
b、此时,原有的Shard仍然会提供服务,Solr将会提取原有Shard并按路由规则,转到新的Shard做索引。同时,新加入的文档:
1.2.用户可以把文档提交给任意一个Replica,并转交给Leader。
3.Leader把文档路由给原有Shard的每个Replica,各自做索引。
III.V. 同时,会把文档路由给新的Shard的Leader
IV.VI.新Shard的Leader会路由文档到自己的Replica,各自做索引,在原有文档重新索引完成,系统会把分发文档路由切到对应的新的Leader上,原有Shard关闭。Shard只是一个逻辑概念,所以Shard的Splitting只是将原有Shard的Replica均匀的分不到更多的Shard的更多的Solr节点上去。
八、Zookeeper :
<一>、SolrCloud中使用ZooKeeper主要实现以下三点功能:
<!--[if !supportLists]-->1、<!--[endif]-->集中配置存储以及管理。
<!--[if !supportLists]-->2、<!--[endif]-->集群状态改变时进行监控以及通知。
<!--[if !supportLists]-->3、<!--[endif]-->shard leader的选举。
<二>、 Znode与短链接
Zookeeper的组织结构类似于文件系统,每一层是一个Znode,每一个Znode存储了一些元数据例如创建时间,修改时间以及一些小量的数据。需要主要的是,Zookeeper并不支持存放大数据,它只支持小于1M大小的数据,因为性能原因,Zookeeper将数据存放在内存中。
Zookeeper另一个重要的概念是短链接,当Zookeeper客户端与Zookeeper建立一个短连接后会在Zookeeper新建一个Znode,客户端会一直与Zookeeper进行通信并保证这个Znode一直存在。如果当客户端与Zookeeper的短连接断开,这个Znode就会消失。在SolrCloud中,/live_nodes下存储了了所有客户端的短连接,表示有哪些Solr组成SolrCloud,具体来说就是当Solr跟Zookeeper保持短连接时,这些Solr主机就组成了SolrCloud,如果其中一个Solr的短连接断掉了,那么Live_nodes下就少了一个Znode,SolrCloud也就少了一个主机,于是Zookeeper就会告诉其他剩余的Solr有一个Solr挂掉了,那么在今后进行查询以及leader数据分发的时候就不用再经过刚才那个Solr了。Zookeeper是通过watch知道有Solr挂了的,而Zookeeper维护的集群状态数据是存放在solr/zoo_data目录下的。
<三>、SolrCloud配置Zookeeper集群的基本过程
事例1、单节点的Zookeeper,包含2个简单的Shard集群:把一个collection的索引数据分布到两个shard上去,并假定两个shard分别存储在两台Solr服务器上。
集群构建的基本流程:
先从第一台solr服务器说起:
1、启动一个嵌入式的Zookeeper服务器,作为集群状态信息的管理者。
2、将自己这个节点注册到/node_states/目录。
3、同时将自己注册到/live_nodes/目录下。
4、创建/overseer_elect/leader,为后续Overseer节点的选举做准备,新建一个Overseer。
5、更新/clusterstate.json目录下json格式的集群状态信息
6、本机从Zookeeper中更新集群状态信息,维持与Zookeeper上的集群信息一致。
7、上传本地配置文件到Zookeeper中,供集群中其他solr节点使用。
8、启动本地的Solr服务器,
9、Solr启动完成后,Overseer会得知shard中有第一个节点进来,更新shard状态信息,并将本机所在节点设置为shard1的leader节点,并向整个集群发布最新的集群状态信息。
10、本机从Zookeeper中再次更新集群状态信息,第一台solr服务器启动完毕。
然后来看第二台solr服务器的启动过程:
1、本机连接到集群所在的Zookeeper。
2、将自己这个节点注册到/node_states/目录下。
3、同时将自己注册到/live_nodes/目录下。
4、本机从Zookeeper中更新集群状态信息,维持与Zookeeper上的集群信息一致。
5、从集群中保存的配置文件加载Solr所需要的配置信息。
6、启动本地solr服务器。
7、solr启动完成后,将本节点注册为集群中的shard,并将本机设置为shard2的Leader节点。
8、本机从Zookeeper中再次更新集群状态信息,第二台solr服务器启动完毕。
示例2、单节点的Zookeeper,包含2个shard的集群,每个shard中有replica节点。
如图所示,集群包含2个shard,每个shard中有两个solr节点,一个是leader,一个是replica节点, 但Zookeeper只有一个。
因为Replica节点,使得这个集群现在具备容错性了,背后的实质是集群的overseer会监测各个shard的leader节点,如果leader节点挂了,则会启动自动的容错机制,会从同一个shard中的其他replica节点集中重新选举出一个leader节点,甚至如果overseer节点自己也挂了,同样会自动在其他节点上启用新的overseer节点,这样就确保了集群的高可用性。
示例3、包含2个shard的集群,带shard备份和zookeeper集群机制
示例2中存在的问题是:尽管solr服务器具有容错机制,但集群中只有一个Zookeeper服务器来维护集群的状态信息,单点的存在即是不稳定的根源。如果这个Zookeeper服务器挂了,那么分布式查询还是可以工作的,因为每个solr服务器都会在内存中维护最近一次由Zookeeper维护的集群状态信息,但新的节点无法加入集群,集群的状态变化也不可知了。
因此,为了解决这个问题,需要对Zookeeper服务器也设置一个集群,让其也具备高可用性和容错性。有两种方式可选,一种是提供一个外部独立的Zookeeper集群,另一种是每个solr服务器都启动一个内嵌的Zookeeper服务器,再将这些Zookeeper服务器组成一个集群。
总结: 通过以上的介绍,可看出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中还提供了其它一些特色功能:
<!--[if !supportLists]-->1、 <!--[endif]-->可将索引存储在HDFS上
<!--[if !supportLists]-->2、 <!--[endif]-->通过MR批量创建索引
3、强大的RESTful API
4、优秀的管理界面:主要信息一目了然,可以清晰的以图形化方式看到SolrCloud的部署分布,当然还有不可或缺的Debug功能。
SolrCloud是Solr4.0版本以后基于Solr和Zookeeper的分布式搜索方案。SolrCloud是Solr的基于Zookeeper一种部署方式。Solr可以以多种方式部署,例如单机方式,多机Master-Slaver方式。
二.特色功能
SolrCloud有几个特色功能:
集中式的配置信息
使用ZK进行集中配置。启动时可以指定把Solr的相关配置文件上传Zookeeper,多机器共用。这些ZK中的配置不会再拿到本地缓存,Solr直接读取ZK中的配置信息。配置文件的变动,所有机器都可以感知到。另外,Solr的一些任务也是通过ZK作为媒介发布的。目的是为了容错。接收到任务,但在执行任务时崩溃的机器,在重启后,或者集群选出候选者时,可以再次执行这个未完成的任务。
自动容错
SolrCloud对索引分片,并对每个分片创建多个Replication。每个Replication都可以对外提供服务。一个Replication挂掉不会影响索引服务。更强大的是,它还能自动的在其它机器上帮你把失败机器上的索引Replication重建并投入使用。
近实时搜索
立即推送式的replication(也支持慢推送)。可以在秒内检索到新加入索引。
查询时自动负载均衡
SolrCloud索引的多个Replication可以分布在多台机器上,均衡查询压力。如果查询压力大,可以通过扩展机器,增加Replication来减缓。
自动分发的索引和索引分片
发送文档到任何节点,它都会转发到正确节点。
事务日志
事务日志确保更新无丢失,即使文档没有索引到磁盘。
其它值得一提的功能有:
索引存储在HDFS上
索引的大小通常在G和几十G,上百G的很少,这样的功能或许很难实用。但是,如果你有上亿数据来建索引的话,也是可以考虑一下的。我觉得这个功能最大的好处或许就是和下面这个“通过MR批量创建索引”联合实用。
通过MR批量创建索引
有了这个功能,你还担心创建索引慢吗?
强大的RESTful API
通常你能想到的管理功能,都可以通过此API方式调用。这样写一些维护和管理脚本就方便多了。
优秀的管理界面
主要信息一目了然;可以清晰的以图形化方式看到SolrCloud的部署分布;当然还有不可或缺的Debug功能。
三.概念
Collection:在SolrCloud集群中逻辑意义上的完整的索引。它常常被划分为一个或多个Shard,它们使用相同的Config Set。如果Shard数超过一个,它就是分布式索引,SolrCloud让你通过Collection名称引用它,而不需要关心分布式检索时需要使用的和Shard相关参数。
Config Set:Solr Core提供服务必须的一组配置文件。每个config set有一个名字。最小需要包括solrconfig.xml (SolrConfigXml)和schema.xml (SchemaXml),除此之外,依据这两个文件的配置内容,可能还需要包含其它文件。它存储在Zookeeper中。Config sets可以重新上传或者使用upconfig命令更新,使用Solr的启动参数bootstrap_confdir指定可以初始化或更新它。
Core: 也就是Solr Core,一个Solr中包含一个或者多个Solr Core,每个Solr Core可以独立提供索引和查询功能,每个Solr Core对应一个索引或者Collection的Shard,Solr Core的提出是为了增加管理灵活性和共用资源。在SolrCloud中有个不同点是它使用的配置是在Zookeeper中的,传统的Solr core的配置文件是在磁盘上的配置目录中。
Leader: 赢得选举的Shard replicas。每个Shard有多个Replicas,这几个Replicas需要选举来确定一个Leader。选举可以发生在任何时间,但是通常他们仅在某个Solr实例发生故障时才会触发。当索引documents时,SolrCloud会传递它们到此Shard对应的leader,leader再分发它们到全部Shard的replicas。
Replica: Shard的一个拷贝。每个Replica存在于Solr的一个Core中。一个命名为“test”的collection以numShards=1创建,并且指定replicationFactor设置为2,这会产生2个replicas,也就是对应会有2个Core,每个在不同的机器或者Solr实例。一个会被命名为test_shard1_replica1,另一个命名为test_shard1_replica2。它们中的一个会被选举为Leader。
Shard: Collection的逻辑分片。每个Shard被化成一个或者多个replicas,通过选举确定哪个是Leader。
Zookeeper: Zookeeper提供分布式锁功能,对SolrCloud是必须的。它处理Leader选举。Solr可以以内嵌的Zookeeper运行,但是建议用独立的,并且最好有3个以上的主机。
四.架构图
4.1.索引(collection)的逻辑图
4.2.Solr和索引对照图
4.3.创建索引过程
4.4.分布式查询
4.5.拆分shard
五、Solr Cloud创建索引和更新索引
<一>、不得不知道的索引存储细节
当Solr客户端发送add/update请求给CloudSolrServer,CloudSolrServer会连接至Zookeeper获取当前SolrCloud的集群状态,并会在/clusterstate.json 和/live_nodes中注册watcher,便于监视Zookeeper和SolrCloud,这样做的好处有以下两点:
1、CloudSolrServer获取到SolrCloud的状态后,它可直接将document发往SolrCloud的leader,从而降低网络转发消耗。
2、注册watcher有利于建索引时候的负载均衡,比如如果有个节点leader下线了,那么CloudSolrServer会立马得知,那它就会停止往已下线的leader发送document。
此外,CloudSolrServer 在发送document时候需要知道发往哪个shard?对于建好的SolrCloud集群,每一个shard都会有一个Hash区间,当Document进行update的时候,SolrCloud就会计算这个Document的Hash值,然后根据该值和shard的hash区间来判断这个document应该发往哪个shard,Solr使用document route组件来进行document的分发。目前Solr有两个DocRouter类的子类CompositeIdRouter(Solr默认采用的)类和ImplicitDocRouter类,当然我们也可以通过继承DocRouter来定制化我们的document route组件。
举例来说当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区间内。
SolrCloud对于Hash值的获取提出了以下两个要求:
1、hash计算速度必须快,因为hash计算是分布式建索引的第一步。
2、 hash值必须能均匀的分布于每一个shard,如果有一个shard的document数量大于另一个shard,那么在查询的时候前一个shard所花的时间就会大于后一个,SolrCloud的查询是先分后汇总的过程,也就是说最后每一个shard查询完毕才算完毕,所以SolrCloud的查询速度是由最慢的shard的查询速度决定的。
基于以上两点,SolrCloud采用了MurmurHash 算法以提高hash计算速度和hash值的均匀分布。
<二>、Solr创建索引可以分为5个步骤(如下图所示):
<!--[if !supportLists]-->1、<!--[endif]-->用户可以把新建文档提交给任意一个Replica(Solr Core)。
<!--[if !supportLists]-->2、<!--[endif]-->如果它不是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,这就需要较高的并发能力。
<三>、更新索引的关键点:
1、 Leader接受到update请求后,先将update信息存放到本地的update log,同时Leader还会给document分配新的version,对于已存在的document,如果新的版本高就会抛弃旧版本,最后发送至replica。
2、一旦document经过验证以及加入version后,就会并行的被转发至所有上线的replica。SolrCloud并不会关注那些已经下线的replica,因为当他们上线时候会有recovery进程对他们进行恢复。如果转发的replica处于recovering状态,那么这个replica就会把update放入update transaction 日志。
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,直接将数据写入磁盘且数据可见。
<四>、对Solr更新索引和创建索引的几点总结:
1、leader转发的规则
1)请求来自leader转发:那么就只需要写到本地ulog,不需要转发给leader,也不需要转发给其它replicas。如果replica处于非active状态,就会将update请求接受并写入ulog,但不会写入索引。如果发现重复的更新就会丢弃旧版本的更新。
2)请求不是来自leader,但自己就是leader,那么就需要将请求写到本地,顺便分发给其他的replicas。
3)请求不是来自leader,但自己又不是leader,也就是该更新请求是最原始的更新请求,那么需要将请求写到本地ulog,顺便转发给leader,再由leader分发。每commit一次,就会重新生成一个ulog更新日志,当服务器挂掉,内存数据丢失的时候,数据就可以从ulog中恢复。
2、建索引的时候最好使用CloudSolrServer,因为CloudSolrServer直接向leader发送update请求,从而避免网络开销。
3、批量添加索引的时候,建议在客户端提前做好document的路由,在SolrCloud内进行文档路由,开销较大。
六、Solr Cloud索引的检索
在创建好索引的基础上,SolrCloud检索索引相对就比较简单了:
1、用户的一个查询,可以发送到含有该Collection的任意Solr的Server,Solr内部处理的逻辑会转到一个Replica。
2、此Replica会基于查询索引的方式,启动分布式查询,基于索引的Shard的个数,把查询转为多个子查询,并把每个子查询定位到对应Shard的任意一个Replica。
3、每个子查询返回查询结果。
4、最初的Replica合并子查询,并把最终结果返回给用户。
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所占资源过多,从而大大影响了查询。所以近实时蛮困扰着我们的,因为客户会不停的要求你更加实时,目前项目中我们采用加入缓存机制来弥补这个实时性。
七、Solr Shard Splitting的具体过程
一般情况下,增加Shard和Replica的数量能提升SolrCloud的查询性能和容灾能力,但是我们仍然得根据实际的document的数量,document的大小,以及建索引的并发,查询复杂度,以及索引的增长率来统筹考虑Shard和Replica的数量。Solr依赖Zookeeper实现集群的管理,在Zookeeper中有一个Znode 是/clusterstate.json ,它存储了当前时刻下整个集群的状态。同时在一个集群中有且只会存在一个overseer,如果当前的overseer fail了那么SolrCloud就会选出新的一个overseer,就跟shard leader选取类似。
Shard分割的具体过程(old shard split为newShard1和newShard2)可以描述为:
a、在一个Shard的文档到达阈值,或者接收到用户的API命令,Solr将启动Shard的分裂过程。
b、此时,原有的Shard仍然会提供服务,Solr将会提取原有Shard并按路由规则,转到新的Shard做索引。同时,新加入的文档:
1.2.用户可以把文档提交给任意一个Replica,并转交给Leader。
3.Leader把文档路由给原有Shard的每个Replica,各自做索引。
III.V. 同时,会把文档路由给新的Shard的Leader
IV.VI.新Shard的Leader会路由文档到自己的Replica,各自做索引,在原有文档重新索引完成,系统会把分发文档路由切到对应的新的Leader上,原有Shard关闭。Shard只是一个逻辑概念,所以Shard的Splitting只是将原有Shard的Replica均匀的分不到更多的Shard的更多的Solr节点上去。
八、Zookeeper :
<一>、SolrCloud中使用ZooKeeper主要实现以下三点功能:
<!--[if !supportLists]-->1、<!--[endif]-->集中配置存储以及管理。
<!--[if !supportLists]-->2、<!--[endif]-->集群状态改变时进行监控以及通知。
<!--[if !supportLists]-->3、<!--[endif]-->shard leader的选举。
<二>、 Znode与短链接
Zookeeper的组织结构类似于文件系统,每一层是一个Znode,每一个Znode存储了一些元数据例如创建时间,修改时间以及一些小量的数据。需要主要的是,Zookeeper并不支持存放大数据,它只支持小于1M大小的数据,因为性能原因,Zookeeper将数据存放在内存中。
Zookeeper另一个重要的概念是短链接,当Zookeeper客户端与Zookeeper建立一个短连接后会在Zookeeper新建一个Znode,客户端会一直与Zookeeper进行通信并保证这个Znode一直存在。如果当客户端与Zookeeper的短连接断开,这个Znode就会消失。在SolrCloud中,/live_nodes下存储了了所有客户端的短连接,表示有哪些Solr组成SolrCloud,具体来说就是当Solr跟Zookeeper保持短连接时,这些Solr主机就组成了SolrCloud,如果其中一个Solr的短连接断掉了,那么Live_nodes下就少了一个Znode,SolrCloud也就少了一个主机,于是Zookeeper就会告诉其他剩余的Solr有一个Solr挂掉了,那么在今后进行查询以及leader数据分发的时候就不用再经过刚才那个Solr了。Zookeeper是通过watch知道有Solr挂了的,而Zookeeper维护的集群状态数据是存放在solr/zoo_data目录下的。
<三>、SolrCloud配置Zookeeper集群的基本过程
事例1、单节点的Zookeeper,包含2个简单的Shard集群:把一个collection的索引数据分布到两个shard上去,并假定两个shard分别存储在两台Solr服务器上。
集群构建的基本流程:
先从第一台solr服务器说起:
1、启动一个嵌入式的Zookeeper服务器,作为集群状态信息的管理者。
2、将自己这个节点注册到/node_states/目录。
3、同时将自己注册到/live_nodes/目录下。
4、创建/overseer_elect/leader,为后续Overseer节点的选举做准备,新建一个Overseer。
5、更新/clusterstate.json目录下json格式的集群状态信息
6、本机从Zookeeper中更新集群状态信息,维持与Zookeeper上的集群信息一致。
7、上传本地配置文件到Zookeeper中,供集群中其他solr节点使用。
8、启动本地的Solr服务器,
9、Solr启动完成后,Overseer会得知shard中有第一个节点进来,更新shard状态信息,并将本机所在节点设置为shard1的leader节点,并向整个集群发布最新的集群状态信息。
10、本机从Zookeeper中再次更新集群状态信息,第一台solr服务器启动完毕。
然后来看第二台solr服务器的启动过程:
1、本机连接到集群所在的Zookeeper。
2、将自己这个节点注册到/node_states/目录下。
3、同时将自己注册到/live_nodes/目录下。
4、本机从Zookeeper中更新集群状态信息,维持与Zookeeper上的集群信息一致。
5、从集群中保存的配置文件加载Solr所需要的配置信息。
6、启动本地solr服务器。
7、solr启动完成后,将本节点注册为集群中的shard,并将本机设置为shard2的Leader节点。
8、本机从Zookeeper中再次更新集群状态信息,第二台solr服务器启动完毕。
示例2、单节点的Zookeeper,包含2个shard的集群,每个shard中有replica节点。
如图所示,集群包含2个shard,每个shard中有两个solr节点,一个是leader,一个是replica节点, 但Zookeeper只有一个。
因为Replica节点,使得这个集群现在具备容错性了,背后的实质是集群的overseer会监测各个shard的leader节点,如果leader节点挂了,则会启动自动的容错机制,会从同一个shard中的其他replica节点集中重新选举出一个leader节点,甚至如果overseer节点自己也挂了,同样会自动在其他节点上启用新的overseer节点,这样就确保了集群的高可用性。
示例3、包含2个shard的集群,带shard备份和zookeeper集群机制
示例2中存在的问题是:尽管solr服务器具有容错机制,但集群中只有一个Zookeeper服务器来维护集群的状态信息,单点的存在即是不稳定的根源。如果这个Zookeeper服务器挂了,那么分布式查询还是可以工作的,因为每个solr服务器都会在内存中维护最近一次由Zookeeper维护的集群状态信息,但新的节点无法加入集群,集群的状态变化也不可知了。
因此,为了解决这个问题,需要对Zookeeper服务器也设置一个集群,让其也具备高可用性和容错性。有两种方式可选,一种是提供一个外部独立的Zookeeper集群,另一种是每个solr服务器都启动一个内嵌的Zookeeper服务器,再将这些Zookeeper服务器组成一个集群。
总结: 通过以上的介绍,可看出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中还提供了其它一些特色功能:
<!--[if !supportLists]-->1、 <!--[endif]-->可将索引存储在HDFS上
<!--[if !supportLists]-->2、 <!--[endif]-->通过MR批量创建索引
3、强大的RESTful API
4、优秀的管理界面:主要信息一目了然,可以清晰的以图形化方式看到SolrCloud的部署分布,当然还有不可或缺的Debug功能。
发表评论
-
ZooKeeper之java客户端访问-入门介绍
2016-03-04 10:47 773时间 2014-03-22 22:42:48 CS ... -
Solr 4.7.0部署及java调用solr
2016-02-25 15:19 528参考了以下2个网站 1.Solr在tomcat中的部署 htt ... -
HTTP请求如何带参
2015-11-10 22:21 746HTTP请求如何带参 转载自:http://www.cnbl ... -
MyBatis 配置sql语句输出
2015-09-29 15:37 13121.首先将ibatis log4j运行级别调到DEBUG可以在 ... -
自定义alert提示框
2015-09-23 16:48 653js和css写的自定义弹出框,可以自己修改颜色和布局,使得弹出 ... -
js判断手机系统类型
2015-09-21 13:52 600function checkOSType(){ ... -
Java生成二维码,扫描后跳转到指定的网站
2015-09-16 22:25 9640本例我是应用google的二维码工具包来做的,附近提供jar包 ... -
net.sf.json.JSONObject 依赖的包
2015-03-01 20:55 6423依赖的包如下图: 主包为json-lib-2.3-jdk13. ... -
通过阻塞队列实现文件关键字检索功能
2015-01-26 13:57 655package com.queue; import ... -
Tomcat热部署
2014-11-25 09:50 524\conf\Catalina\localhost目录下新建xm ... -
合并多个excel文件到一个文件
2014-11-16 19:41 1255package com.ben.utils; imp ... -
Java实现FTP上传和下载
2014-08-14 15:04 873import java.io.ByteArrayInput ... -
使用正则表达式替换数字
2014-06-19 16:38 1199public static void main(Strin ... -
Java Webservice例子
2014-06-17 12:38 5181.webservice服务端代码,发布一个webservic ... -
Java基础知识汇总
2014-05-08 08:28 589一、关于main方法 1.main方法被定义为private, ... -
查看JDK源码
2014-05-07 22:54 511查看JDK源码: step1:打开MyEclipse选择Wi ... -
Java中取两个集合的并集、交集和差集
2014-04-23 16:58 112631.并集 也叫合集,即把两个集合的所有元素加在一起。 pu ... -
JXPathContext支持迷糊匹配
2014-03-12 15:40 1077看完例子就会了 public ... -
统计英文单词的数量
2014-03-12 10:18 747使用正则表达式来统计一段文字中的英文单词的数量 publi ... -
使用序列化方法实现list集合的深拷贝
2014-03-05 14:28 3003对于可序列化(实现Serializable接口)的对象,封装它 ...
相关推荐
在Windows 7环境下搭建SolrCloud5.2.1、Tomcat7和Zookeeper3.4.6的集成环境是进行分布式搜索和索引管理的重要步骤。下面将详细介绍整个配置过程。 1. **软件环境配置** - **操作系统**: Windows 7 - **Tomcat**: ...
SolrCloud是Apache Lucene项目下的一个基于分布式搜索引擎,通过将多个Solr实例组合成一个集群,可以实现高可用性和高性能的搜索系统。Tomcat是Apache软件基金会的一个开源的Java Servlet容器,而Zookeeper是一个...
SolrCloud是一个分布式搜索引擎系统,基于Apache Solr和Zookeeper构建。它允许用户在大型数据集上进行高效、可扩展的搜索和分析。本教程主要介绍如何在Windows 7环境下搭建SolrCloud 5.2.1,使用Tomcat 7作为应用...
### SolrCloud 5.2.1 + Tomcat 7 + Zookeeper 3.4.6 搭建教程 #### 一、环境准备 **软件环境:** - **操作系统:** Windows 7 - **Tomcat 版本:** 7.0.56 - **Solr 版本:** 5.2.1 - **Zookeeper 版本:** 3.4.6 **...
SolrCloud高可用集群搭建是实现大规模、分布式搜索引擎的关键步骤,它通过集成Zookeeper来管理和协调各个Solr节点,确保数据的一致性和可用性。在搭建过程中,我们需要遵循一定的步骤和配置,以下是一些关键的知识点...
Solr-Zookeeper-Tomcat集群搭建教程 在大数据和搜索引擎领域,Apache Solr是一个非常流行的全文检索服务。它能够提供高效、可扩展的搜索和分析功能。为了实现高可用性和负载均衡,通常会将Solr部署在分布式环境中,...
本文详细介绍了如何在Tomcat服务器上部署SolrCloud,包括Zookeeper集群的搭建、Solr软件包的获取与配置、SolrCloud的部署流程等内容。这些步骤对于实际环境中部署和维护SolrCloud系统具有重要的参考价值。通过以上...
通过以上步骤,我们可以成功地搭建一个Zookeeper集群和SolrCloud,确保服务的高可用性和数据的分散存储,为大数据环境下的搜索和分析提供强大支持。在实际应用中,还需要关注监控、日志管理以及性能优化等方面,以...
在这个集群环境中,Tomcat作为Servlet容器运行Solr,而Zookeeper则作为分布式协调服务,管理整个集群的状态和配置。 一、Solr 4.9 集群的核心概念 1. **Sharding**: Solr集群通过分片技术将大量数据分散到多个节点...
### Solr集群搭建与SolrCloud分布式搜索方案详解 #### 一、SolrCloud概述 SolrCloud 是 Apache Solr 提供的一种分布式搜索解决方案。它主要用于处理大规模数据集的索引和检索工作,并具备容错性和分布式特性。当...
在本场景中,我们主要关注如何在Linux环境下搭建一个基于Zookeeper的SolrCloud集群。 首先,我们需要准备必要的软件环境。操作系统选择的是Linux,而Solr服务使用的是版本4.8.1,与之配合的Tomcat服务器是7.0.54...
本教程将指导你在Win7环境下搭建一个单机版的伪分布式SolrCloud环境,利用Tomcat作为应用服务器,以及Zookeeper进行集群协调。 **一、软件工具箱** 1. **Tomcat-7.0.62**:作为Solr的容器,负责部署和运行Solr应用...
SolrCloud作为Apache Solr的一个核心特性,主要应用于大规模、高性能的分布式搜索场景。当系统面临海量数据索引及高并发查询请求时,SolrCloud能够提供一套完整且高效的解决方案。 #### SolrCloud的核心价值 - **...
Solr 还提供了分布式搜索能力,可以在多台服务器之间分布索引和查询,以实现更高的可用性和可伸缩性。通过 SolrCloud 功能,用户可以创建集群,并利用 ZooKeeper 进行管理和协调。 在实际应用中,Solr 可用于电子...
- **定义**:SolrCloud 是 Solr 提供的一种分布式搜索解决方案,适用于需要处理大规模数据集、支持高并发搜索请求以及实现容错机制的应用场景。 - **适用场景**:当单个索引的数据量较小且搜索请求频率不高时,无需...
Solr集群搭建是构建大规模、高可用搜索服务的基础。在这个过程中,我们将主要关注以下几个关键步骤和概念: 1. **Solr的基本介绍**:Solr是一款开源的企业级全文搜索引擎,由Apache软件基金会开发,用于处理和索引...
5. **云支持**:在分布式环境中,`lib`目录会包含`solrcloud.jar`,提供SolrCloud的功能,包括Zookeeper协调和集群状态管理。 6. **其他依赖**:Solr还可能依赖于其他第三方库,如`jackson*`系列的JAR文件用于JSON...