之前我们有讲过bulk的json格式很奇葩,不能换行,两行为一组(除删除外),如下:
{"action" : {"meta"}}
{"data"}
而不是
[
{
"action" : {},
"data" : {}
}
]
1、bulk中的每个操作都可能要转发到不同的node的shard去执行
2、如果采用比较良好的json数组格式
首先,整个可读性非常棒,读起来很爽,ES拿到那种标准格式的JSON串以后,要按照下述流程去进行处理
(1)将JSON数组解析为JSONArray对象,这个时候,整个数据,就会在内存中出现一份一模一样的拷贝,一份数据是JSON文本,一份数据是JSONArray对象。
(2)解析JSON数组里的每个JSON,对每个请求中的document进行路由
(3)为路由到同一个shard上的多个请求,创建一个请求数组。
(4)将这个请求数组序列化
(5)将序列化后的请求数组发送到对应的节点上去
3、现在这种丑陋两行格式的JSON
{"action" : {"meta"}} \n
{"data"} \n
{"action" : {"meta"}} \n
{"data"} \n
(1)不用将其转换为JSON对象,不会出现内存中的相同数据的拷贝,直接按照换行符切割JSON
(2)对每两个一组的json,读取meta,进行document路由
(3)直接将对应的json发送到node上去
4、两种格式对比,为什么ES选择丑陋的格式?
(1)优雅格式:
耗费更多的内存,更多的JVM GC开销
我们之前提到过 bulk size最佳大小的问题,一般建议说在几千条那样,然后大小在10MB左右,所以说,可怕的事情来了,假设说现在100个bulk请求发送到了一个节点上去,然后每个请求是10MB,100个请求就是1000MB=1GB。然后每个请求的json都copy一份为JSONArray对象,此时内存中的占用就会翻倍,就会占用2GB内存,甚至还不止,因为弄成JSONArray后,还可能会多搞一些其他的数据结构,2GB+的内存占用。
占用更多的内存可能就会积压其他请求的内存使用量,比如说最重要的搜索请求,分析请求,等等,此时就可能会导致其他请求的性能急速下降
另外的话,占用内存更多,就会导致ES的java虚拟机的垃圾回收次数更多,更频繁,每次要回收的垃圾对象更多,耗费的时间更多,导致ES的java虚拟机停止工作线程的时间更多。
(2)丑陋的JSON格式:
最大的优势在于,不需要将JSON数组解析为一个JSONArray对象,形成一份大数据的拷贝,浪费内存空间,尽可能的保证性能。
若有兴趣,欢迎来加入群,【Java初学者学习交流群】:458430385,此群有Java开发人员、UI设计人员和前端工程师。有问必答,共同探讨学习,一起进步!
欢迎关注我的微信公众号【Java码农社区】,会定时推送各种干货:

网友评论
即非丑陋的这步骤
(3)为路由到同一个shard上的多个请求,创建一个请求数组。