当前位置:首页 > 经验 >

elasticsearch代码(elasticsearch接口调用)

来源:原点资讯(www.yd166.com)时间:2022-11-04 04:38:13作者:YD166手机阅读>>

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到底孰先孰后
  • 和数据库不同,数据库是先写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()) { 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); } ....... }多副本时如何写入

  • 上面的是单副本情况下的写入,如果是多副本写入可以参考下面的图。默认情况下,当primary shard写入成功后,即返回写入成功,后续replica shard通过异步的方式同步数据或者translog恢复数据。
  • 该机制可以通过设置index.write.wait_for_active_shards参数进行设置。该参数可以使用all或者在1到副本数加1(number_of_replicas 1)之间任何的一个整数值。如果是all也就是等待主分片和副本都写入成功,请求才返回,这样可以保证elasticsearch的强一致性,但是代价一是写入线程会阻塞,影响吞吐量;二是会影响elasticsearch的可用性。有一个节点不正常写入就会阻塞,直到节点恢复或者写入超时。

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

index buffer refresh
  • 数据写入到这里的时候还无法被搜索到,默认1s后执行refresh操作,将内容写入文件系统缓冲区(os cache)中的新段(segment)。此segment的内容尚未被fsynced(未被写入到硬盘),但是segment是打开的,内容可被搜索。
  • 但是1s一次的refresh会导致频繁生成新文件,在占用大量句柄以及系统资源的同时也会影响到查询数据的效率。所以对于实时性要求不是很高的业务场景,可以将refresh的时间拉长,比如30s,"index.refresh_interval":"30s"
  • 最后在refresh写完segment后会更新shard的commit point。commit point在shard中以segments_xxx名字的文件存在。用来记录每个shard中segment相关的信息。
flush
  • 当os cache中的segments数据积累到一定时间(默认30分钟)或者translog达到一定大小时(默认512M),os cache中的segments会被flush到硬盘上进行持久化,持久化成功后,对应的translog由于失去存在的意义而被删除。
  • 此处有几个参数和flush相关,大家可以根据需求进行配置: index.translog.flush_threshold_ops:当发生多少次操作时进行一次flush。默认是 unlimited。 index.translog.flush_threshold_size:当translog的大小达到此值时会进行一次flush操作。默认是512mb。 index.translog.flush_threshold_period:在指定的时间间隔内如果没有进行flush操作,会进行一次强制flush操作。默认是30m。 index.translog.interval:多少时间间隔内会检查一次translog,来进行一次flush操作。es会随机地在这个值到这个值的2倍大小之间进行一次操作,默认是5s。
segment merge
  • segments被持久化后写入硬盘,硬盘上的segments的数量就会越来越多,又会引发句柄占用以及影响查询效率,所以此时会触发segment merge操作。由于这个操作比较复杂,受限于本文长度就先不在这里说了,后续会专门写一篇文章来说明。
Delete&&Update操作

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

  • Delete:磁盘上的每个分段(segement)都有一个.del文件与它关联。当客户端发送删除请求时,该文档未被真正删除,而是在.del文件中标记为已删除。此文档仍然可能被搜到,但会从结果中过滤掉。当分段合并时,在.del文件中标记为删除的文档不会包括在新的合并段中。
  • Update:创建新文件,Elasticsearch将该文档分配一个版本号。对文档的每次更改都会产生一个新的版本号,版本号使用versionMap来进行管理,用以减少热点数据的多次磁盘IO开销。当执行更新时,旧版本在.del文件中标记为已删除,并且并且在新版本的分片中编入索引。旧版本可能仍然与搜索查询匹配,但是从结果中将其过滤掉。
读数据

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

名词解释
  • 正排索引:doc id -> value,方向是正常方向,所以称为正排索引。使用场景是get这种通过doc id找value的场景。在shard中以后缀名为fdx与fdt结尾的文件存储,dfx是索引文件,fdt是数据文件。这两部分数据是硬盘消耗的大户,elasticsearch中的source字段即存储在fdt文件中。
  • 倒排索引:index -> doc id,方向与上面的相反,所以称为倒排索引。使用场景是search通过查询条件匹配对应的倒排索引拿到对应数据的doc id,拿到doc id后查询正排索引拿到真正的数据。在shard中以后缀名除了正排索引外绝大部分都是各种类型的倒排索引,每一种倒排索引也分为索引文件和数据文件。这两部分数据是内存消耗的大户,elasticsearch中的倒排索引都会加载到off heap中用来加速查询,这也是要留给lucene一半内存最主要的原因。
