{"action": {"meta"}}n
{"data"}n
{"action": {"meta"}}n
{"data"}n
...java
因为bulk中的每一个操做均可能要转发到不一样的node的shard去执行,假设咱们不用这种奇特的json格式,采用比较良好的json数组格式,容许任意的换行,整个可读性很是棒,读起来很爽。可是ES拿到这种标准格式的json串以后,要按照下述流程去进行执行处理。
格式以下:
[
{node
"action": { }, "data": { }
}
]
(1)将json数组解析为JSONArray对象,这个时候,整个数据,就会在内存中出现一份一摸同样的拷贝,一份数据是json文本,一份数据是JSONArray对象
(2)解析json数组里面的每一个json,对每一个请求中的document进行路由
(3)为路由到同一个shard上的多个请求,建立一个请求数组
(4)将这个请求数组序列化
(5)将序列化后的请求数组发送到对应的节点上去
不难看出这样就会耗费更多的内存,更多的jvm gc开销。json
假设一个场景,对于bulk size的大小通常建议在几千条,大小在10MB左右,因此说,可怕的事情来了。假设说如今100个bulk请求发送到了一个节点上去,而后每一个请求是10MB,100个请求就是1000MB=1G,而后每一个请求的json都copy一份JSONArray对象,此时内存中的占用就会翻倍,就会占用2GB的内存,甚至还不止,由于弄成JSONArray对象以后,还可能会多弄一些其它的数据结构,2GB+的内存占用。
占用更多的内存可能就会积压其它请求的内存使用量,好比说最重要的搜索请求,分析请求等等。此时就可能会致使其它请求的性能急速降低,另外的话,占用内存更多,就会致使java虚拟机的垃圾回收次数更多,更加频繁,每次要回收的垃圾对象更多,耗费的时间更多,致使ES的java虚拟机中止工做线程的时间更多。api
而使用这个奇特格式的json
{"action": {"meta"}}n
{"data"}n
{"action": {"meta"}}n
{"data"}n
...
(1)不用将其转换为json对象,不会出现内存中的相同数据的拷贝,直接按照换行符切割json
(2)对每两个一组的json,读取meta,进行document路由
(3)直接将对应的json发送到node上去
和标准格式的json相比,最大的优点在于不须要将json数组解析为一个JSONArray对象,造成一份大数据的拷贝,浪费内存空间,尽量的保证性能。数组
实战:数据结构
PUT _bulk {"index": {"_index": "test", "_id": "1"}} {"field1": "value1", "field2": "value2"} {"index": {"_index": "test", "_id": "2"}} {"field1": "value1 id2", "field2": "value2 id2"} {"delete": {"_index": "test", "_id": "2"}} {"create": {"_index": "test", "_id": "3"}} {"field1": "value3"} {"update": {"_index": "test", "_id": "1"}} {"doc": {"field2": "value2"}} { "took" : 68, "errors" : true, "items" : [ { "index" : { "_index" : "test", "_type" : "_doc", "_id" : "1", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 4, "_primary_term" : 1, "status" : 200 } }, { "index" : { "_index" : "test", "_type" : "_doc", "_id" : "2", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 5, "_primary_term" : 1, "status" : 201 } }, { "delete" : { "_index" : "test", "_type" : "_doc", "_id" : "2", "_version" : 2, "result" : "deleted", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 6, "_primary_term" : 1, "status" : 200 } }, { "create" : { "_index" : "test", "_type" : "_doc", "_id" : "3", "status" : 409, "error" : { "type" : "version_conflict_engine_exception", "reason" : "[3]: version conflict, document already exists (current version [1])", "index_uuid" : "rOLJZzIVTDCWtDQcJuei6w", "shard" : "0", "index" : "test" } } }, { "update" : { "_index" : "test", "_type" : "_doc", "_id" : "1", "_version" : 2, "result" : "noop", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "status" : 200 } } ] }