1、bulk api奇特的json格式
{"action":{"meta"}}\n
{"data"}\n
{"action":{"meta"}}\n
{"data"}\n
2、如果采用比较良好的json数组格式
[{
"action":{
"meta"
},
"data":{
}
}]
允许任意的换行,整个可读性非常的棒,es拿到这种标准格式的json串以后,要按照下述流程去进行处理
(1)将json数组解析成JSONArray对象,这个时候整个数据就会在内存中出现一份一模一样的拷贝,一份数据是json文本,一份数据是JSONArray对象
(2)解析json数组里的每个json,对每个请求中的document进行路由
(3)为路由到同一个shard上的多个请求,创建一个请求数组
(4)将这个请求数组序列化
(5)将序列化后的请求数组发送到对应的节点上
3、耗费更多的内存,更多的jvm gc开销
bulk size有最佳大小的问题,一般建议说在几千条,然后文件大小在10MB左右。假设说现在100个bulk请求发送到了一个节点上,然后每个请求10MB,100个请求就是1000MB=1GB,然后每个请求的json都copy一份为JSONArray对象,此时占用的内存就会翻倍,结果占用2GB的内存,甚至还不止,因为弄成JSONAray之后,还可能会多搞一些其他的数据结构,2GB+的内存占用。
占用更多的内存就会挤压其他请求的内存使用量,比如最重要的搜索请求,分析请求等等,此时就可能会导致其他请求的性能急速下降。另外,占用内存更多,就会导致java虚拟机的垃圾回收次数更多,更频繁,每次需要回收的垃圾对象更多,导致es的java虚拟机停止工作线程的时间更多。
4、现在的奇特格式
(1)不用将其转化为JSONArray对象,不会出现内存中的相同数据的拷贝,直接按照换行符切割json
(2)对每两个一组的json,读取meta,进行document路由
(3)直接将对应的json发送到node上
最大的优势是,不需要将json数组解析为一个JSONArray对象,形成一份大数据的拷贝,浪费内存空间,最终尽可能地保证性能。