文章目录
- 段的基础知识
- 什么是段合并
- 为什么要进行段合并
- 段合并的潜在问题
- 段合并问题的优化建议
- [段合并策略(Merge Policy)](#段合并策略(Merge Policy))
段的基础知识
我们需要在更新几点对段的基础认知,如下所示。
❑一个集群包含一个或多个节点。
❑一个节点包含一个或多个索引。
❑每个索引又由一个或多个分片组成。
❑每个分片都是一个Lucene索引实例,能够对Elasticsearch集群中的数据进行索引并处理相关查询。
❑每个分片包含多个段,每一个段都是一个倒排索引,查询时会把所有的段查询结果汇总,并将其作为最终的分片查询结果返回。
❑在Lucene中,为了实现高索引速度(高写入速度)使用了分段存储,将一批写入数据保存在一个段中,其中每个段是磁盘中的单个文件。
什么是段合并
自动刷新流程每秒会创建一个新的段(由动态配置参数refresh_interval决定),导致短时间内段数量暴增。而段数目太多会带来众多问题,包含但不限于如下几点。
❑资源消耗:每一个段都会消耗文件句柄、内存和CPU运行周期。
❑搜索变慢:每个搜索请求都必须轮流检查每个段,所以段越多,搜索也就越慢。
Elasticsearch通过在后台进行段合并来解决上述问题。小段被合并到大段,这些大段再被合并到更大的段。
段合并的时候会将那些旧的已删除文档从文件系统中清除。被删除的文档(或被更新文档的旧版本)不会被拷贝到新的大段中。当进行索引的时候,刷新操作会创建新的段并将段打开(即状态为opened)以供搜索使用。合并进程中首先会选择一部分大小相似的段,然后在后台将它们合并到更大的段中,且这个过程并不会导致索引和搜索中断。
为什么要进行段合并
Elasticsearch是一个近实时搜索引擎,文档的写入和删除是实时进行的,这意味着索引中的段数量会随着时间的推移而增加,这会导致一些问题。比如搜索效率下降,搜索时需要对多个段进行查询并将结果合并,当段数量增多时,搜索效率会变得越来越低;占用空间过多,每个段都需要占用磁盘空间,当段数量增多时,索引占用的磁盘空间也会越来越大。
为了解决这些问题,Elasticsearch需要定期对索引中的段进行合并。具体来说,段合并有以下作用。
❑提高搜索效率:合并后的大段可以减少查询时需要扫描的段的数量,从而提高搜索效率。
❑释放空间:合并后的段可以减少占用的磁盘空间,从而释放空间,减少硬盘的IO开销,该过程的细节如15.2节所述。
❑优化索引结构:段合并后可以优化索引结构,减少冗余数据,从而进一步提高搜索效率。需要注意的是,段合并操作会占用系统资源,因此Elasticsearch通常会在低峰期进行段合并。
段合并的潜在问题
虽然段合并操作可以提高搜索效率、释放空间并优化索引结构,但是它也可能带来以下问题。
❑资源消耗率高:段合并操作需要占用系统资源,例如CPU、内存、磁盘资源等,如果在高负载时进行段合并,可能会影响系统的性能。
❑磁盘碎片增多:段合并操作可能导致磁盘碎片,因为合并后的段可能不是连续的,而是由多个不连续的片段组成的,这会导致磁盘读写速度变慢,影响系统性能。
❑写入或检索延迟大:如果进行段合并操作时需要合并的段数量过多,可能会导致合并操作的时间较长,从而延迟写入操作和搜索操作。
❑极端情况下索引不可用:如果段合并操作失败或被中断,则可能会导致索引不可用,需要进行恢复操作。
为了避免以上问题,建议在低负载时进行段合并操作、定期监控索引的状态,及时进行维护和优化操作,以保证Elasticsearch的性能和稳定性。
段合并问题的优化建议
(1)针对段合并资源消耗的建议段合并会消耗磁盘IO和影响检索性能,整体来看段合并非常耗费资源,建议在非业务密集时间段实施段合并操作。
(2)段合并参数推荐
1)降低段生成的频率:默认情况下,refresh_interval设为1s。如果对数据的实时性要求并不严格,建议将此参数设置为30s或更长。这能有效降低段生成的频率,从而减少段合并的需求。
2)根据CPU核心数量调整index.merge.scheduler.max_thread_count参数:Elasticsearch会根据CPU核心数量自动设定此参数。在某些情况下,手动调整此参数可以更好地利用系统资源,优化合并性能。在调整此参数时,需要考虑到CPU的其他负载情况,以防止因合并操作占用过多资源而影响其他服务的性能。
段合并策略(Merge Policy)
TieredMergePolicy的特点是找出大小接近且最优的段集。首先,这个策略会计算在当前索引中可分配的段(segment)数量预算(budget,代码中变量allowedSegCount,通过index总大小totIndexBytes和最小段大小minSegmentBytes进行一系列计算获得),如果超预算(budget)了,策略会对段(segment)安装大小进行降序排序,找到*最小成本(least-cost)的段进行合并。最小成本(least-cost)*由合并的段的"倾斜度(skew,最大段除以最小段的值)"、总的合并段的大小和回收的删除文档的百分比(percent deletes reclaimed)来衡量。"倾斜度(skew)"越小、段(segment)总大小越小、可回收的删除文档越大,合并将会获得更高的分数。
这个策略涉及到几个重要的参数
- max_merged_segment:默认5G,合并的段的总大小不能超过这个值。
- floor_segment:当段的大小小于这个值,把段设置为这个值参与计算。默认值为2m。
- max_merge_at_once:合并时一次允许的最大段数量,默认值是10。
- segments_per_tier:每层允许的段数量大小,默认值是10。一般 >= max_merge_at_once。