{"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 } } ] }