06.delete_by_query操作
文章目錄
- 1. Delete By Query API簡介
- 2. URL參數
- 3. 響應體
- 4. 配合Task API使用
- 1. 配合取消任務API使用
- 5. 切片并行
- 1. 手動切片并行
- 2. 自動切片
- 3. 挑選slice的數量
1. Delete By Query API簡介
根據查詢API進行刪除
最簡單的用法是使用_delete_by_query對每個查詢匹配的文檔執行刪除。這是API:
該查詢必須以與Search API相同的方式作為query鍵的值傳遞。您也可以以與search api相同的方式使用q參數。
它將返回類似如下的一些東西:
{"took" : 147,"timed_out": false,"deleted": 119,"batches": 1,"version_conflicts": 0,"noops": 0,"retries": {"bulk": 0,"search": 0},"throttled_millis": 0,"requests_per_second": -1.0,"throttled_until_millis": 0,"total": 119,"failures" : [ ] }_delete_by_query在開始處理時時獲取索引的快照,并使用內部版本控制刪除它所查找到的內容。這意味著如果文檔在query和處理刪除之間發生變化,會報沖突錯誤。當版本匹配時文檔被刪除。
** 注意 **
由于內部版本控制不支持值0作為有效的版本號,因此無法使用_delete_by_query刪除版本等于零的文檔,并且將請求失敗。
在_delete_by_query執行期間,依次執行多個搜索請求,以便找到要刪除的所有匹配文檔。每次發現一批文檔時,執行相應的批量請求以刪除所有這些文檔。如果搜索或批量請求被拒絕,_delete_by_query依賴于默認策略來重試拒絕的請求(最多10次,以指數返回)。達到最大重試次數限制會導致_delete_by_query中止,并在響應失敗中返回所有故障。已經執行的刪除仍然保持。換句話說,進程沒有回滾,只會中止。當第一個故障導致中止時,失敗批量請求返回的所有故障都會返回到故障元素中;因此,有可能會有不少失敗的實體。
也就是說這不是一個事務操作,不會回滾。
如果您只想統計版本沖突,而不是導致它們中止,那么在URL上設置conflicts=proceed或在請求體重中設置"conflicts": “proceed”。
返回到API格式,您可以將_delete_by_query限制為單一類型。下面示例將只會從Twitter的索引中刪除tweet類型的文檔:
POST twitter/_delete_by_query?conflicts=proceed {"query": {"match_all": {}} }也可以一次刪除多個索引文件和多個類型,就像搜索API:
POST twitter,blog/_delete_by_query {"query": {"match_all": {}} }如果您提供routing,則將路由復制到滾動查詢,將過程限制為與該路由值匹配的分片:
POST twitter/_delete_by_query?routing=1 {"query": {"range" : {"age" : {"gte" : 10}}} }默認情況下_delete_by_query使用滾動批量處理數量為1000。您可以使用URL的scroll_size參數更改批量大小:
POST twitter/_delete_by_query?scroll_size=5000 {"query": {"term": {"user": "kimchy"}} }2. URL參數
除了標準參數像pretty之外,“Delete By Query API”還支持refresh、wait_for_completion、wait_for_active_shards、timeout以及requests_per_second。
發送refresh將在一旦根據查詢刪除完成之后, 刷新所有涉及到的分片。這與delete API的refresh參數不同,delete API只會refresh收到delete請求的shard。
如果請求包含wait_for_completion=false,那么Elasticsearch將執行一些預檢檢查、啟動請求、然后返回一個任務,可以與Tasks API一起使用來取消或獲取任務的狀態。Elasticsearch還將以.tasks/task/${taskId}作為文檔創建此任務的記錄。這是你可以根據是否合適來保留或刪除它。當你完成它時,刪除它可以讓Elasticsearch回收它使用的空間。
wait_for_active_shards控制在繼續請求之前必須有多少個分片必須處于活動狀態,詳見這里。timeout控制每個寫入請求等待不可用分片變成可用的時間。兩者都能正確地在Bulk API中工作。
requests_per_second可以設置為任何正數(1.4,6,1000等),來作為“delete-by-query”每秒請求數的節流閥數字,或者將其設置為-1以禁用限制。節流是在批量批次之間等待,以便它可以操縱滾動超時。等待時間是批次完成的時間與request_per_second * requests_in_the_batch的時間之間的差異。由于分批處理沒有被分解成多個批量請求,所以會導致Elasticsearch創建許多請求,然后等待一段時間再開始下一組。這是“突發”而不是“平滑”。默認值為-1。在集群本省的任務比較重的情況下建議開啟限流,以減少對集群資源的使用。
throttle的計算方式是,每秒處理requests_per_second 個request,假如我們設置requests_per_second=500,寫1000個需要0.5s,則等待時間是
target_time = 1000 / 500 per second = 2 seconds wait_time = target_time - write_time = 2 seconds - .5 seconds = 1.5 seconds默認沒有限流
3. 響應體
JSON響應類似如下:
{"took" : 147,"timed_out": false,"total": 119,"deleted": 119,"batches": 1,"version_conflicts": 0,"noops": 0,"retries": {"bulk": 0,"search": 0},"throttled_millis": 0,"requests_per_second": -1.0,"throttled_until_millis": 0,"failures" : [ ] }took: 從整個操作的開始到結束的毫秒數。
timed_out: delete by query的請求處理過程中是否超時
total: 成功處理的doc數量
deleted: 成功刪除的文檔數。
batches: 通過查詢刪除的scroll響應數量。
version_conflicts: 根據查詢刪除時,版本沖突的數量。
noops: 這個在這里沒有用,只是為了讓delete by query, update by query, and reindex APIs 返回相同結構的 responses
retries: search 操作和bulk操作的重試次數
throttled_millis: 因為requests_per_second而產生的睡眠時間
requests_per_second: 每秒處理的請求數
throttled_until_millis: 這個也是總是0,沒有用,為了保持結構一致性
failures: 失敗的情況,會終止操作的失敗
失敗的索引數組。如果這是非空的,那么請求因為這些失敗而中止。請參閱 conflicts 來如何防止版本沖突中止操作。
4. 配合Task API使用
您可以使用Task API獲取任何正在運行的根據查詢刪除請求的狀態:
GET _tasks?detailed=true&actions=*/delete/byquery響應會類似如下:
{"nodes" : {"r1A2WoRbTwKZ516z6NEs5A" : {"name" : "r1A2WoR","transport_address" : "127.0.0.1:9300","host" : "127.0.0.1","ip" : "127.0.0.1:9300","attributes" : {"testattr" : "test","portsfile" : "true"},"tasks" : {"r1A2WoRbTwKZ516z6NEs5A:36619" : {"node" : "r1A2WoRbTwKZ516z6NEs5A","id" : 36619,"type" : "transport","action" : "indices:data/write/delete/byquery","status" : { //①"total" : 6154,"updated" : 0,"created" : 0,"deleted" : 3500,"batches" : 36,"version_conflicts" : 0,"noops" : 0,"retries": 0,"throttled_millis": 0},"description" : ""}}}} }① 此對象包含實際狀態。它就像是響應json,重要的添加total字段。 total是重建索引希望執行的操作總數。您可以通過添加的updated、created和deleted的字段來估計進度。當它們的總和等于total字段時,請求將完成。
使用任務id可以直接查找任務:
GET /_tasks/r1A2WoRbTwKZ516z6NEs5A:36619這個API的優點是它與wait_for_completion=false集成,以透明地返回已完成任務的狀態。如果任務完成并且wait_for_completion=false被設置,那么它將返回results或error字段。此功能的成本是wait_for_completion=false在.tasks索引創建taskId的文檔,需要你自己刪除該doc。
1. 配合取消任務API使用
所有根據查詢刪除都能使用Task Cancel API取消:
POST _tasks/task_id:1/_cancel可以使用上面的任務API找到task_id。 取消應盡快發生,但可能需要幾秒鐘。上面的任務狀態API將繼續列出任務,直到它被喚醒取消自身。
重置節流閥
request_per_second的值可以在通過查詢刪除時使用_rethrottle API更改:
可以使用上面的任務API找到task_id。
就像在_delete_by_query API中設置它一樣,request_per_second可以是-1來禁用限制,或者任何十進制數字,如1.7或12,以節制到該級別。加速查詢的會立即生效,但是在完成當前批處理之后,減慢查詢的才會生效。這樣可以防止滾動超時。
5. 切片并行
1. 手動切片并行
Delete by query支持滾動切片,您可以相對輕松地手動并行化處理:
POST twitter/_delete_by_query {"slice": {"id": 0,"max": 2},"query": {"range": {"likes": {"lt": 10}}} }POST twitter/_delete_by_query {"slice": {"id": 1,"max": 2},"query": {"range": {"likes": {"lt": 10}}} }上面兩個請求的max要保持一致,代表了總共有2個并行的任務,一個id為0,一個id為1。
您可以通過以下方式驗證:
GET _refresh POST twitter/_search?size=0&filter_path=hits.total {"query": {"range": {"likes": {"lt": 10}}} }其結果一個合理的total像這樣:
{"hits": {"total" : {"value": 0,"relation": "eq"}} }2. 自動切片
你還可以讓根據查詢刪除使用切片的_uid來自動并行的滾動切片。
POST twitter/_delete_by_query?refresh&slices=5 {"query": {"range": {"likes": {"lt": 10}}} }上面的會自動分成5個任務來執行
您可以通過以下方式驗證:
POST twitter/_search?size=0&filter_path=hits.total {"query": {"range": {"likes": {"lt": 10}}} }其結果一個合理的total像這樣:
{"hits": {"total" : {"value": 0,"relation": "eq"}} }將切片設置為自動將使Elasticsearch選擇要使用的切片數。此設置將每個分片使用一個slice,上限為一定限制。如果有多個源index,它將根據分片數量最少的索引選擇slice。
在_delete_by_query使用slice只會自動執行上一節中使用的手動過程,從而創建子請求,這意味著它具有一些怪癖:
3. 挑選slice的數量
在這一點上,我們圍繞要使用的slices數量提供了一些建議(比如手動并行化時,切片API中的max參數):
不要使用大的數字,500就能造成相當大的CPU抖動。
在源索引中使用完全相同的分片是從查詢性能的角度來看效率最高的。
索引性能應在可用資源之間以slices數量線性擴展。
索引或查詢性能是否支配該流程取決于許多因素,如正在重建索引的文檔和進行reindexing的集群。
總結
以上是生活随笔為你收集整理的06.delete_by_query操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 05.doc_delete操作
- 下一篇: 08.update_by_query操作