ElasticSearch 6.3版本 Document APIs之Delete By Query API

Delete By Query API

最简单的用法是_delete_by_query对匹配查询的每个文档执行删除操作。这是API:

POST twitter/_delete_by_query
{
"query": {
"match": {
"message": "some message"
}
}
}

必须query以与Search API相同的方式将查询作为值传递给键。也可以使用 q 与Search API相同的方式使用参数。

返回内容如下:

{
"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在索引启动时获取索引的快照,并使用internal版本控制删除它找到的内容。这意味着如果文档在拍摄快照的时间和处理删除请求之间发生更改,则会出现版本冲突。当版本匹配时,文档被删除。

由于internal版本控制不支持将值0作为有效版本号,因此无法使版本等于零的文档删除,_delete_by_query请求失败。

在_delete_by_query执行期间,顺序执行多个搜索请求以便找到要删除的所有匹配文档。每次找到一批文档时,都会执行相应的批量请求以删除所有这些文档。如果搜索或批量请求被拒绝,则_delete_by_query依赖于默认策略来重试被拒绝的请求(最多10次,指数后退)。达到最大重试次数限制会导致_delete_by_query中止,并failures在响应中返回所有失败。已执行的删除仍然有效。换句话说,该过程不会回滚,只会中止。当第一个失败导致中止时,失败的批量请求返回的所有失败都将返回到failures元件,因此可能存在相当多的失败实体。

如果想计算版本冲突而不是让它们中止,可以在URL中设置 confilcts=proceed 或在请求体中设置 "conflicts":"proceed"。

回到API格式,删除twitter索引中的推文:

POST twitter / _doc / _delete_by_query?conflicts = proceed
{
“query”:{
“match_all”:{}
}
}

也可以一次删除多个索引和多个类型的文档,就像Search API一样:

POST twitter,blog / _docs,post / _delete_by_query
{
“query”:{
“match_all”:{}
}
}

如果提供路由,则将路由复制到滚动查询,将进程限制为与路由值匹配的分片:

POST twitter / _delete_by_query?routing = 1
{
“query”:{
“range”:{
“age”:{
“gte”:10
}
}
}
}

默认情况下,_delete_by_query使用1000的滚动批次。您可以使用scroll_size URL参数更改批量大小:

POST twitter / _delete_by_query?scroll_size = 5000
{
“query”:{
“term”:{
“user”:“kimchy”
}
}
}

URL 参数

除了标准的参数,如pretty,删除通过查询API也支持refresh,wait_for_completion,wait_for_active_shards,timeout和scroll。

发送refresh请求将在请求完成后刷新查询删除中涉及的所有分片。这与Delete API的refresh参数不同,后者仅导致接收删除请求的分片被刷新。

如果请求包含,wait_for_completion=false则Elasticsearch将执行一些预检检查,启动请求,然后返回task可与Tasks API一起使用的取消或获取任务状态的请求。Elasticsearch还将创建此任务的记录作为文档.tasks/task/${taskId}。你可以保留或者删除只要你认为合适。当你完成它后删除它,以便Elasticsearch可以回收它使用的空间。

wait_for_active_shards控制在继续请求之前必须激活分片的副本数量。timeout控制每个写入请求等待不可用分片变为可用的时间。两者都完全适用于Bulk API中的工作方式。由于_delete_by_query采用滚动搜索,你还可以指定scroll参数来控制它存活多长时间保持“搜索上下文”,例如?scroll=10m,默认情况下它是5分钟。

requests_per_second可以被设置为任何正十进制数(1.4,6,1000等)和节流速率_delete_by_query通过填充每个批次由一等待时间发出的删除操作的批次。可以通过设置requests_per_second为-1来禁用限制。

节流通过在批处理之间的等待来完成限制,以便在_delete_by_query内部使用的滚动可以被赋予考虑填充的超时。填充时间是批量大小除以requests_per_second写入所花费的时间之间的差异。默认情况下,批量大小为1000,因此如果requests_per_second设置为500:

target_time = 1000 / 500 per second = 2 seconds
wait_time = target_time - write_time = 2 seconds - .5 seconds = 1.5 seconds

由于批处理是作为单个_bulk请求发出的,因此大批量大小将导致Elasticsearch创建许多请求,然后等待一段时间再开始下一组。这是“突发”而不是“平滑”。默认是-1.

响应正文

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:若在通过查询执行删除期间执行的任何请求超时,则将此标志设置为true;

  • total:已成功处理的文档数;

  • deleted:已成功删除的文档数;

  • batches:通过查询删除拉回的滚动响应数;

  • version_conflicts:按查询删除的版本冲突数;

  • noops:对于按查询删除,此字段始终等于零。它只存在于由查询删除、查询更新和重新索引API返回的具有相同结构的响应中;

  • retries:通过查询删除尝试的重试次数。bulk是重试的批量动作的数量,search是重试的搜索动作的数量;

  • throttled_millis:请求睡眠符合的毫秒数requests_per_second;

  • requests_per_second:在通过查询删除期间有效执行的每秒请求数;

  • throttled_until_millis:在按查询响应删除时,此字段应始终等于零。它只在使用Task API时有意义,它指示下一次(自纪元以来的毫秒数)为了符合将再次执行受限制的请求requests_per_second;

  • failures:如果在此过程中存在任何不可恢复的错误,则会出现故障数组。如果这是非空的,那么请求因为那些失败而中止。逐个查询是使用批处理实现的,任何故障都会导致整个进程中止,但当前批处理中的所有故障都会被收集到数组中。可以使用该conflicts选项来防止reindex在版本冲突中中止。

使用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是reindex期望执行的操作总数。可以通过添加估计的进展updated,created以及deleted多个领域。请求将在其总和等于total字段时结束。

使用任务ID,可以直接查找任务:

GET /_tasks/taskId:1

此API的优势在于它可以集成wait_for_completion=false以透明地返回已完成任务的状态。如果任务已完成并wait_for_completion=false已设置在其上,则它将返回results或带有error字段。此功能的成本是wait_for_completion=false创建的文档 .tasks/task/${taskId} 。你可以删除该文档。

使用Cancel Task API

可以使用“Task Cancel API”取消任何“Delete By Query”:

POST _tasks/task_id:1/_cancel

在task_id可以使用上述任务的API被发现。

取消应该很快发生,但可能需要几秒钟。上面的任务状态API将继续列出任务,直到它被唤醒以取消自身。

Rethrottling

requests_per_second可以使用_rethrottle API通过查询在运行删除时更改值:

POST _delete_by_query/task_id:1/_rethrottle?requests_per_second = -1

在task_id可以使用上述任务的API被发现。

就像在_delete_by_query API上设置它一样,requests_per_second可以设置-1禁用限制或任何十进制数,如1.7或12限制到该级别。加速查询的Rethrottling会立即生效,但是在完成当前批处理后,重新启动会降低查询速度。这可以防止滚动超时。

切片

逐个查询支持切片滚动以并行化删除过程。这种并行化可以提高效率,并提供一种方便的方法将请求分解为更小的部分。

手动切片

通过为每个请求提供切片ID和切片总数,手动切片查询:

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
}
}
}
}

