es写入数据的工作原理是什么?

文章详细阐述了Elasticsearch(ES)的写数据流程,包括客户端请求、协调节点分配、主副分片处理以及数据同步。同时,深入介绍了数据写入的底层原理,如先写入buffer和translog,然后通过refresh操作进入oscache,最后通过flush操作持久化到磁盘,确保数据安全并支持搜索。translog用于故障恢复,merge操作则用于合并segmentfile并清理已删除文档。

在这里插入图片描述
流程图

一. es写数据过程

1)客户端任意选择一个node发送请求过去,这个node就是coordinating node(协调节点)
2)coordinating node,对该数据经过hash后,判断该数据属于哪个shard进程,找到有该shard的primary shard的node,然后对document进行路由,将请求转发给对应的node(有primary shard的结点)
3)具体接收的primary shard处理请求,然后将数据同步到replica node
4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端

二.es写数据的底层原理

写数据底层原理

1)先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件(防止宕机buffer数据丢失)

2)如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh。

默认每隔1秒钟,es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件 segment file,这个segment file中就存储最近1秒内buffer中写入的数据

但是如果buffer里面此时没有数据,那当然不会执行refresh操作,不会创建文件,如果buffer里面有数据,默认1秒钟执行一次refresh操作,刷入一个新的segment file中;

操作系统里面,磁盘文件其实都有一个东西,叫做os cache,操作系统缓存,就是说数据写入磁盘文件之前,会先进入os cache,先进入操作系统级别的一个内存缓存中去,再进入磁盘

只要buffer中的数据被refresh操作,刷入os cache中,就代表这个数据就可以被搜索到了,只要数据被输入os cache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份了

这里也解释了为什么叫es是准实时的?NRT,near real-time,准实时。
因为其默认是每隔1秒refresh一次的,有一定延迟,所以es是准实时的,因为写入的数据1秒之后才能被看到。
这个延迟也可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os
cache中,让数据立马就可以被搜索到。

3)只要数据进入os cache,此时就可以让这个segment file的数据对外提供搜索了

4)重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去(数据写入到segment file里后就建立好了倒排索引),每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发 translog 的commit操作。

buffer中的数据,倒是好,每隔1秒就被刷到os cache中去,然后这个buffer就被清空了。所以说这个buffer的数据始终是可以保持住不会填满es进程的内存的。

每次一条数据写入buffer,同时会写入一条日志到translog日志文件中去,所以这个translog日志文件是不断变大的,当translog日志文件大到一定程度的时候,就会执行commit操作。

5)commit操作发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer

6)将一个commit point写入磁盘文件,里面标识着这个commit point对应的所有segment file

7)强行将os cache中目前所有的数据都fsync到磁盘文件中去

translog日志文件的作用是什么? 在执行commit操作之前,可能有些数据要么是停留在buffer中,要么是停留在os
cache中,无论是buffer还是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。
所以需要将数据对应的操作写入一个专门的日志文件,translog日志文件中,一旦此时机器宕机,再次重启的时候,es会自动读取translog日志文件中的数据,恢复到内存buffer和os
cache中去。

commit操作:1、写commit point;2、将os cache数据fsync强刷到磁盘上去;3、清空translog日志文件

8)将现有的translog清空,然后再次重启启用一个translog,此时commit操作完成。
默认每隔30分钟会自动执行一次commit,但是如果translog过大,也会触发commit。
整个commit的过程,叫做flush操作。我们可以手动执行flush操作,就是将所有os cache数据刷到磁盘文件中去。

不叫做commit操作,flush操作。es中的flush操作,就对应着tanslog commit的全过程。我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件。

9)translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去
所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。也可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多。

所以其实es第一是准实时的,数据写入1秒后可以搜索到;可能会丢失数据的,你的数据有5秒的数据,停留在buffer、translog os cache、segment file os cache中,有5秒的数据不在磁盘上,此时如果宕机,会导致5秒的数据丢失。
如果你希望一定不能丢失数据的话,你可以设置个参数,每次写入一条数据,都是写入buffer,同时写入磁盘上的translog,但是这会导致写性能、写入吞吐量会下降一个数量级。本来一秒钟可以写2000条,现在你一秒钟只能写200条,都有可能。

10)如果是删除操作,commit的时候会生成一个.del文件(磁盘),里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了

11)如果是更新操作,就是将原来的doc标识为deleted状态,然后新写入一条数据

12)buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,此时会定期执行merge

13)每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file,然后打开segment file供搜索使用,同时删除旧的segment file。

es里的写流程,有4个底层的核心概念,refresh、flush、translog、merge

### Elasticsearch 数据快速查找的实现原理 Elasticsearch 是一个基于 Lucene 的分布式搜索和分析引擎,能够实现实时、可扩展的全文搜索与结构化数据检索[^2]。其核心机制包括倒排索引(Inverted Index)、分片(Sharding)以及分布式查询执行策略。 #### 倒排索引机制 Elasticsearch 使用倒排索引作为其数据存储和检索的核心结构。倒排索引将文档中的词汇映射到包含该词汇的文档列表中,从而使得关键词的查找变得高效。例如,对于一组文档: - 文档1:`"The quick brown fox"` - 文档2:`"Quick jumps"` 倒排索引可能如下所示: ``` { "the": [1], "quick": [1, 2], "brown": [1], "fox": [1], "jumps": [2] } ``` 这种结构允许在用户输入查询词后,系统迅速定位相关文档,而无需遍历所有数据。倒排索引由 Lucene 提供支持,Lucene 是一个高效的全文检索库,负责构建和维护索引结构[^3]。 #### 分片与副本机制 为了提高性能和容错能力,Elasticsearch 将索引划分为多个分片(shards),每个分片是一个独立的 Lucene 索引。数据写入时会根据文档 ID 被分配到特定的分片上,从而实现水平扩展。同时,每个分片可以配置多个副本(replicas),用于负载均衡和高可用性。查询可以在主分片或副本分片上执行,避免单点故障并提升并发处理能力[^2]。 例如,创建一个具有3个分片和2个副本的索引: ```json PUT /my_index { "settings": { "number_of_shards": 3, "number_of_replicas": 2 } } ``` #### 查询执行流程 当用户发起查询请求时,协调节点(coordinating node)接收请求,并将其广播到涉及的所有分片。每个分片本地执行查询并返回匹配的文档ID及评分信息。协调节点汇总结果后进行排序、分页等操作,最终返回给客户端。这一过程充分利用了分布式计算的优势,确保大规模数据集上的查询仍然具备高性能[^2]。 #### 实时性与刷新机制 Elasticsearch 支持近实时搜索(Near Real-Time Search)。默认情况下,索引更新每秒刷新一次(refresh interval = 1s),即新插入或更新的数据在一秒内即可被搜索到。如果对实时性要求更高,可以手动触发刷新: ```json POST /my_index/_refresh ``` 此外,translog 日志文件保证了数据在崩溃恢复时不会丢失。每次写入操作都会记录到 translog 中,并在 flush 操作后持久化到磁盘。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值