当前位置: 移动技术网 > IT编程>数据库>其他数据库 > Solr 15 - Solr添加和更新索引的过程(文档的路由细节)

Solr 15 - Solr添加和更新索引的过程(文档的路由细节)

2019年03月29日  | 移动技术网IT编程  | 我要评论

1 添加文档的细节

1.1 注册观察者 - watcher

solr单机服务中, 与solr内部进行交互的类是httpsolrserver.
solrcloud集群中, 与solr内部进行交互的类是cloudsolrserver.
这里以solrcloud集群为例讲解添加文档的相关细节.

当solr客户端向cloudsolrserver发送add/update请求时, cloudsolrserver会从zookeeper获取当前solrcloud的集群状态,并在zookeeper管理的配置文件/clusterstate.json/live_nodes中注册观察者watcher, 便于监视zookeeper和solrcloud.

注册观察者的好处是:

cloudsolrserver获得solrcloud的状态后, 就能直接把要添加/修改的document发往solr集群的leader, 从而降低网络转发上的消耗;
② 注册watcher有利于添加索引时的负载均衡: 如果有个节点的leader下线了, cloudsolrserver就能立刻感知到, 它就会停止往已下线的leader发送请求.

1.2 文档的路由 - document route

cloudsolrserver添加document时, 需要确定该document发往哪个shard. solrcloud集群中, 每个shard都有一个hash区间, 添加时, solrcloud会计算该文档的hash值, 然后根据它的hash值, 把它发送到对应hash区间的shard.

—— 上述过程称为文档的分发, 由solr的document route(文档路由)组件来完成.

1.2.1 路由算法

solrcloud提供了两种路由算法, 创建collection(集合, 类似于mysql中的表)时, 需要通过router.name来指定路由策略.

① compositeid - 默认的路由算法:

  • 该策略是一致性哈希路由, shards的哈希范围是80000000~7fffffff;
  • 创建collection的时候必须指定numshards, 这个路由算法将根据shard的个数, 计算出每个shard的哈希范围;
  • 索引数据会均匀分布在每个shard上;
  • 这个路由策略不支持扩展shard, 否则会导致一些已经索引到solr中的文档无法被检索.

② implicit - 绝对路由策略:

  • 该路由策略是直接指定索引文档落到具体的某个shard上;
  • 索引数据并不会均匀分布到每个shard上;
  • 使用implicit路由策略的collection才支持 创建/扩展 shard.

1.2.2 solr路由的实现类

solr中路由的基类是docrouter, 它有2个子类: compositeidrouter(默认使用的), 和implicitdocrouter.

我们可以通过继承docrouter类来定制自己的document route组件.

1.2.3 implicit路由算法的使用

  • 通过solrj创建文档索引时, 使用implicit策略指定文档的所属shard:

    代码如下:

    doc.addfield("route", "shard_x");

    同时, 要在schema.xml约束文件中添加字段:

    <field name="_route_" type="string"/>
  • 利用url创建implicit路由方式的collection:

    http://ip:port/solr/admin/collections?action=create&name=coll&router.name=implicit&shards=shard1,shard2,shard3

1.2.4 solr获取文档hash值的要求

① hash值的计算速度必须很快, 这是分布式创建索引的第一步;

② hash值必须能均匀地分布到每一个shard上. 如果某个shard中document数量远多于其他shard, 那么在查询等操作中, 文档数量多的shard所花的时间就会大于其他shard, 而solrcloud的查询是 先分给各个shard查询, 然后汇总返回 的过程, 也就是说solrcloud的查询速度是由最慢的shard决定的.

基于以上两点, solr的底层引擎lucene使用了murmurhash算法, 用来提高hash值的计算速度和均匀分布.

关于murmurhash哈希算法, 可参考文末的相关链接.


2 添加索引的过程

solrcloud添加索引的过程

参照上图, 解析添加索引的过程:

(1) 用户把要添加的文档提交给任意一个replica(副本, 可以是主副本, 也可以是从副本);

(2) 如果接收到请求的replica不是leader, 它会把请求转给同shard中的leader;

(3) leader把文档路由给本shard的其他所有replica;

(iii) 如果根据路由规则, 当前文档并不属于当前的shard, 这个leader就会把它转交给对应shard的leader;

(vi) 对应的leader会把文档路由给本shard的每个replica, 从而完成添加操作.

注意:

添加索引时, 单个document的路由非常简单.

但是solrcloud支持批量添加索引, 也就是说对多个document同时进行路由, 这时solrcloud会根据document路由的去向分开存放document, 然后并发传送到相应的shard, 这就需要solrcloud具有较高的并发能力.


3 更新索引的过程

(1) leader接受到update请求后, 先将需要修改的文档存放到本地的update log, 同时leader还会对这个文档分配新的version(版本信息), 对于已经存在的文档, 如果新版本值大于旧版本值, 就会抛弃旧版本;

(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丢失.

==> 可以借鉴zookeeper的选举策略, 使用majority quorum(大多数法定人数)策略来避免这个情况: 比如当多数replica下线了, 客户端的写请求就会失败.

(4) 索引的commit(提交)有两种:

① softcommit(软提交): 在内存中生成segment, 此时document是可见的, 可以供客户端请求查询, 但是还没有写入磁盘, 系统断电等故障后数据会丢失;

② hardcommit(硬提交): 直接把内存中的数据写入磁盘, 知道写入完成才可见.

—— 软提交的近实时性更强, 硬提交的安全性更高.


4 solr创建和更新索引的总结

4.1 leader的转发规则

(1) 请求来自leader转发: 只需要把数据写到本地的ulog, 不需要转发给leader, 也不需要转发给其它的replicas. 如果当前replica处于非活跃状态, 就会将请求数据接受并写入ulog, 但不会写入索引; 如果发现有重复的更新, 会丢弃旧版本的更新;

(2) 请求不是来自leader, 但自己就是leader: 需要把请求写到本地, 并分发给其他的replicas;

(3) 请求不是来自leader, 自己也不是leader: 该请求应该是最原始的请求, 就需要将请求写到本地ulog, 顺便转发给leader, 再由leader分发给同一个shard下的replica.

(4) 每commit一次(生成新的提交点), 就会重新生成一个ulog更新日志. 当服务器挂掉、内存数据丢失的时候, 数据就可以从ulog中恢复.

4.2 高效实践的建议

(1) 创建索引的时候最好使用cloudsolrserver: 因为cloudsolrserver会直接向leader发送update请求, 避免了网络的额外开销;

(2) 批量添加索引的时候, 建议在客户端提前做好document的路由, 因为在solrcloud内进行文档路由的开销比较大.

参考资料

solrcloud之分布式索引及与zookeeper的集成

solrcloud 5.0 路由、collection创建与数据迁移

一致性哈希算法与java实现

murmurhash算法

版权声明

作者: ma_shoufeng(马瘦风)

出处: 博客园

您的支持是对博主的极大鼓励, 感谢您的阅读.

本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网