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