背景
- Bulk请求是ES常用的一种multi-document请求,其处理比较复杂,之前一直搞不清请求的处理逻辑,今天就从源码入手,仔细剖析一下其执行逻辑。
时序分析
- 简单而言,Bulk的时序如下图所示,Http节点只将包转为TCP,ingest节点进行些预设的前置处理,然后按shard拆分,再把按shard拆开的bulk再发到真实的data节点上,最后由data节点进行主副本同步写入。
具体流程
-
RestControllor
接收请求,dispatch到对应的handler上
-
BaseRestHandler
调用 RestBulkAction
进行前置处理,请求转为 BulkRequest
-
NodeClient
根据 ActionModule
注册的映射关系,找到TransportBulkAction
作为tcp的处理逻辑
-
TransportBulkAction
检查自己是不是 ingest node
,如果不是就转发
-
Ingest Node
接收到请求,执行pipeline
-
TransportBulkAction
调用BulkOperation
将BulkRequest
拆为BulkShardRequest
,转发到DataNode
-
Primary Data Node
收到请求,转为ReplicationOperation
操作,调用TransportShardBulkAction
进行主副本的依次执行
-
TransportShardBulkAction
的具体执行过程为shardOperationOnPrimary
和shardOperationOnReplica
,执行时直接调用了Engine进行执行。具体代码就不贴了,比较长
线程池分析
- 在日常中,我们经常遇到由于线程池占满的
es_rejected_execution_exception
- 通过源码可以看到,bulk的线程池为
ThreadPool.Names.BULK
,全局查找后发现只有TransportShardBulkAction
和PipelineExecutionService
有用。
- Rest和TransportBulk居然没有用Bulk线程池,很是惊讶。不知道是不是没找到。。。
让搜索更简单
- ZSearch2.0 服务申请入口:http://search.alipay.com/看我们这二级的域名就知道重要性了吧。
- 蚂蚁中间件的ZSearch2.0,核心采用了ElasticSearch,原生支持所有的ElasticSearch的操作,具备强大的数据检索和分析能力,自5月份投入试运行以来,已线上服务16个业务方,数据规模在130TB,近2K亿的文档数,QPS稳定在30W左右。 通过数月不断的观察、调优、测试,如今已达到正式上线的标准,欢迎同学们踊跃使用,提出宝贵意见。
- 后续我们会对Elasticsearch和Lucene做持续优化,欢迎大家来使用,并提出你的需求。
- 有任何问题可以联系我们(@善仁(xinyu.jxy),@丰坚(yinghao.wyh),@十倍(lvliang.ll),@城破(huabiao.mahb) )
- 详细介绍请参阅ZSearch2.0 夏日来袭