Elasticsearch 架构原理—— 新数据写入过程

40次阅读

共计 1337 个字符,预计需要花费 4 分钟才能阅读完成。

前言
在分布式日志服务架构中,我们只需要将 logstash 的 output 指向 ES 就可以了,但是,写入的数据是如何变成 Elasticsearch 里可以被检索和聚合的索引内容的呢?本文重点介绍数据在写入 Elasticsearch 索引流程中发生的具体操作。重点在于其中 segment、buffer 和 translog 三部分对实时性和性能方面的影响。
动态更新的 Lucene 索引
Lucene 对于新收到的数据写入到新的索引文件里。Lucene 把每次生成的倒排索引,叫做一个 segment,然后另外使用一个 commit 文件,记录索引内所有的 segment。而生成 segment 的数据来源则是放在内存中的 buffer,也就是说,动态更新过程如下:

当前索引有 3 个 segment 可用;
新接收的数据进入内存 buffer;
内存 buffer 刷到磁盘,生成一个新的 segment,commit 文件同步更新。

利用磁盘缓存实现的准实时检索
上面的内容中,内存 buffer 刷入磁盘,但是不可避免的问题就是写磁盘太慢了。对于我们的日志服务来说,如果要进行一些实时性统计,这个速度是不能接受的。所以,在内存 buffer 刷入磁盘的处理中,还有一个中间状态:

内存 buffer 生成一个新的 segment,刷到文件系统缓存中,Lucene 即可检索这个新的 segment。
文件系统缓存真正同步到磁盘上,commit 文件更新。

其实就是多加了一步文件系统缓存。Elasticsearch 中默认 1s 中刷新一次。如果觉得间隔时间还是很短,可以调用 /_refresh 接口来修改。不过对于日志场景来说,我们更需要的是更快的写入性能,所以我们最好是通过 /_settings 接口或者定制 template 的方式,加大 refresh_intereval 参数:
curl -XPOST http://127.0.0.1:9200/logstash-lms-2019.02.19/_settings -d'{“refresh_interval”:”10s”}’
如果是导入历史数据的场合,甚至可以直接关闭。
索引数据一致性保证——translog 提供的磁盘同步控制
refres 只是写到文件系统缓存,如果最后一步写入到磁盘期间发生了错误、硬件故障灯问题,数据会丢失吗?这里有另一个控制机制。Elasticsearch 在把数据写入到内存 buffer 的同时,其实还另外记录了一个 translog 日志。refres 发生时,translog 日志文件依旧保持原样。如果期间发生异常,Elasticsearch 会从 commit 位置开始,恢复整个 translog 文件中的记录,保证数据一致性。等到真正吧 segment 刷新到磁盘,commit 文件更新后,translog 才会清空,即 flush 操作。Elasticsearch 默认 30 分钟 flush 一次,或者 translog 文件 >512M 时会主动 flush。可以通过以下参数进行设置:
index.translog.flush_threshold_period
index.translog.flush_threshold_size
#控制每收到多少条数据后 flush 一次
index.translog.flush_threshold_ops

正文完
 0