elasticsearch 查询过程

 

背景
学习elasticsearch查询流程,了解es源码。在网络上看了很多elasticsearch的教程。对es的流程介绍都是停留在query then fetch层面。没有一篇真正细致的深入到流程的每一步。本篇博客旨在细致的介绍es search过程的整个调试流程,介绍的是query then fetch的流程。所以,默认对es有一定理解,且能搭建一个本地的调试环境。
请带着以下问题去读本篇文章。

elasticsearch client是如果发送请求的,又是如何接受和处理返回的结果?
协调节点的接收到client请求后的处理流程是怎样的?
协调节点怎么收集合并数据,分数处理?
数据节点接收到查询请求的处理过程?
数据节点接受到fetch请求的处理过程?
search过程中涉及到的请求有哪些?
这些问题会在文章最后解答。
查询过程
首先从整体架构上介绍整个查询流程。
我们知道,es的查询分为query then fetch和dfs query then fetch两种,而本文介绍的是前者。es的底层结构是倒排索引,这个查询的过程,query就是先根据查询获取具体的数据的id。fetch就是根据query过程的获取的id拿出具体的数据。整个流程涉及到了三个实体,客户端(client),协调节点(Coordinator),数据节点(DataNode)。三者的具体关系看下图,这个流程在网上也有很多的文章介绍。


接下来会结合源码分析上图中的每个流程。

客户端发送请求流程
话不多数,还是先上个图。
这个图描述了client的调用过程。在TransportClientNodesService过程中,是属于client模块服务层。后面这部分处理属于公共的网络层。
我再调试这个过程中比较在意的数据怎么回来的?所以这个流程中比较在意的几个类是:
AbstractClient类,截个图:


在execute()函数中实现了一个返回结果的类,这个类实现了ActionListener。在结果返回后回调listener中的onResponse函数。我们点进去看这个函数具体实现。

具体还的看set函数:


看完上面这些其实还是存在疑惑,就是这个ActionListener在哪里给调用了?我们接着往下看。在后续的流程中,ActionListener给封装了几次,这个过程大家调试过程中看一下,这里就不介绍了。
最后来到TransportService的sendRequestInternal()函数。


比较重要的地方写了说明。
接下来就是结果返回了。对于tcp请求,结果返回是在TcpTransport中的messageReceived函数做分发处理。这里可能很多人不理解,怎么突然到这步。上面一步请求通过netty4发送请求后,client处于等待状态,当server处理往数据后,又通过netty4发送到client,而client的接收通过Netty4MessageChannelHandler->TcpTransport。最后在TcpTransport中的messageReceived函数做分发处理。

 

messageReceived函数主要看一下这段代码。里面重要的几个地方,1.调用handleRequest,这个其实是server端,当别人请求过来时,调用这个函数。2.transportServiceAdapter.onResponseReceived,这个就是我之前说的通过requestId从clientHandler中获取具体的回调ActionListener处理。3.handleResponse,处理返回结果,通过handler。
到此,整个的client调用过程就结束。

节点接受请求流程
习惯性先上图哈。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uX5EHMB-1600004146979)(evernotecid://CD8D29A3-4674-4DAF-91D6-5E8332FBECE8/appyinxiangcom/12451481/ENResource/p325)]
上面其实我们已经提到了,走tcp过来的请求,都是到TcpTransport中的messageReceived处理。这里详细点介绍请求过来的分发和处理情况。messageReceived在前面已经说过了。往下介绍handlerequest()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mf02CGd8-1600004146979)(evernotecid://CD8D29A3-4674-4DAF-91D6-5E8332FBECE8/appyinxiangcom/12451481/ENResource/p326)]
这里最主要还是transportServiceAdapter.getRequestHandler()这个函数,通过action获取具体的处理器。
最后启动一个单独的线程处理这个请求。
接着我们往里面这个多线程去看,执行的是TransportHandler的messageReceived()函数,这个函数实现了一个回调类ActionListener,当结果完成后就会通过channel发送结果给客户端。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pJl3PJcg-1600004146980)(evernotecid://CD8D29A3-4674-4DAF-91D6-5E8332FBECE8/appyinxiangcom/12451481/ENResource/p327)]
在往里走,就是TransportSearchAction,这里面实现了一个rewriteListener类,这个类里面调用了executeSearch()函数,从这个函数开始,我将它分为下一个流程,协调节点调用查询请求流程。
这里还有个问题,这个rewriteListener在哪里给调用了。跟着图走。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-khrmJufi-1600004146980)(evernotecid://CD8D29A3-4674-4DAF-91D6-5E8332FBECE8/appyinxiangcom/12451481/ENResource/p328)]
在rewriteAndFetch里面执行了onResponse()函数。
到此,节点接受请求流程完毕。

协调节点发送query请求流程
协调节点发送fetch请求流程
数据节点处理query请求流程
数据节点处理fetch请求流程
————————————————
版权声明:本文为CSDN博主「叶ycc」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ycccsdn/article/details/108568721

posted @ 2021-09-13 11:46  进阶的马龙  阅读(678)  评论(0编辑  收藏  举报