Excel函数Search的语法及基本用法介绍 Find函数实现不了的实例(excel中的search函数)
1336
2022-05-28
背景:
ES在做Segment合并的时候,根据写入模式和数据量,通常会有几倍到十几倍的写放大。此处写放大的定义是:磁盘写入数据总量/最终生成索引的大小。ES通常有两种类型的合并:NatureMerge和ForceMerge。NatureMerge是ES为了提升查询性能、回收删除Doc,在后台定期调度的merge操作。对索引的任何增删改操作都有可能触发NatureMerge。而ForceMerge是指在一次导入大批量数据后,由运维人员手动触发的merge操作,目的是减少segment数量,提升查询性能。ForceMerge由于是人工触发,通常预设当前无查询流量,所以过程比较激进,例如默认会merge成一个segment。
ES Merge过程解析
ES Merge过程可以视为一个典型的生产者-消费者模式。首先由MergePolicy根据一系列算法生成一个MergeSpecification对象。其次由MergeScheduler 执行这个MergeSpecification。
MergePolicy类图如上所示,当前ES/Lucene的默认Merge策略是TieredMergePolicy。具体算法流程解析稍后给出。在基类中的findMerges/findForcedMerges分别对应前述的NatureMerge和ForceMerge过程。
MergeScheduler的类图如上所示,ES/Lucene默认实现为ConcurrentMergeScheduler。在Lucene层面,如果用户不想触发Merge,可以把默认MergePolicy和MergeScheduler分别指定为NoMergePolicy和NoMergeScheduler。但是ES目前并不开放这个配置。
分层Nature合并:
在前文中提到ES/Lucene的默认merge策略是TieredMergePolicy,即分层Merge。注意此处层只是一个按Segment大小划分的逻辑概念,在文件系统和ES架构中不同层的索引并无本质区别。分层Merge主流程主要分三步:
1. 根据分层算法和deletesPctAllowed配置推导出本次Merge完成后AllowedSegCount和AllowedDelCount。这两个值是后续循环中止条件。分层算法的逻辑非常简单:比如当前索引总量为20M,AllowedSegCount为10个(10*2M)。当前索引总量为220M,AllowedSegCount为20个(20M*10 + 2M*10)。依此类推。
2. 滑动窗口算法寻找OneMerge对象。如下图所示:对候选Segments按大小排序,通过一个滑动窗口从左往右滑动。窗口包含的Segment数从1开始,最大不超过maxMergeAtOnce(默认10)。同时窗口内的SegmentSize总和不超过maxMergedSegmentByte(默认5G)。
3. 对第二步选出来的OneMerge对象进行打分(分数越低越优)。打分考虑如下三个因素,考虑权重依次降低:
a) 选中Segment的大小平均度,越平均越好
b) 选中Segment中可回收Doc的比率,越高越好。
c) 选中SegmentByte总和,越小越好
分层Force合并
由于Force合并是手工触发,并不考虑当前服务吞吐和延迟。所以策略比Nature合并简单粗暴很多。
1. 首先看当前Segment总数 2. 如果上述条件不满足,则依旧采用滑动窗口算法。但是和Nature合并相反,Force合并是从右向左滑动。窗口的初始值为2,不超过maxMergeAtOnceExplicit,并且窗口内SegmentSize总和不超过maxMergedSegmentByte。 ConcurrentMergeScheduler执行过程 ConcurrentMergeScheduler实际上是对一个后台线程池的封装。当设备硬件为传统磁盘时,启动1个线程。当年设备硬件为SSD固态硬盘时,启动的线程数为max(1, min(4, core/2))。同时工作的MergeCount = ThreadCount + 5。ConcurrentMergeScheduler执行流程如下图所示: 由上图可知,整个流程其实就是对线程池的调用,虚线部分表示这是一个线程池Push的异步操作,并不需要等待merge工作实际完成。整个Merge过程实际上分四步,分别是mergeInit,mergeMiddle,mergeSuccess和mergeFinish。实际干活的事情都在mergeMiddle中实现。MergeMiddle借助SegmentMerger封装,对FieldInfo、倒排、正排等索引结构做依次Merge。Merge过程如下: Lucene借助Codec的抽象,将索引处理流程和索引数据结构解耦开。右边是Merge流程,左边是每个数据结构对应的Codec。Codec中包含输入数据的Consumer/Producer。分别负责生成索引和读取索引。 小结 由上文可知,整个Lucene索引Merge的流程并不复杂。通过Policy/Scheduler将索引合并的描述MergeSpecification的生成和执行解耦。开发者可以根据自己的业务场景需要,自由灵活的组装。而Merge的实际工作MergeMiddle主要依赖SegmentMerger类实现。 附录1:ES/Lucene对Merge写放大有影响的参数 参数名 含义 默认值 备注 max_merge_at_once 一次普通merge可以参与的segment数量 10 max_merge_at_once_explicit 一次forcemerge可以参与的segment数量 30 推荐适度调大,可降低写放大。 max_merged_segment_bytes OneMerge产出的segment最大值 5G 对于小规模索引够用,对于海量索引数据推荐调大。如调为0则不触发Nature Merge 附录2:参考文献 Lucene-8.6源码:https://github.com/apache/lucene-solr Lucene官方API文档:https://lucene.apache.org/core/8_6_2/core/index.html Solar官方文档: https://lucene.apache.org/solr/guide/8_6/ http://blog.mikemccandless.com/2011/02/visualizing-lucenes-segment-merges.html 云搜索服务 CSS
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。