您可以验证哪个适用于:

GET _refresh
POST twitter/_search?size=0&filter_path=hits.total
{
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}

这样的结果是明智的:

{
"hits": {
"total": 0
}
}

自动切片

您也可以让delete_by_query自动并行化,使用“切片滚动”在_uid上切片。使用slices指定要使用的片数:

POST twitter/_delete_by_query?refresh&slices=5
{
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}

你也可以验证以下内容:

POST twitter/_search?size=0&filter_path=hits.total
{
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}

这样的结果是明智的:

{
"hits": {
"total": 0
}
}

设置slices为auto将让Elasticsearch选择要使用的切片数。此设置将使用每个分片一个切片,达到一定限制。如果有多个源索引,它将根据具有最小分片数的索引选择切片数。

添加slices到_delete_by_query创建子请求,这意味着它有一些怪癖:

  • 你可以在Tasks API中查看这些请求,这些子请求是带有切片的请求的任务的“子任务”;

  • 获取请求的任务状态slices仅包含已完成切片的状态;

  • 这些子请求可单独寻址,例如取消和重新限制;

  • 对请求进行重新处理slices将按比例重新调整未完成的子请求;

  • 取消请求slices将取消每个子请求;

  • 由于切片的性质,每个子请求将无法获得文档的完全均匀部分。所有文档都将被处理,但某些切片可能比其他文件更大。期望更大的切片具有更均匀的分布;

  • 像requests_per_second请求和size请求的参数slices按比例分配给每个子请求,结合上面关于分布不均匀的点,可得出结论,使用size with slices可能并不会导致每个文件被分配的文档大小是均匀的;

  • 每个子请求获得的源索引的快照是略有不同的,尽管这些都是在大约相同的时间进行的。

挑选切片的数量

如果自动切片,设置slices为auto将为大多数索引选择合理的数字。如果手动切片或以其他方式调整自动切片,请使用以下指南。

当切片数量等于索引中的分片数时,查询性能最有效。如果该数字很多(如500),请选择较小的数字,因为太多slices(切片)会损害性能。设置切片数高于分片数通常不会提高效率并增加开销。

删除性能在可用资源上以切片数量线性扩展。

查询或删除性能是否主导运行时取决于重新编制索引的文档和集群资源。

猜你喜欢

转载自blog.csdn.net/qingmou_csdn/article/details/80957688
今日推荐