ElasticSearch--写入数据的流程(原理)

原文网址:ElasticSearch--写入数据的流程(原理)_IT利刃出鞘的博客-CSDN博客

简介

        本文介绍ES是如何将数据写入磁盘并返回的。

分片的路由原理

见 :ElasticSearch--分片的路由原理_IT利刃出鞘的博客-CSDN博客

ES写到分片中的流程

ES与MySQL的写入的对比

MySQL ES
记录日志 redo log translog
复制日志 binlog translog

近实时的原理(refresh)

        ES 默认每隔 1 秒会从内存 buffer 中的数据写入 filesystem cache,这个过程叫做 refresh。这也是为什么说 ES 是近实时搜索的原因,因为数据写入到 filesystem cache 后才会被搜索到。

        Elasticsearch提供了一个refresh操作,会定时地调用lucene的reopen(新版本为openIfChanged)为内存中新写入的数据生成一个新的segment,此时被处理的文档均可以被检索到。refresh操作的时间间隔由refresh_interval参数控制,默认为1s。还可以在写入请求中带上refresh表示写入后立即refresh,另外还可以调用refresh API显式refresh。

分段(segment)

        每个 shard 都是一个 Lucene Index,包含多个 segment 文件和一个 commit point 文件。每个 segment 都是一个倒排索引,存储的是一个个 Document。commit point 记录了segment 文件信息。

        在查询的时,会把所有的 segment 查询结果汇总归并后转为最终的分片查询结果返回。

合并分段(merge)

        refresh默认间隔为1s中,因此会产生大量的小segment。为此ES会运行一个任务检测当前磁盘中的segment,对符合条件的segment进行合并操作,减少lucene中的segment个数,提高查询速度,降低负载。

        merge也是文档删除和更新操作后,旧的doc真正被删除的时候。

        用户还可以手动调用_forcemerge API来主动触发merge,以减少集群的segment个数和清理已删除或更新的文档。

提交点(commit point)

        commit point记录当前所有可用的 segment,每个 commit point 都会维护一个.del 文件(ES 删除数据本质是不属于物理删除)。

        当 ES 做删改操作时首先会在 .del 文件中声明某个 document 已经被删除,.del文件记录了在某个 segment 内某个文档已经被删除。当查询请求过来时在 segment 中被删除的文件是能够查出来的,但是当返回结果时会根据 commit point 维护的那个 .del 文件把已经删除的文档过滤掉。

部分更新

        Lucene只支持对文档的整体更新。ES为了支持局部更新,在Lucene的Store索引中存储了一个_source字段,该字段的key值是文档ID, 内容是文档的原文。当进行更新操作时先从_source中获取原文,与更新部分合并后,再调用lucene API进行全量更新, 对于写入了ES但是还没有refresh的文档,可以从translog中获取。

        为了防止读取文档过程后执行更新前有其他线程修改了文档,ES增加了版本机制,当执行更新操作时发现当前文档的版本与预期不符,则会重新获取文档再更新。

保证数据可靠新

translog(记录日志)

        ES数据是先写入缓存中,如果在写入数据时ES节点突然宕机可能会造成数据丢失。为保证数据存储的可靠性,当进行文档写操作时会先将文档写入Lucene,然后写入一份到translog,写入translog是落盘的,这样就可以防止服务器宕机后数据的丢失

        translog会每隔5秒或者在一个变更请求完成之后执行一次fsync操作,将translog从缓存刷入磁盘。如果对可靠性要求不是很高,也可以设置异步落盘,可以提高性能,由配置index.translog.durability和index.translog.sync_interval控制。

        ES 在写入缓存后,再写入 translog 日志文件(因为有可能缓存写入失败,为了减少写入失败回滚的复杂度,因此先写入缓存)。

        由于 translog 是追加写入,因此性能要比随机写入要好。

flush(写入磁盘)

        每30分钟或当translog达到一定大小(由index.translog.flush_threshold_size控制,默认512mb), ES会触发一次flush操作,此时ES会先执行refresh操作将buffer中的数据生成segment,然后调用lucene的commit方法将所有内存中的segment 写(fsync)到磁盘。此时Lucene中的数据就完成了持久化,会清空translog中的数据(6.x版本为了实现sequenceIDs,不删除translog)

其他网址

深入理解Elasticsearch写入过程 - Elastic 中文社区

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/126426436