get

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

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

  • 首先使用doc id字段从os cache中的translog中查询,如果能查询到就直接返回客户端;
  • 如果os cache中的translog没有查询到的话,再去disk上的tranlog中查询,如果能查询到就直接返回客户端;
  • 如果reanslog中没有查询到对应的数据,再去segment中查询对应的数据。首先把正排索引的fdx数据加载到off heap中去查询doc id。如果查询不到则直接返回null;如果能查询到doc id,根据查询结果中的偏移量直接去硬盘上查询对应的原始数据并返回。
  • 此处大家思考下get操作(其实update以及delete操作也会优先查询translog)为什么要优先查询translog后再去查询segment数据?这里说明一下原因:上文已经说过了delete以及update操作在elasticsearch中都是先打删除标记然后通过segment merge操作进行真删,所以一条数据可能在elasticsearch中有几个版本,而最新的版本可能会存在于translog中。所以如果在translog中查询到目标数据直接返回即可,一定是最新的数据;如果translog中没有目标数据,再去segments中查询。
search

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

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

  • 查询阶段:在此阶段,协调节点将搜索请求路由到索引中的所有分片(包括:主分片和副本分片)。分片独立执行搜索,并根据相关性分数创建一个优先级排序结果.所有分片将匹配到的文档和相关性分数的文档id返回给协调节点。协调节点创建一个新的优先级队列,并对全局结果进行排序。可以有很多文档匹配结果,但默认情况下,每个分片将前10个结果发送到协调节点,协调节点创建优先级队列,从所有分片中分选结果并返回前10个匹配结果。
  • 获取阶段:在协调节点对所有的结果进行排序,生成全局排序的文档列表后,它将所有分片请求原始文档。所有的分片都会丰富文档并将其返回到协调节点。

term search的流程如下:

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

  • 首先client会根据search中的term去elasticsearch heap中的Segment Cache中查询FST数据(如果不知道FST数据建议参考之前的博文),简单来说就是倒排索引的前缀树。
  • 根据FST数据来查询对应的倒排索引tip文件,将tip文件加载到off heap中进行查询,将查询后的索引数据查询倒排索引数据tim文件,得到对应的doc id列表。
  • 根据doc id列表将对应的正排索引文件fdx数据当如到off heap中查询对应doc id的地址,查询之后去fdt文件中取出对应的原始数据中必要的信息返回到协调节点(完整的数据在fetch阶段获取)。
后记

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

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

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

栏目热文

elasticsearch 做什么用的(elasticsearch有什么用)

elasticsearch 做什么用的(elasticsearch有什么用)

作者:靠发型吃饭的柳树 来自:柳树的絮叨叨Elasticsearch是什么? Elasticsearch is the ...

2022-11-04 04:17:02查看全文 >>

elasticsearch是用什么语言写的(es数据查询)

elasticsearch是用什么语言写的(es数据查询)

我们之前介绍了相关的技术,并且也简单介绍了Elasticsearch相关的基本知识。那通过之前的内容我们知道Elasti...

2022-11-04 04:23:08查看全文 >>

elasticsearch干什么的(elasticsearch适合做什么)

elasticsearch干什么的(elasticsearch适合做什么)

由于近期在公司内部做了一次 Elasticsearch 的分享,所以本篇主要是做一个总结,希望通过这篇文章能让读者大致了...

2022-11-04 04:20:30查看全文 >>

elasticsearch用来干嘛的(elasticsearch有什么作用)

elasticsearch用来干嘛的(elasticsearch有什么作用)

Elasticsearch是什么elasticsearch是一款大数据场景下的分布式全文搜索、统计分析引擎elastic...

2022-11-04 04:20:15查看全文 >>

elasticsearch是免费的吗(elasticsearch在哪里下载)

elasticsearch是免费的吗(elasticsearch在哪里下载)

简介:本书基于【Elasticsearch生态&技术峰会Online】阿里巴巴集团副总裁、Elastic创始人&...

2022-11-04 04:16:12查看全文 >>

elasticsearch 可以干什么(elasticsearch是怎么存储的)

elasticsearch 可以干什么(elasticsearch是怎么存储的)

摘要先自上而下,后自底向上的介绍ElasticSearch的底层工作原理,试图回答以下问题:为什么我的搜索 *foo-b...

2022-11-04 04:40:27查看全文 >>

elasticsearch怎么读中文(elasticsearch快速入门)

elasticsearch怎么读中文(elasticsearch快速入门)

Elasticsearch是什么•Elasticsearch 是一个分布式的开源搜索和分析引擎。•适用于所有类型的数据,...

2022-11-04 04:58:03查看全文 >>

elasticsearch有什么用(elasticsearch快速入门)

elasticsearch有什么用(elasticsearch快速入门)

目录一、ElasticSearch是什么?二、ElasticSearch基本概念1. 全文搜索(Full-text Se...

2022-11-04 04:54:14查看全文 >>

elasticsearch用什么语言写的(elasticsearch什么语言好)

elasticsearch用什么语言写的(elasticsearch什么语言好)

本文演示了如何使用IK Analysis 插件来实现在 Elasticsearch 中的中文分词功能。使用中文分词在“S...

2022-11-04 04:39:29查看全文 >>

elasticsearch干嘛的(elasticsearch白名单)

elasticsearch干嘛的(elasticsearch白名单)

Elasticsearch,这个家伙我就不用过多介绍了吧,简称ES,这可不是js里面的es语法也不是阿里云里面的es云服...

2022-11-04 04:35:08查看全文 >>

文档排行