33.bulk json格式的理解
bulk json格式的理解
一、常规格式
按常规理解,bulk中json格式可以是以下方式
[{
"action": {
},
"data": {
}
}]
这种方式对程序员友好,可读性好。但是如果写成这样的话,es拿到这种格式的json串以后,要按照下述流程去进行处理:
(1)将json数组解析为JSONArray对象,这个时候,整个数据,就会在内存中出现一份一模一样的拷贝,一份数据是json文本,一份数据是JSONArray对象。(主要问题就出在这里)
(2)解析json数组里的每个json,对每个请求中的document进行路由
(3)为路由到同一个shard上的多个请求,创建一个请求数组
(4)将这个请求数组序列化
(5)将序列化后的请求数组发送到对应的节点上去
由上述步骤分析可以看出,这种方式下会产生以下影响
耗费更多内存,更多的java虚拟机开销
举例如下:我们之前学好到过bulk size最佳大小的那个问题,一般建议说在几千条那样,然后大小在10MB左右。现在有100个bulk请求发送到了一个节点上去,然后每个请求是10MB,此时document占用内存大约是1GB,然后每个请求的json都copy一份为jsonarray对象,此时内存中的占用就会翻倍,就会占用2GB的内存,甚至更好。因为json数据在转换成jsonarray对象之后,还可能会有其他内存消耗。占用更多的内存可能就会挤压其他请求的内存使用量,比如说最重要的搜索请求、分析请求等等,此时就可能会导致其他请求的性能急速下降。另外,json数据在转换成jsonarray对象所产生的内存消耗均是临时内存消耗,这种情况下就会导致java虚拟机的垃圾回收次数更多,更频繁,每次要回收的垃圾对象更多,耗费的时间更多,导致es的java虚拟机停止工作线程的时间更多。
二、bulk规定的格式
{"action": {"meta"}}\n
{"data"}\n
这种格式下es处理的好处:
(1)不用将其转换为json对象,直接按照换行符切割json,不会出现内存中的相同数据的拷贝。
(2)对每两个一组的json,读取meta,进行document路由
(3)直接将对应的json发送到node上去
采用这种方式最大的优势在于,不需要将json数组解析为一个JSONArray对象,不用形成一份大数据的拷贝,浪费内存空间,尽可能地保证性能。