elasticsearch學習筆記(二十)——Elasticsearch bulk api的奇特json格式與底層性能優化關係

bulk api奇特的json格式

{"action": {"meta"}}n
{"data"}n
{"action": {"meta"}}n
{"data"}n
...java

爲何bulk要採用這種奇特的json格式?

因爲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
      }
    }
  ]
}
相關文章
相關標籤/搜索