热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

elasticsearchmerge

这两周主要看了下Elasticsearch(其实是Lucene)的segments的merge流程。事情起因是,线上的ES有些大索引&#x

这两周主要看了下 Elasticsearch(其实是Lucene)的 segments 的 merge 流程。事情起因是,线上的ES有些大索引,其中的segments 个数几十个,每个大小100M+,小 segments 若干,而遇到问题就是这些大的 segments 不再做 merge 了,除非强制进行forceMerge 操作,由于我们第一次ES上线,其实也不清楚这究竟是个问题还是本来 Lucene 就是这样,网上找了一些关于ES 或者 Lucene 的 merge 的策略介绍,除了说道大家都了解的一些常规的参数,如最大size,最大doc 下不会再做merge云云,就是没提到到了多少个 segments 之后就不 merge ,接着问了Elasticsearch 圈子的一些人,也没有找到非常确定的答案。查找几天资料无果,顺带就看看源码,最终在昨天又瞄了几眼终于发现一段算法,虽无验证,但应八九不离十,故记录分享之。




Segments

首先还是先重温一下 Lucene 下的 segments,对这个比较陌生的可以阅读三斗大神的这一节


  • segment、buffer和translog对实时性的影响

Lucene产生segments示意图

我只引用最下面那张图介绍一下,绿色的就是已经固化的一个个的 segments 文件,不会再更新,左下角就是当前在内存的 Lucene 维护的查询可见的仍为持久化的segment,当Elasticsearch 配置的refresh_invterval (默认是1s,可调)到时,这些in in-memory buffer就会推送到OS的文件系统缓存中去,注意这里只是到缓存,很可能OS仍未持久化到文件系统,成为一个单独的 segment 文件,而啥时commit 到文件系统永不丢失,则由Lucene 的flush 机制保证,当Lucene 做完flush 则表明该 segment 真正推送到文件系统,此时才会在translog做标记并可以删除commit之前的translog 了。


注意这里只是一个简化描述,据三斗和赖总介绍,Lucene 仍有很多因素会促使产生一个segment 而不是百分百由Elasticsearch的refresh_interval 决定。这里就不继续讨论究竟在哪些情况会立即生成一个segment了。



Segment 的merge

详细信息可看三斗这一节 这里只引用两个图介绍一下

merge前

merge后

从图上看,Lucene每次会选取一些小的segments 进而merge到一个大的segment,我这里不再赘述流程和策略,这里只补充一句就是,如果你之前用的scroll查询,之前的scroll还是会指向老的segments,也就是说老的segments 的引用会知道scroll失效后才会被回收。




Elasticsearch 5.x merge 参数的变化

在老的Elasticsearch 中,merge 被认为是一个非常消耗资源的操作,甚至只有一个线程来做这事,并且会影响indexing的request。在之前的版本里,merge 操作用的是一类 merge throttle limit这样的配置来限制各种峰值数据,如下面这些参数,注意这些参数都已经在5.x 中移除掉了。


  • indices.store.throttle.type


  • indices.store.throttle.max_bytes_per_sec

因为在Elasticsearch 5.x 想采用多线程和动态调整这种方式来更加智能地去执行merge操作。如检测是否使用SSD硬盘,应该启动多少个merge线程等。
在Elasticsearch 5.x 下,tired merge policy 成为了唯一的merge策略。因此下面的参数同样也在5.x 下被移除了。


  • index.merge.policy.type


  • index.merge.policy.min_merge_size
  • index.merge.policy.max_merge_size
  • index.merge.policy.merge_factor
  • index.merge.policy.max_merge_docs
  • index.merge.policy.calibrate_size_by_deletes
  • index.merge.policy.min_merge_docs
  • index.merge.policy.max_merge_docs

如上面说的,ES希望采用一种更智能的方式去调整这些参数,达到一个性能的折中。在5下我们可以配置这些参数:


  • index.merge.policy.expunge_deletes_allowed: 指删除了的文档数在一个segment里占的百分比,默认是10,大于这个值时,在执行expungeDeletes 操作时将会merge这些segments.


  • index.merge.policy.floor_segment: 官网的解释我没大看懂,我的个人理解是ES会避免产生很小size的segment,小于这个阈值的所有的非常小的segment都会做merge直到达到这个floor 的size,默认是2MB.
  • index.merge.policy.max_merge_at_once: 一次最多只操作多少个segments,默认是10.
  • index.merge.policy.max_merge_at_once_explicit: 显示调用optimize 操作或者 expungeDeletes时可以操作多少个segments,默认是30.
  • index.merge.policy.max_merged_segment: 超过多大size的segment不会再做merge,默认是5g.
  • index.merge.policy.segments_per_tier: 每个tier允许的segement 数,注意这个数要大于上面的at_once数,否则这个值会先于最大可操作数到达,就会立刻做merge,这样会造成频繁
  • index.reclaim_deletes_weight: 考虑merge的segment 时删除文档数量多少的权重,默认即可.
  • index.compund_format: 还不知道干啥用的,默认即可.



merge 线程调整

Elasticsearch 5 采用了多线程去执行merge,可以通过修改index.merge.scheduler.max_thread_count 来动态调整这个线程数,默认的话是通过下面公式去计算:


推荐阅读
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • C#多线程解决界面卡死问题的完美解决方案
    当界面需要在程序运行中不断更新数据时,使用多线程可以解决界面卡死的问题。一个主线程创建界面,使用一个子线程执行程序并更新主界面,可以避免卡死现象。本文分享了一个例子,供大家参考。 ... [详细]
  • 本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。 ... [详细]
  • 本文介绍了Composer依赖管理的重要性及使用方法。对于现代语言而言,包管理器是标配,而Composer作为PHP的包管理器,解决了PEAR的问题,并且使用简单,方便提交自己的包。文章还提到了使用Composer能够避免各种include的问题,避免命名空间冲突,并且能够方便地安装升级扩展包。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
author-avatar
阿钱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有