環境
虛拟機:centos7
作業系統:win7
elasticsearch:5.5
Delete By Query API
_delete_by_query 的簡單用法,就是在查詢比對到的每個文檔上執行删除。例如:
POST twitter/_delete_by_query
{
"query": { ①
"match": {
"message": "some message"
}
}
}
①:查詢必須是有效的鍵值對,
query
是鍵,這和
Search API
是同樣的方式。在
search api
中
q
參數和上面效果是一樣的。
結果:
{
"took" : ,
"timed_out": false,
"deleted": ,
"batches": ,
"version_conflicts": ,
"noops": ,
"retries": {
"bulk": ,
"search":
},
"throttled_millis": ,
"requests_per_second": -,
"throttled_until_millis": ,
"total": ,
"failures" : [ ]
}
當啟動時(開始要删除時),
_delete_by_query
會得到索引(資料庫)的快照并且使用内部版本号來找到要删除哪些文檔。這意味着,如果擷取到快照與執行删除過程的這段時間,有文檔發生改變,那麼版本就會沖突。通過版本控制比對到的文檔會被删除。
注意:
因為 internal
版本控制不支援0為有效數字,是以版本号為0的文檔不能删除,并且請求将會失敗。
在執行
_delete_by_query
期間,為了删除比對到的所有文檔,多個搜尋請求是按順序執行的。每次找到一批文檔時,将會執行相應的批處理請求來删除找到的全部文檔。如果搜尋或者批處理請求被拒絕,
_delete_by_query
根據預設政策對被拒絕的請求進行重試(最多10次)。達到最大重試次數後,會造成
_delete_by_query
請求中止,并且會在
failures
字段中響應 所有的故障。已經删除的仍會執行。換句話說,該過程沒有復原,隻有中斷。
在第一個請求失敗引起中斷,失敗的批處理請求的所有故障資訊都會記錄在
failures
元素中;并傳回回去。是以,會有不少失敗的請求。
如果你想計算有多少個版本沖突,而不是中止,可以在
URL
中設定為
conflicts=proceed
或者在請求體中設定
"conflicts": "proceed"
。
回到
api
格式中,你可以在一個單一的類型(即:表)中限制
_delete_by_query
。
下面僅僅隻是删除索引(即:資料庫)
twitter
中類型(即:表)
tweet
的所有資料:
POST twitter/tweet/_delete_by_query?conflicts=proceed
{
"query": {
"match_all": {}
}
}
一次删除多個索引(即:資料庫)中的多個類型(即表)中的資料,也是可以的。例如:
POST twitter,blog/tweet,post/_delete_by_query
{
"query": {
"match_all": {}
}
}
如果你提供了
routing
,接着這個路由會被複制給
scroll query
,根據比對到的路由值,來決定哪個分片來處理:
POST twitter/_delete_by_query?routing=
{
"query": {
"range" : {
"age" : {
"gte" :
}
}
}
}
預設情況下,
_delete_by_query
自上而下批量1000條資料,你也可以在URL中使用參數
scroll_size
:
POST twitter/_delete_by_query?scroll_size=
{
"query": {
"term": {
"user": "kimchy"
}
}
}
URL Parameters(url 參數)
除了标準參數像
pretty
,
Delete By Query API
也支援
refresh
、
wait_for_completion
、
wait_for_active_shards
和
timeout
。
發送帶
refresh
參數的請求一旦完成,在
delete by query
api中涉及到的所有分片都将會重新整理。這不同于
Delete API
中的
refresh
參數,其是在收到删除請求時就重新整理分片。
如果請求中包含
wait_for_completion=false
,那麼
elasticsearch
将會執行
預檢查
、
啟動請求
,并傳回一個可被
Tasks APIs
使用的
task
,以取消或者得到
task
狀态。
elasticsearch
也将會在
.tasks/task/${taskId}
路徑中建立一個文檔來記錄這個
task
。你可以根據自己的情況來選擇保留還是删除它;當你删除後,
elasticsearch
會回收利用它的空間。
在處理請求之前,
wait_for_active_shards
控制需要多少個副本分片必須處于活動狀态。詳情這裡。
timeout
用于控制每個寫請求等待不可用分片變成可用分片的時間。兩者都能在
Bulk API
中正常工作。
requests_per_second
可以設定任何正的十進制數字(1.4、6、1000等等)并且可以限制
delete-by-query
發出的每秒請求數量或者将其設定為
-1
來禁用這種限制。這種限制會在批處理之間等待,以便于其能操作
scroll timeout
。這個等待時間與完成批處理之間的時間和
requests_per_second * requests_in_the_batch
時間是有差別的。由于批處理不會分解成多個請求,而如此大的批處理将會造成
elasticsearch
建立多個請求并且會在開始下個集合(批處理)之前等待一會,這是
bursty
而不是
smooth
。預設為
-1
。
Response body(響應體)
響應體的
json
格式如下:
{
"took" : ,
"deleted": ,
"batches": ,
"version_conflicts": ,
"retries": ,
"throttled_millis": ,
"failures" : [ ]
}
參數 | 描述 |
---|---|
took | 從整個操作開始到結束花費的時間,機關是毫秒 |
deleted | 成功删除文檔的數量 |
batches | 通過 返復原動響應的數量(我的看法:符合 條件的文檔數量) |
version_conflicts | api命中的沖突版本的數量(即在執行過程中,發生了多少次沖突) |
retries | 在 響應一個完整隊列,重試的次數 |
throttled_millis | 根據 ,請求睡眠多少毫秒 |
failures | 是個數組,表示失敗的所有索引(插入);如果它不為空的話,那麼請求會因為故障而中止。可以參考如何防止版本沖突而中止操作。 |
Works with the Task API
你可以使用
Task API
來擷取任何一個正在運作的
delete-by-query
請求的狀态。
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" : ,
"type" : "transport",
"action" : "indices:data/write/delete/byquery",
"status" : { ①
"total" : ,
"updated" : ,
"created" : ,
"deleted" : ,
"batches" : ,
"version_conflicts" : ,
"noops" : ,
"retries": ,
"throttled_millis":
},
"description" : ""
}
}
}
}
}
①這個對象包含實際的狀态。響應體是
json
格式,其中
total
字段是非常重要的。
total
表示期望執行
reindex
操作的數量。你可以通過加入的
updated
、
created
和
deleted
字段來預估進度。但它們之和等于
total
字段時,請求将結束。
使用
task id
可以直接查找此
task
。
GET /_tasks/taskId:
這個
api
的優點是它整合了
wait_for_completion=false
來透明的傳回已完成任務的狀态。如果此任務完成并且設定為
wait_for_completion=false
,那麼其将傳回
results
或者
error
字段。這個特性的代價就是當設定
wait_for_completion=false
時,會在
.tasks/task/${taskId}
中建立一個文檔。當然你也可以删除這個文檔。
Works with the Cancel Task API
任何一個
Delete By Query
都可以使用
Task Cancel API
來取消掉:
POST _tasks/task_id:1/_cancel
可以使用上面的
task api
來找到
task_id
;
取消應該盡快發生,但是也可能需要幾秒鐘,上面的
task 狀态 api
将會進行列出
task
直到它被喚醒并取消自己。
Rethrottling
requests_per_second
的值可以在使用
_rethrottle
參數的正在運作的
delete by query
api上進行更改:
使用上面的
tasks API
來查找
task_id
就像在
_delete_by_query
中設定一樣,
requests_per_second
可以設定
-1
來禁止這種限制或者任何一個10進制數字,像
1.7
或者
12
來限制到這種級别。加速查詢的
Rethrottling
會立即生效,但是緩慢查詢的
Rethrottling
将會在完成目前批處理後生效。這是為了防止
scroll timeouts
。
Manually slicing
Delete-by-query
支援
Sliced Scroll
,其可以使你相對容易的手動并行化程序:
POST twitter/_delete_by_query
{
"slice": {
"id": ,
"max":
},
"query": {
"range": {
"likes": {
"lt":
}
}
}
}
POST twitter/_delete_by_query
{
"slice": {
"id": ,
"max":
},
"query": {
"range": {
"likes": {
"lt":
}
}
}
}
你可以通過以下方式進行驗證:
GET _refresh
POST twitter/_search?size=&filter_path=hits.total
{
"query": {
"range": {
"likes": {
"lt":
}
}
}
}
像下面這樣隻有一個
total
是合理的:
{
"hits": {
"total":
}
}
Automatic slicing
你也可以使用
Sliced Scroll
讓
delete-by-query api
自動并行化,以在
_uid
上切片:
POST twitter/_delete_by_query?refresh&slices=
{
"query": {
"range": {
"likes": {
"lt":
}
}
}
}
你可以通過以下來驗證:
POST twitter/_search?size=&filter_path=hits.total
{
"query": {
"range": {
"likes": {
"lt":
}
}
}
}
像下面的
total
是一個合理的結果:
{
"hits": {
"total":
}
}
添加
slices
,
_delete_by_query
将會自動執行上面部分中使用手動處理的部分,建立子請求這意味着有些怪事:
- 你可以在
中看到這些請求。這些子請求是使用了Tasks APIs
請求任務的子任務。slices
- 為此請求(使用了
)擷取任務狀态僅僅包含已完成切片的狀态。slices
- 這些子請求都是獨立尋址的,例如:取消和
.rethrottling
- Rethrottling the request with slices will rethrottle the unfinished sub-request proportionally.
- 取消
請求将會取消每個子請求。slices
- 由于
的性質,每個子請求并不會得到完全均勻的文檔結果。所有的文檔都将要處理,但是有些slices
(切片)會大些,有些會小些。希望大的slices
(切片)有更均勻的配置設定。slices
- 在
請求中像slices
和requests_per_second
參數,按比例配置設定給每個子請求。結合上面的關于配置設定的不均勻性,你應該得出結論:在包含size
的slices
請求中使用_delete_by_query
參數可能不會得到正确大小的文檔結果。size
- 每個子請求都會獲得一個略微不同的源索引快照,盡管這些請求都是大緻相同的時間。
Picking the number of slices
這裡我們有些關于
slices
數量的建議(如果是手動并行的話,那麼在
slice api
就是
max
參數):
- 不要使用大數字。比如500,将會建立相當大規模的
CPU
震蕩。
這裡說明下震蕩(thrashing)的意思:
大部分時間都在進行換頁,而真正工作時間卻很短的現象稱之為cpu
thrashing (震蕩)
- 從查詢性能角度來看,在源索引中使用多個分片是更高效的。
- 從查詢性能角度來看,在源索引中使用和分片相同的數量是更高效的。
- 索引性能應該在可利用
之間進行線性擴充。slices
- 索引(插入)或查詢性能是否占主導地位取決于諸多因素,比如:重新索引文檔和叢集進行重新索引。
參考位址:
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html