ElasticSearch的bulk操作性能高的原理

ElasticSearch中提供了用于批量操作的bulk API,可参考:ES的bulk操作,这种api使用时可以通过一次请求操作批量完成多个增删改的操作,性能比较高。为什么批量操作性能这么高呢?这就离不开其底层的请求数据格式,下面将介绍ES中bulk操作的请求数据的优化原理。

温馨提示:本博客已经发布小程序,可在微信小程序中搜索”百变码农”,手机上也能看!

1、bulk操作的整个过程

(1)客户单发送一个bulk请求,可能同时有多个写操作,此时将这个请求发送到集群中的某个协调节点(coordinate node)上;

(2)协调节点收到请求之后,首先解析批量操作的请求报文,然后将每个操作路由到指定的节点上;

(3)等所有节点上的操作全部完成之后,给协调节点反馈操作结果,然后协调节点收到反馈之后,将结果汇总再返回给客户端;

2、批量操作的请求报文

(1)bulk操作的请求报文通常是成对出现的json字符串,每个字符串使用换行符分隔,例如:

{"action": {"meta_data"}} \n   // 成对出现,没对之间用换行符分隔
{"data"}\n
...

(2)如果使用普通的json数组,例如下述的请求报文,可读性非常好,整个请求过程是什么样的呢?

[{
   "action": {"meta_data"},
   "data": {}
},{
   "action": {"meta_data"},
   "data":{}
}]

① 首先协调节点收到该请求之后,需要先对该json字符串进行序列化,将其序列化为JSONArray,这个过程中,会拷贝到一份数据到内存中,内存中就会同时存在一份json文本数据和一份json对象数据;

② 解析出JSONArray中的每个json对象,然后构造请求报文,并使用路由算法将请求路由到其他节点上;

(3)使用bulk api要求的换行格式过程是怎样的呢?

① 协调节点收到bulk请求之后,直接按照换行符两两分隔,即得到多个bulk请求,不需要将大的请求报文先解析一份到内存中;

② 读取metadata,并路由到其他节点上;

(4)对比为何bulk这种换行符的性能高?

① 如果按照格式化之后的JSONArray发送bulk请求,协调节点需要将请求报文多余解析一份放到内存,而bulk操作的最佳bulk size大小大概为10M左右,如果多个bulk请求,将会特别耗费ES节点的内存,而是用bulk要求的请求格式,不需要进行大的请求报文拷贝,节约了大量的内存;

② 占用内存特别大,就会导致其他正常请求的内存使用量不够,从而可能会导致ES节点jvm频繁GC,影响其他查询操作的性能。

至此,ElasticSearch的bulk操作api为何要求特定的请求报文格式介绍完毕,欢迎转发!

注意:文章属于原创,如果转发请标注文章来源:个人小站【www.jinnianshizhunian.vip

另外提供一些优秀的Java架构师及IT开发视频,书籍资料。无需注册,无需登录即可下载,免费下载地址:https://www.592xuexi.com