Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elasticsearch写入文档的过程 #24

Open
TFdream opened this issue Apr 20, 2021 · 0 comments
Open

Elasticsearch写入文档的过程 #24

TFdream opened this issue Apr 20, 2021 · 0 comments

Comments

@TFdream
Copy link
Owner

TFdream commented Apr 20, 2021

这里的索引文档应该理解为文档写入ES,创建索引的过程。

文档写入包含:单文档写入和批量bulk写入,这里只解释一下:单文档写入流程。

记住官方文档中的这个图:
image

ES中接收并转发请求的节点称为coordinating节点,ES中所有节点都可以充当coordinating节点。

当一个节点接受到写请求或更新请求后,会执行如下操作:

  • 第一步:客户写集群某节点写入数据,发送请求。
  • 第二步:节点1接受到请求后,使用文档_id来确定文档属于分片0。请求会被转到另外的节点,假定节点3。因此分片0的主分片分配到节点3上。
  • 第三步:节点3在主分片上执行写操作,如果成功,则将请求并行转发到节点1和节点2的副本分片上,等待结果返回。所有的副本分片都报告成功,节点3将向协调节点(节点1)报告成功,节点1向请求客户端报告写入成功。

文档获取分片的过程?
回答:借助路由算法获取,路由算法就是根据路由和文档id计算目标的分片id的过程。

shard = hash(_routing) % (num_of_primary_shards)

注:
设置routing:获取请求URL或mapping中的_routing,如果没有则使用_id, 如果没有指定_id则ES会自动生成一个全局唯一ID。该_routing字段用于决定文档分配在索引的哪个shard上。
构建BulkShardRequest:由于Bulk Request中包含多种(Index/Update/Delete)请求,这些请求分别需要到不同的shard上执行,因此协调节点,会将请求按照shard分开,同一个shard上的请求聚合到一起,构建BulkShardRequest

将请求发送给primary shard 因为当前执行的是写操作,因此只能在primary上完成,所以需要把请求路由到primary shard所在节点。

数据存储可靠性

1.引入translog
当一个文档写入Lucence后是存储在内存中的,即使执行了refresh操作仍然是在文件系统缓存中,如果此时服务器宕机,那么这部分数据将会丢失。为此ES增加了translog, 当进行文档写操作时会先将文档写入Lucene,然后写入一份到translog,写入translog是落盘的(如果对可靠性要求不是很高,也可以设置异步落盘,可以提高性能,由配置 index.translog.durability和 index.translog.sync_interval控制),这样就可以防止服务器宕机后数据的丢失。

由于translog是追加写入,因此性能要比随机写入要好。与传统的分布式系统不同,这里是先写入Lucene再写入translog,原因是写入Lucene可能会失败,为了减少写入失败回滚的复杂度,因此先写入Lucene。

2.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建立在Lucene基础之上,底层采用Lucene来实现文件的读写操作,实现了文档的存储和高效查询。然后Lucene作为一个搜索库在应对海量数据的存储上仍有一些不足之处。

Elasticsearch通过引入分片概念,成功地将lucene部署到分布式系统中,增强了系统的可靠性和扩展性。

Elasticsearch通过定期refresh lucene in-momory-buffer中的数据,使得ES具有了近实时的写入和查询能力。

Elasticsearch通过引入translog,多副本,以及定期执行flush,merge等操作保证了数据可靠性和较高的存储性能。

Elasticsearch通过存储_source字段结合verison字段实现了文档的局部更新,使得ES的使用方式更加灵活多样。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant