ES集群搜索稳定性保障

发布时间 2023-09-04 21:03:14作者: 大熊猫同学

如果将 Elasticsearch(ES)作为线上C端服务的查询引擎,那么 search query 的响应时间则至关重要。因为毕竟面向C端用户,如果一个搜索请求 1 秒内还未返回,那么用户将不可接受。

因此,C端服务对ES的性能稳定性做了许多工程上的优化,比如:

  1. 强制将索引的段文件设置为1,也即索引中只有一个段文件。
  2. 禁用swap,这在ES官方文档也有提及:https://www.elastic.co/guide/en/elasticsearch/reference/current/_memory_lock_check.html
    (这篇文章也提到了mlock)
  3. ES 节点启动时预热(预加载)

本文介绍,通过 memory lock 锁住“倒排索引”,避免搜索的核心数据结构被 swap 到磁盘上。
首先看背景:大神的文章:https://blog.mikemccandless.com/2010/07/lucenes-ram-usage-for-searching.html 讲了 lucene 在检索时,若“索引文件”被 swap 到磁盘上,则会存在严重的查询性能问题。
而我们可通过 linux 的 mlock 命令,(参考:https://man7.org/linux/man-pages/man2/mlock.2.html )将“倒排索引”文件 Lock 在内存,保障这些核心数据结构不被 swap out。
那 lock 哪些文件呢?主要有3类:

  1. .tim 文件。这是:词典/字典/Term:存储所有的Term的地方,另外在.tim文件中还存储了该term在.doc、.pos、.pay文件中的偏移量,我们可以快速定位到term关联的doc链表、Pos位置、Payload相关信息。

  2. .tip文件。字典索引/Term索引:为了加速查找Term在.tim中的位置,需要对字典做索引,Lucene使用FST作为Term的前缀索引,这个存储在.tip文件中。

  3. 倒排链:倒排链存放在.doc文件中,是一系列的有序doc的集合,另外为了快速做查找和遍历 .doc中还存储了跳表,方便快速定位到doc。

因此,在 ES索引构建成功后,通过 快照 将索引恢复(snapshot restore)到内存后,就可以将这3类文件通过:linux mlock 命令 lock 住,进一步保障在线C端查询服务依赖的ES 查询性能更稳定。

具体实现是:基于 ES 插件机制,开发一个 rest-handler 处理插件,该插件接收 mlock 命令,然后通过 JNA 方式调用 libc 函数库,从而执行 mlock命令,将此 ES节点 的倒排索引文件 lock 住。