elasticsearch代码,elasticsearch接口调用

首页 > 经验 > 作者:YD1662022-11-04 04:38:13

elasticsearch代码,elasticsearch接口调用(1)

前言

看到标题以后大家有些人可能感觉有点小题大做,毕竟cilent端几行代码就能解决的问题,没必要兴师动众的来仔细讲一下。其实如果你仅仅想使用一下elasticsearch的功能,并不追求性能以及高可用性,那么这么想无可厚非。

但是如果想在生产环境下使用elasticsearch,尤其是高并发高吞吐量的场景下,那么性能优化和高可用性就不可或缺了,要做到上面两点那么数据读写这两个操作的优化是必不可少的。古语有云:“工欲善其事,必先利其器”。想要优化这两个操作,必须先了解这两个操作的原理。

曾经有一个大神说过:“完全理解了数据库的读写流程,这个数据库一半的内容已经掌握了”。既然如此重要且势在必行,那就先在网上学习下,但是网上的博客写得不太详细而且很多地方还有些小问题,于是仔细逛了一遍官网以及看了部分源码后,将相关的内容整理了出来,供自己以及需要的兄弟姐妹们观摩学习。

正文写数据

先把我画的流程图拿出来,大家可以照着图来理解接下来的流程:

elasticsearch代码,elasticsearch接口调用(2)

client写入数据时首先先连接到elasticsearch cluster的coordinator 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到底孰先孰后

public IndexResult index(Index index) throws IOException { ....... final IndexResult indexResult; if (plan.earlyResultOnPreFlightError.isPresent()) { indexResult = plan.earlyResultOnPreFlightError.get(); assert indexResult.getResultType() == Result.Type.FAILURE : indexResult.getResultType(); } else if (plan.indexIntoLucene || plan.addStaleOpToLucene) { // 将数据写入lucene,最终会调用lucene的文档写入接口 indexResult = indexIntoLucene(index, plan); } else { indexResult = new IndexResult( plan.versionForIndexing, getPrimaryTerm(), plan.seqNoForIndexing, plan.currentNotFoundOrDeleted); } if (index.origin().isFromTranslog() == false) { final Translog.Location location; if (indexResult.getResultType() == Result.Type.SUCCESS) { location = translog.add(new Translog.Index(index, indexResult)); ...... // 将数据写入lucene后才开始写translog indexResult.setTranslogLocation(location); } ....... }多副本时如何写入


elasticsearch代码,elasticsearch接口调用(3)

index buffer refreshflushsegment mergeDelete&&Update操作

Delete&&Update操作也是一种特殊的写操作,但是由于Delete&&Update操作并不是即时生效,而是通过标记删除的方式来实现,最终通过segment merge操作实现真删。所以和标准的写入还是有一定的差别,下面来说一下具体差别:

读数据

elasticsearch中的读操作包含get操作以及search操作,下面就根据这两个操作来详细讲解elasticsearch是如何进行读数据操作的。为了节省篇幅,此处统一说明一下,client从coordinator节点路由到对应数据所在节点的过程与写入数据的流程相同,请大家参考上面写数据相关的内容。下面直接就从数据节点开始讲解。

名词解释get

get操作即使用doc id字段进行单条数据的查询,查询流程图如下:

elasticsearch代码,elasticsearch接口调用(4)

search

search也是elasticsearch中比较复杂的流程。总体分为term search以及分词search。分词search内容较多,考虑到篇幅,后续会单独写一篇文章讲述。此处仅仅是为了讲解search的原理和流程,所以使用term search来进行讲解。

search操作的阶段取决于search type的选择,后续单独写一篇文章来说明elasticsearch的search type。而search type默认使用query then fetch类型,该类型由两个阶段组成:查询阶段(query)和获取阶段(fetch)阶段。

term search的流程如下:

elasticsearch代码,elasticsearch接口调用(5)

后记

elasticsearch读写不仅是将数据写入或者读出数据库,更包含了数据在elasticsearch中的流转过程,并触发elasticsearch的相关机制,这些机制都是elasticsearch的核心机制,也是性能优化以及高可用性配置的优先考虑对象。

考虑到篇幅,该篇文章也只是将主要流程解读了一下,还有很多细节没能完整讲解,这些就需要大家在以后的工作中按需了解了,但是如果能将上述篇幅中的内容完全理解,基本上也能应对绝大多数场景了。

最后,笔者长期关注大数据通用技术,通用原理以及NOSQL数据库的技术架构以及使用。如果大家感觉笔者写的还不错,麻烦大家多多点赞和分享转发,也许你的朋友也喜欢。

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.