ES的写入流程

373 阅读4分钟

ES的写入流程

ElasticSearch搜索引擎:数据的写入流程_张维鹏的博客-CSDN博客_elasticsearch数据写入流程

【Elasticsearch 技术分享】—— 十张图看懂ES原理 !明白为什么说:ES 是准实时的! - 知乎 (zhihu.com)

理解ES的refresh、flush、merge_强哥叨逼叨的博客-CSDN博客_es refresh

ES写数据的整体流程:

image_vqGGksVQfn.png

image_XbFt4pwNzg.png

(1)客户端选择 ES 的某个 node 发送请求过去,这个 node 就是协调节点 coordinating node (2)coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard) (3)实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node (4)coordinating node 等到 primary node 和所有 replica node 都执行成功之后,最后返回响应结果给客户端。

ES主分片写数据的详细流程:

image_k5nvB1T-On.png image_Tpo3MEWwCT.png

(1)主分片先将数据写入ES的 memory buffer,然后定时(默认1s)将 memory buffer 中的数**据写入一个新的 segment **文件中,并进入操作系统缓存 Filesystem cache(同时清空 memory buffer)(注意这时候还没有commit罗),这个过程就叫做 refresh;每个 segment 文件实际上是一些倒排索引的集合, 只有经历了 refresh 操作之后,这些数据才能变成可检索的。

(2)由于 memory Buffer 和 Filesystem Cache 都是基于内存,假设服务器宕机,那么数据就会丢失,所以** ES 通过 translog 日志文件来保证数据的可靠性,** 在数据写入 memory buffer 的同时,将数据也写入 translog 日志文件中,当机器宕机重启时,es 会自动读取 translog 日志文件中的数据,恢复到 memory buffer 和 Filesystem cache 中去。

ES 的近实时性(NTR)(refresh):

数据存在 memory buffer 时是搜索不到的,只有数据被 refresh 到 Filesystem cache 之后才能被搜索到,而 refresh 是每秒一次, 所以称 es 是近实时的;可以手动调用 es 的 api 触发一次 refresh 操作,让数据马上可以被搜索到;

ES 数据丢失的问题:

translog有两种落盘时机

1 request — 每操作都写(默认策略),可靠性最高。

2 async — 异步定时写,可靠性跟时间间隔有关,试问自己断电时你能接受多少数据无法恢复?

第二种落盘时机,translog 也是先写入 Filesystem cache,然后默认每隔 5 秒刷一次到磁盘中,所以默认情况下,可能有 5 秒的数据会仅仅停留在 memory buffer 或者 translog 文件的 Filesystem cache中,而不在磁盘上,如果此时机器宕机,会丢失 5 秒钟的数据。

为了保证数据不丢失,可以将 translog 设置成每次写操作必须是直接 fsync 到磁盘,但是性能会差很多。

flush

不断重复上面的步骤,translog 会变得越来越大,不过 translog 文件默认每30分钟或者 阈值超过 512M 时,就会触发 commit 操作,即 flush操作,将 memory buffer 中所有的数据写入新的 segment 文件中, 并将内存中所有的 segment 文件全部落盘,最后清空 translog 事务日志。

commit操作主要做以下几件事

① 将 memory buffer 中的数据 refresh 到 Filesystem Cache 中去,清空 buffer; ② 创建一个新的 commit point(提交点),同时强行将 Filesystem Cache 中目前所有的数据都 fsync 到磁盘文件中; ③ 删除旧的 translog 日志文件并创建一个新的 translog 日志文件,此时 commit 操作完成

merge

每次refresh操作都会生成一个新的segment,随着时间的增长segmengt会越来越多,这就出现一个比较严重的问题是每次search操作必须依次扫描所有的segment,导致查询效率变慢,为了避免该问题es会定期多这个segment进行合并操作。

将refresh产生的多个小segment整合为一个大的segment的操作就叫做merge。同时merge操作会将已经打.del标签的文档从文件系统进行物理删除。merge属于一个后台操作。

在es中每个delete操作其实都是对将要删除的文档打一个.del的标签,同理update操作就是将原文档进行.del打标然后插入新文档,只有merge操作才会将这些已经打标的.del文件真正进行物理删除。(逻辑删除/软删除)

一个大segment的merge操作是很消耗CPU、IO资源的,如果使用不当会影响到本身的serach查询性能。es默认会控制merge进程的资源占用以保证merge期间search具有足够资源。