前言
看到标题以后大家有些人可能感觉有点小题大做,毕竟cilent端几行代码就能解决的问题,没必要兴师动众的来仔细讲一下。其实如果你仅仅想使用一下elasticsearch的功能,并不追求性能以及高可用性,那么这么想无可厚非。
但是如果想在生产环境下使用elasticsearch,尤其是高并发高吞吐量的场景下,那么性能优化和高可用性就不可或缺了,要做到上面两点那么数据读写这两个操作的优化是必不可少的。古语有云:“工欲善其事,必先利其器”。想优化这两个操作,必须先了解这两个操作的原理。
曾经有一个大神说过:“完全理解了数据库的读写流程,这个数据库一半的内容已经掌握了”。既然如此重要且势在必行,那就先在网上学习下,但是网上的博客写的不太详细而且很多地方还有些小问题,于是仔细逛了一遍官网以及看了部分源码后,将相关的内容整理了出来,供自己以及需要的兄弟姐妹们观摩学习。
正文
写数据
先把我画的流程图拿出来,大家可以照着图来理解下来的流程:

client写入数据时首先先连接到elasticsearch cluster的coordinator node(如果对elasticsearch的node不了解的话,可以参考下这篇文章一文详解Elasticsearch中的Node角色以及使用方法),coordinator node根据需要写入数据的doc id字段(默认使用该字段,如果数据写入指定了routing的话,则使用routing进行分片路由)进行路由到对应的分片。路由计算方式:shard=hash(document id)%(num_of_primary_shards),然后根据节点的cluster state找到该shard所在的data node,请求就被转发到了该data node
refresh
下面就开始正式的写数据流程了。首先数据被写入到elasticsearch的index buffer中,该buffer在elasticsearch的heap中。写完index buffer后,数据才会写入到translog中,translog写入完毕后即可以返回客户端写入成功。此处有几个问题需要强调下,也是网上的资料经常出问题的地方,划重点:
index buffer和translog到底孰先孰后
-
和数据库不同,数据库是先写CommitLog,然后再写内存,而Elasticsearch是先写内存,最后才写TransLog。这个有悖常理,笔者也曾经很费解,后来考虑到可能是因为Lucene的内存写入很重很复杂,很容易失败,比如分词,字段类型不匹配且无法转型,字段长度超过限制等,为了避免TransLog中有大量无效记录,减少recover的复杂度并提升效率,所以就把写Lucene放在了写translog前面。
-
此处需要说明下,网上很多博客都说先写translog后写index buffer或者同时写translog和index buffer的,这些优势有文艺的,为了证明,拿出最好的证据-源码来说明问题:
public IndexResult index(Index index) throws IOException {
.......
final IndexResult indexResult;
if (plan.earlyResultOnPreFlightError.isPresent()) {
&nbs

本文详细探讨了Elasticsearch在生产环境中的数据读写流程,包括写数据时的索引缓冲区、Translog机制,以及多副本同步策略。在读数据方面,解释了Get和Search操作的实现原理,涉及到正排索引、倒排索引和SegmentCache的使用。通过对这些核心机制的理解,有助于优化性能和确保高可用性。
最低0.47元/天 解锁文章
1926

被折叠的 条评论
为什么被折叠?



