ElasticSearch教程——批量處理(mget和bulk)
阿新 • • 發佈:2019-02-02
批量查詢
優點:能夠大大減少網路的請求次數,縮減網路開銷。
(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語法
- delete:刪除一個文件,只要1個json串就可以了
- create:PUT /index/type/id/_create,強制建立
- index:普通的put操作,可以是建立文件,也可以是全量替換文件
- 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格式
目前處理流程
- 直接按照換行符切割json,不用將其轉換為json物件,不會出現記憶體中的相同資料的拷貝;
- 對每兩個一組的json,讀取meta,進行document路由;
- 直接將對應的json傳送到node上去;
換成良好json格式的處理流程
- 將json陣列解析為JSONArray物件,這個時候,整個資料,就會在記憶體中出現一份一模一樣的拷貝,一份資料是json文字,一份資料是JSONArray物件;
- 解析json數組裡的每個json,對每個請求中的document進行路由;
- 為路由到同一個shard上的多個請求,建立一個請求陣列;
- 將這個請求陣列序列化;
- 將序列化後的請求陣列傳送到對應的節點上去;
奇特格式的優缺點
缺點:可讀性差;
優點:不需要將json陣列解析為一個JSONArray物件,形成一份大資料的拷貝,浪費記憶體空間,能夠儘可能地保證效能;
例如:
bulk size最佳大小一般建議說在幾千條,大小在10MB左右。假設說現在100個bulk請求傳送到了一個節點上去,然後每個請求是10MB,100個請求,就是1000MB = 1GB,然後每個請求的json都copy一份為jsonarray物件,此時記憶體中的佔用就會翻倍,就會佔用2GB的記憶體,甚至還不止。因為弄成jsonarray之後,還可能會多搞一些其他的資料結構,2GB+的記憶體佔用。
佔用更多的記憶體可能就會積壓其他請求的記憶體使用量,比如說最重要的搜尋請求,分析請求,等等,此時就可能會導致其他請求的效能急速下降。
另外的話,佔用記憶體更多,就會導致java虛擬機器的垃圾回收次數更多,跟頻繁,每次要回收的垃圾物件更多,耗費的時間更多,導致es的java虛擬機器停止工作執行緒的時間更多。