1. 程式人生 > >ElasticSearch教程——批量處理(mget和bulk)

ElasticSearch教程——批量處理(mget和bulk)

批量查詢

優點:能夠大大減少網路的請求次數,縮減網路開銷。

(1)自定義設定index、type以及document id

GET /_mget
{
   "docs" : [
      {
         "_index" : "ecommerce",
         "_type" :  "product",
         "_id" :    1
      },
      {
         "_index" : "ecommerce",
         "_type" :  "product",
         "_id" :    2
      }
   ]
}

返回結果如下

id為1的沒有查到(found為false)

{
  "docs": [
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "1",
      "found": false
    },
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "2",
      "_version": 2,
      "found": true,
      "_source": {
        "name": "jiajieshi yagao",
        "desc": "youxiao fangzhu",
        "price": 25,
        "producer": "jiajieshi producer",
        "tags": [
          "fangzhu"
        ]
      }
    }
  ]
}

(2)在對應的index、type下進行批量查詢

注意:在ElasticSearch6.0以後一個index下只能有一個type,否則會報錯

GET /ecommerce/product/_mget
{
    "ids": [2, 3]
}

或者

GET /ecommerce/product/_mget
{
   "docs" : [
      {
         "_id" :    2
      },
      {
         "_id" :    3
      }
   ]
}

返回結果

{
  "docs": [
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "2",
      "_version": 2,
      "found": true,
      "_source": {
        "name": "jiajieshi yagao",
        "desc": "youxiao fangzhu",
        "price": 25,
        "producer": "jiajieshi producer",
        "tags": [
          "fangzhu"
        ]
      }
    },
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "3",
      "_version": 1,
      "found": true,
      "_source": {
        "name": "zhonghua yagao",
        "desc": "caoben zhiwu",
        "price": 40,
        "producer": "zhonghua producer",
        "tags": [
          "qingxin"
        ]
      }
    }
  ]
}

基於bulk的增刪改

bulk語法

  1. delete:刪除一個文件,只要1個json串就可以了
  2. create:PUT /index/type/id/_create,強制建立
  3. index:普通的put操作,可以是建立文件,也可以是全量替換文件
  4. update:執行的partial update操作

注意點

1.bulk api對json的語法有嚴格的要求,除了delete外,每一個操作都要兩個json串,且每個json串內不能換行,非同一個json串必須換行,否則會報錯;

2.bulk操作中,任意一個操作失敗,是不會影響其他的操作的,但是在返回結果裡,會告訴你異常日誌;

建立文件index

未指定id時,系統會自動建立id

POST /_bulk
{ "index": { "_index": "ecommerce", "_type":"product"}}
{ "name": "test yagao", "desc": "youxiao fangzhu"}

返回結果

{
  "took": 19,
  "errors": false,
  "items": [
    {
      "index": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "KXfSFWYBBoLynJN1TUPo",
        "_version": 1,
        "result": "created",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 9,
        "_primary_term": 2,
        "status": 201
      }
    }
  ]
}

強制建立文件create

POST /_bulk
{ "create": { "_index": "ecommerce", "_type": "product", "_id": "4" }}
{ "test_field":    "test12" }

返回結果

{
  "took": 88,
  "errors": false,
  "items": [
    {
      "create": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_version": 1,
        "result": "created",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 6,
        "_primary_term": 2,
        "status": 201
      }
    }
  ]
}

修改文件update

POST /_bulk
{ "update": { "_index": "ecommerce", "_type": "product", "_id": "4","retry_on_conflict" : 3 }}
{ "doc" : {"test_field" : "test update"} }

返回結果

{
  "took": 1,
  "errors": false,
  "items": [
    {
      "update": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_version": 2,
        "result": "noop",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "status": 200
      }
    }
  ]
}

刪除文件delete

POST /_bulk
{ "delete": { "_index": "ecommerce", "_type": "product", "_id": "4"}} 

返回結果

{
  "took": 12,
  "errors": false,
  "items": [
    {
      "delete": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_version": 3,
        "result": "deleted",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 8,
        "_primary_term": 2,
        "status": 200
      }
    }
  ]
}

bulk api奇特的json格式

目前處理流程

  1. 直接按照換行符切割json,不用將其轉換為json物件,不會出現記憶體中的相同資料的拷貝;
  2. 對每兩個一組的json,讀取meta,進行document路由;
  3. 直接將對應的json傳送到node上去;

換成良好json格式的處理流程

  1. 將json陣列解析為JSONArray物件,這個時候,整個資料,就會在記憶體中出現一份一模一樣的拷貝,一份資料是json文字,一份資料是JSONArray物件;
  2. 解析json數組裡的每個json,對每個請求中的document進行路由;
  3. 為路由到同一個shard上的多個請求,建立一個請求陣列;
  4. 將這個請求陣列序列化;
  5. 將序列化後的請求陣列傳送到對應的節點上去;

奇特格式的優缺點

缺點:可讀性差;

優點:不需要將json陣列解析為一個JSONArray物件,形成一份大資料的拷貝,浪費記憶體空間,能夠儘可能地保證效能;

例如:

bulk size最佳大小一般建議說在幾千條,大小在10MB左右。假設說現在100個bulk請求傳送到了一個節點上去,然後每個請求是10MB,100個請求,就是1000MB = 1GB,然後每個請求的json都copy一份為jsonarray物件,此時記憶體中的佔用就會翻倍,就會佔用2GB的記憶體,甚至還不止。因為弄成jsonarray之後,還可能會多搞一些其他的資料結構,2GB+的記憶體佔用。

佔用更多的記憶體可能就會積壓其他請求的記憶體使用量,比如說最重要的搜尋請求,分析請求,等等,此時就可能會導致其他請求的效能急速下降。
另外的話,佔用記憶體更多,就會導致java虛擬機器的垃圾回收次數更多,跟頻繁,每次要回收的垃圾物件更多,耗費的時間更多,導致es的java虛擬機器停止工作執行緒的時間更多。