Elasticsearch架构原理

本文介绍了Elasticsearch的工作原理,包括数据如何变为可检索的索引内容,Lucene的segment机制,refresh和translog的角色,以及分布式的路由和副本策略。强调了实时性与写入性能的平衡,以及flush、merge过程和归并策略对性能的影响。还讨论了数据一致性、磁盘IO控制和集群的自动发现与故障恢复机制。
摘要由CSDN通过智能技术生成

架构原理

本书作为 Elastic Stack 指南,关注于 Elasticsearch 在日志和数据分析场景的应用,并不打算对底层的 Lucene 原理或者 Java 编程做详细的介绍,但是 Elasticsearch 层面上的一些架构设计,对我们做性能调优,故障处理,具有非常重要的影响。

所以,作为 ES 部分的起始章节,先从数据流向和分布的层面,介绍一下 ES 的工作原理,以及相关的可控项。各位读者可以跳过这节先行阅读后面的运维操作部分,但作为性能调优的基础知识,依然建议大家抽时间返回来了解。

带着问题学习

写入的数据是如何变成elasticsearch里可以被检索和聚合的索引内容的?

lucene如何实现准实时索引?

什么是segment?

什么是commit?

segment的数据来自哪里?

segment在写入磁盘前就可以被检索,是因为利用了什么?

elasticsearch中的refresh操作是什么?配置项是哪个?设置的命令是什么?

refresh只是写到了文件系统缓存,那么实际写入磁盘是由什么控制呢?,如果这期间发生错误和故障,数据会不会丢失?

什么是translog日志?什么时候会被清空?什么是flush操作?配置项是什么?怎么配置?

什么是段合并?为什么要段合并?段合并线程配置项?段合并策略?怎么forcemerge(optimize)?

routing的规则是什么样的?replica读写过程?wait_for_active_shards参数timeout参数 ?

reroute 接口?

两种 自动发现方式?

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

既然介绍数据流向,首先第一步就是:写入的数据是如何变成 Elasticsearch 里可以被检索和聚合的索引内容的?

以单文件的静态层面看,每个全文索引都是一个词元的倒排索引,具体涉及到全文索引的通用知识,这里不单独介绍,有兴趣的读者可以阅读《Lucene in Action》等书籍详细了解。

动态更新的 Lucene 索引

以在线动态服务的层面看,要做到实时更新条件下数据的可用和可靠,就需要在倒排索引的基础上,再做一系列更高级的处理。

其实总结一下 Lucene 的处理办法,很简单,就是一句话:新收到的数据写到新的索引文件里

Lucene 把每次生成的倒排索引,叫做一个段(segment)。然后另外使用一个 commit 文件,记录索引内所有的 segment。而生成 segment 的数据来源,则是内存中的 buffer。也就是说,动态更新过程如下:

当前索引有 3 个 segment 可用。索引状态如图 2-1;

图 2-1

新接收的数据进入内存 buffer。索引状态如图 2-2;

图 2-2

内存 buffer 刷到磁盘,生成一个新的 segment,commit 文件同步更新。索引状态如图 2-3。

图 2-3

利用磁盘缓存实现的准实时检索

既然涉及到磁盘,那么一个不可避免的问题就来了:磁盘太慢了!对我们要求实时性很高的服务来说,这种处理还不够。所以,在第 3 步的处理中,还有一个中间状态:

内存 buffer 生成一个新的 segment,刷到文件系统缓存中,Lucene 即可检索这个新 segment。索引状态如图 2-4。

图 2-4

文件系统缓存真正同步到磁盘上,commit 文件更新。达到图 2-3 中的状态。

这一步刷到文件系统缓存的步骤,在 Elasticsearch 中,是默认设置为 1 秒间隔的,对于大多数应用来说,几乎就相当于是实时可搜索了。Elasticsearch 也提供了单独的/_refresh接口,用户如果对 1 秒间隔还不满意的,可以主动调用该接口来保证搜索可见。

注:5.0 中还提供了一个新的请求参数:?refresh=wait_for,可以在写入数据后不强制刷新但一直等到刷新才返回。

不过对于 Elastic Stack 的日志场景来说,恰恰相反,我们并不需要如此高的实时性,而是需要更快的写入性能。所以,一般来说,我们反而会通过/_settings接口或者定制 template 的方式,加大refresh_interval参数:

# curl -XPOST http://127.0.0.1:9200/logstash-2015.06.21/_settings -d'

{ "refresh_interval": "10s" }

'

如果是导入历史数据的场合,那甚至可以先完全关闭掉:

# curl -XPUT http://127.0.0.1:9200/logstash-2015.05.01 -d'

{

"settings" : {

"refresh_interval": "-1"

}

}'

在导入完成以后,修改回来或者手动调用一次即可:

# curl -XPOST http://127.0.0.1:9200/logstash-2015.05.01/_refresh

translog 提供的磁盘同步控制

既然 refresh 只是写到文件系统缓存,那么第 4 步写到实际磁盘又是有什么来控制的?如果这期间发生主机错误、硬件故障等异常情况,数据会不会丢失?

这里,其实有另一个机制来控制。Elasticsearch 在把数据写入到内存 buffer 的同时,其实还另外记录了一个 transl

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农老K

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值