1、客户端写请求发送到协调节点(Coordinating Node)
2、协调节点路由写请求到活跃的shard中。路由规则:(实现类OperationRouting)
2.1 默认: hash(document_id)/(主shard数)
2.2 根据指定字段的值作为路由参数: hash(参数值)/(主shard数)。思考:分母为什么是主shard数?主要是因为写入时需要先写入主shard中。然后再同步到副shard中去。
3、数据先写入主分片的memory buffer中,然后再写入到transaction log(默认同步,也可配置为异步),当主分片中的请求全部返回成功后,再并行写入到副分片中。当主副本全部写入成功后即返回到客户端。此时数据是不能被搜索的。只能通过id在trans log中提取。
4、refresh阶段: memory buffer会周期性(默认1s)的做refresh操作。将内容写入到一个新的segment中。此阶段对应lucene的flush阶段。故此时数据可以被搜索。但并没有落盘持久化。
5、flush阶段: 每隔30分钟或者当trans log中的数据量太大时,会产生一次flush操作。该操作会清空内存缓冲区,从而产生一个新的segment,触发一个lucene的commit操作,落盘产生一个commit point点(就是备份)。此时trans log就可以被清除了。
6、segment合并阶段: lucene会定期merge一些小的segment至一个大的segment中。防止segment太多,占用太多文件句柄及降低查询效率。
2、refresh阶段
2.1 流程
refresh阶段主要是将之前写入缓冲区的数据,刷成一个新的segment。保证数据可搜索。这个刷新的频率,影响搜索的实时性。
具体过程如图:
1、数据写入内存缓冲区和translog
2、数据refresh成一个segment, 同时清空缓冲区的内容。此时的segment没有落盘。但同样是可搜索的
2.2 配置项及api
缓冲区属于节点级别的资源,节点上的所有shard共享。关于缓冲区大小的配置如下:
indices.memory.index_buffer_size 缓冲区大小。默认是节点总堆的10%。也可配置为绝对值。
indices.memory.min_index_buffer_size 如果index_buffer_size为百分比,则该参数可设置缓冲区最小值。默认48mb。
indices.memory.max_index_buffer_size 如果index_buffer_size为百分比,则该参数可设置缓冲区最大值。默认无界。
缓冲区刷新频率的配置:
refresh_interval 刷新频率。默认每秒刷新一次。 设置为-1为关闭刷新。
接口:
代码语言:txt
AI代码解释
POST /blogs/_refresh 指定索引刷新 POST /_refresh 全部手动 PUT /my_logs/_settings 关闭自动刷新 { "refresh\_interval": -1 } PUT /my_logs/_settings 每秒刷新1次 { "refresh_interval": "1s" }
3、flush阶段
3.1 流程
1、每30分钟或者当translog中的数据达到阈值后,会触发一次flush操作。产生一个point点。并落到磁盘。
2、commit point点产生,会清空内存缓冲区及translog数据
3.2 配置项及api
translog相关配置
代码语言:txt
AI代码解释
index.translog.sync_interval 刷新频率。默认5s,不能低于100ms index.translog.durability 刷新方式。默认request(同步), async 异步 index.translog.flush_threshold_size flush阶段的translog阈值。默认512mb。如果达到则会强制flush,否则需要等待30分钟 index.translog.retention.size 保留的translog大小。默认512mb index.translog.retention.age 保留的translog时间。默认12h
上面2个translog保留的配置可能会用于副本的恢复。不会影响写入性能。
代码语言:txt
AI代码解释
index.translog.generation_threshold_size 单个独立translog的大小阈值,如果超过则生成新的translog,不flush。默认64mb。 flush api可以针对单个或者所有索引进行flush POST /twitter/_flush/synced POST /blogs/_flush POST /_flush?wait_for_ongoing 同步刷新 异步,5s频率 PUT /my_index/_settings { "index.translog.durability": "async", "index.translog.sync\_interval": "5s" }
4、merge阶段
4.1 流程
1、将refresh和flush产生的segment进行合并,合并成一个大的segment。合并过程中的segment仍可以被搜索。如下图:
2、合并完成后会进行一个flush操作。产生一个新的commit point点。同时将已合并的segment删除。
4.2 配置&算法
配置汇总
代码语言:txt
AI代码解释
index.merge.policy.floor_segment 最小参考的segment的大小,并非实际最小segment的大小。默认设置为2mb index.merge.policy.max_merge_at_once 单次合并的最大segment数量。默认是10个 index.merge.policy.max_merged_segment 合并时的最大segment阈值,大于该阈值的正常不会合并。除非触发了第3种情况的合并规则。默认5gb index.merge.policy.segments_per_tier 每层的segment数量 index.merge.policy.deletes_pct_allowed segment中文档删除百分比。取值范围:20~50。默认值是33.当达到该值时即使segment大于max_merged_segment大小也会发生merge index.merge.scheduler.max_merge_count 最大merge次数 index.merge.policy.max_merge_at_once_explicit forceMerge或forceMergeDeletes方式时单次合并的最大segment数量。默认30
es中的合并分为3种类型:
1)NATURAL: 常规合并。合并一些小于指定segment阈值以内的segment。使其成为一个大的segment。提高index效率。es自动完成。
2) FORCE_MERGE_DELETES:合并一些大于指定segment阈值且包含大量已删除文件的segment。也就是给大segment "瘦身" , es自动完成。
3)FORCE_MERGE: 手动强制合并。通过api接口调用。一般情况不需要使用。
注意:所有算法中,标注颜色的变量均是配置项,即可调优参数。
4.2.1 NATURAL
配置
代码语言:txt
AI代码解释
index.merge.policy.floor_segment 最小参考的segment的大小,并非实际最小segment的大小。默认设置为2mb index.merge.policy.max_merge_at_once 单次合并的最大segment数量。默认是10个 index.merge.policy.max_merged_segment 合并时的最大segment阈值,大于该阈值的正常不会合并。除非触发了FORCE_MERGE_DELETES合并规则。默认5gb index.merge.policy.segments_per_tier 每层的segment数量。 index.merge.policy.deletes_pct_allowed segment中文档删除百分比。取值范围:20~50。默认值是33.当达到该值时即使segment大于max_merged_segment大小也会发生merge index.merge.scheduler.max_merge_count 最大merge次数
算法
1、根据 segment大小倒序排列 并 剔除不符合条件的segment
1) 正在参与合并操作的segment
2) segment大小大于maxMergedSegmentBytes/2(maxMergedSegmentBytes默认5g)且segment中删除文档的比例较低的segment(segDelPct <=deletesPctAllowed)
2、计算触发merge条件的segment数(allowedSegCount),如果实际待merge的segment数小于该值则不会触发合并。具体算法:
假设如下配置: floorSegmentBytes = 2*1024*1024 , segsPerTier= 10, maxMergeAtOnce= 20,maxMergedSegmentBytes= 50*1024*1024
索引中最小: segment:minSegmentBytes = 1 1024 1024
索引大小:totIndexBytes = 500 1024 1024
则allowedSegCount = 26;
3、从待合并的segment列表中分层提取segment进行merge。直到待合并的segment列表中的元素小于 allowedSegCount 时,则中止此次合并。
1)每层中segment的大小总和不得超过maxMergedSegmentBytes
2)每层中segment的个数不得超过mergeFactor
代码语言:javaaly.mcmajans.com
AI代码解释
`final int mergeFactor = (int) Math.min(maxMergeAtOnce,segsPerTier);`
3)层的个数不得超过max_merge_count
由于待合并的segment是倒序排列,则合并的原则总是优先合并满足条件的大的segment。
例如: maxMergedSegmentBytes = 5G, 则蓝色是可以合并,红色是不能合并的。如下图:
4.2.2 FORCE_MERGE_DELETES
对segment中已删除文档的比例大于deletes_pct_allowed阈值的segment进行合并
配置aly.yaziyooo.com77
代码语言:txt
AI代码解释
index.merge.policy.deletes_pct_allowed segment中文档删除比例的阈值。取值范围:20~50。默认值是33.当达到该值时即使segment大于max_merged_segment大小也会发生merge。 index.merge.policy.max_merge_at_once_explicit forceMerge或forceMergeDeletes方式时单次合并的最大segment数量。默认30
算法
1、查找所以segment中是否存在已删除的文档比例大于deletes_pct_allowed阈值且处于未合并状态的segment。如果有,则继续。没有,则返回。
2、对所有segment根据大小按照降序排序 并 剔除不符合的segment。
1)正在参与合并的segment
2) 已删除的文档比例小于 deletes_pct_allowed的segment
注意:这里没有剔除大于maxMergedSegmentBytes / 2的segment。这是和常规合并最大的区别。
3、从待合并的segment列表中分层提取segment进行merge。直到合并所有的待合并segment,则中止此次合并。这里的中止条件和常规合并的不一致。
1) 当前层中存在多个segment时,此层中segment的大小总和不得超过 maxMergedSegmentBytes。
2) 当前层中存在单个segment时,此层中的segment大小没有限制。可以大于maxMergedSegmentBytes,也可以小于maxMergedSegmentBytes。
3)每层中segment的个数不得超过 maxMergeAtOnceExplicit
注:由于待合并的segment是倒序排列,则合并的原则总是优先合并满足条件的大的segment。和常规合并的策略一致。
4.2.3 FORCE_MERGE
配置
代码语言:txt
AI代码解释
index.merge.policy.max_merge_at_once_explicit forceMerge或forceMergeDeletes方式时单次合并的最大segment数量。默认30 max_num_segments 最终合并的segment个数,通过api参数指定。 api 如下: POST /test/_forcemerge?only_expunge_deletes=false&max_num_segments=100&flush=true
算法 aly.tas1000.com55
1、对所有segment根据大小按照降序排序 并 剔除不符合的segment。
1) 正在合并中的segment
2) 大于mergeBytes的segment
2、计算合并后的单个segment大小上限(maxMergeBytes)。可以看到当指定只合并成1个segment时,maxMergeBytes基本是接近无限大的。**
最小也是maxMergedSegmentBytes的1.25倍。最大就看指定合并后的segment个数和总的待合并的大小
3、从待合并的segment列表中分层提取segment进行merge。直到合并所有的待合并segment,则中止此次合并。`这里的中止条件和常规合并的不一致。
1)单层合并
1、待合并的segment个数小于max_merge_at_once_explicit
2、只合并成1个segment。
3、待合并的segment总大小 小于 maxMergeBytes
2)分层合并
1) 当前层中存在多个segment时,此层中segment的大小总和不得超过 maxMergeBytes。