elasticsearch源码分析之服务端(四)

来源:互联网 发布:期货网络销售好做吗 编辑:程序博客网 时间:2024/06/05 05:51
上篇博客说明了客户端的情况,现在继续分析服务端都干了些啥,es是怎么把数据插进去的,此处以transport的bulk为入口来探究,对于单个document的发送就忽略了。

一、服务端接收

1.1接收消息

在客户端分析中已经提到,netty中通信的处理类是MessageChannelHandler,其中messageReceived方法用来处理消息。

1.1.1解析数据流


1.1.2调用handleRequest,此处读取出来action,跟不同的action生成具体的TransportRequest子类和不同的HandledTransportAction。


其中生成reg和request解析如下:


最终执行到了TransportBulkAction类的doExecute方法,处理bulkRequest。

1.2主要类UML图


server端接收message,解析协议,根据action生成不同request和transportAction,进而执行transportAction.execute(request,listener)。

此处的结构会有很多具体的TransportAction类实现了HandeldTransportAction,实现了不同的响应接口。

二、服务端处理


2.1索引的处理


2.1.1索引分类处理

根据上面的分析,bulk的处理执行到TransportBulkAction类的doExecute(),代码如下:


此处会分析bulkRequest中的所有请求中的index和type,生成 Map<String, Set<String>> indicesAndTypes,然后遍历indicesAndTypes,分index执行不同的bulk。

2.1.2生成_id

遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话)、指定的timestamp(如果没有带timestamp会使用当前时间),如果没有指定id字段,在action.bulk.action.allow_id_generation配置为true的情况下,会自动生成一个base64UUID作为id字段。

2.1.3生成shardid

再次遍历所有的request,获取获取每个request应该发送到的shardId,获取的过程是这样的:request有routing(上面获取到的)就直接返回,如果没有,会先对id求一个hash


 

分片算法如下:


hash函数默认使用的是Murmur3,也可以通过配置index.legacy.routing.hash.type来决定使用的hash函数。

其实上面就是要对request按shard来分组,进而进行分片处理。

2.1.4分片处理requst

遍历,对不同的分组创建一个bulkShardRequest,包含配置consistencyLevel和timeout。执行BrokerTransportShardBulkAction.execute(bulkShardRequest,listener),

创建一个brokerPhase线程,并执行。

brokerPhase首先解析处理分片主节点,然后请求主节点上执行。



此时请求会转发到node节点。

2.2写入primary

2.2.1PrimaryPhase

请求转发到node节点的主节点的TransportReplicationAction.execute(),创建一个PrimaryPhase线程,并执行。调用routeRequestOrPerformLocally方法,调用performOnPrimary方法



其中第一个红框表示主分片上执行索引操作,第二个红框生成ReplicationPhase线程,供后期完成执行副本任务,副本任务暂不分析。

2.2.2生成document

在shardOperationOnPrimary-->shardIndexOperation-->executeIndexRequestOnPrimary中有
prepareIndexOperationOnPrimary方法,其中生成了doc


TransportReplicationAction类


IndexShard类


2.2.3生成索引

在shardOperationOnPrimary-->shardIndexOperation-->executeIndexRequestOnPrimary-->Engine.execute()-->indexWriter.add/updateDocument


至此,索引数据写入完成,但是只是将数据写入了buffer和translog里面。后面还有refresh和flush,保证数据可查和安全性。

数据doc的格式如下:


2.3refresh

2.4flush

1 0