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