使用 Delete By Query API 的方式删除ES索引中的数据 - 腾讯云开发者社区

腾讯云 · · 1361 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、前言|

ES作为现今最流行的搜索存储库,我们需要定期去清理ES集群的数据以保证集群处在一个最佳负载状态,那么如何去删除这些数据呢,我们今天来介绍一种比较常见的通过Delete By Query的方式去删除索引中的数据。

二、Delete By Query API 介绍

怎么理解这个API呢?实际是批量删除数据的意思 功能:根据特定的查询条件对ES相关索引中某些特定的文档进行批量删除。

POST index_name/_delete_by_query
{
  "query": { //这些是自定义查询条件,根据查询条件去批量删除
    "match": {//请求体跟Search API是一样的
      "message": "some message"
    }
  }
}

Delete By Query 删除原理:

Delete_by_query并不是真正意义上物理文档删除,而是只是版本变化并且对文档增加了删除标记。当我们再次搜索的时候,会搜索全部然后过滤掉有删除标记的文档。因此,该索引所占的空间并不会随着该API的操作磁盘空间会马上释放掉,只有等到下一次段合并的时候才真正被物理删除,这个时候磁盘空间才会释放。相反,在被查询到的文档标记删除过程同样需要占用磁盘空间,这个时候,你会发现触发该API操作的时候磁盘不但没有被释放,反而磁盘使用率上升了。

使用Delete By Query 删除API注意事项:

1, 一般生产环境中,使用该API操作的索引都很大,文档都是千万甚至数亿级别。索引大小在几百G甚至几个T,因此,这个操作建议在业务低峰期或者晚上进行操作,因为大数据量情况下删除的需要消耗较多的i/o CPU 资源,容易对生产集群造成影响。

2,在删除过程中要确定集群磁盘有一定的余量,因为标记删除需要占用磁盘空间。如果磁盘空间不够,这个操作的失败率还是很大的。

3,Delete By Query有很多配置参数,这里不详解,具体可以参考文档:

https://www.elastic.co/guide/en/elasticsearch/reference/7.2/docs-delete-by-query.html

三、段合并 --> 强制段合并 --> Force merge 《高资源消耗动作》

由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦。 每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢。Elasticsearch通过在后台进行段合并来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段。段合并的时候会将那些旧的已删除文档从文件系统中清除。被删除的文档(或被更新文档的旧版本)不会被拷贝到新的大段中。启动段合并不需要你做任何事。进行索引和搜索时会自动进行。

Elasticseach会有后台线程根据Lucene的合并规则定期进行segment merging合并操作,一般不需要用户担心或者采取任何行动。被删除的文档在segment合并时,才会被真正删除掉。在此之前,它仍然会占用着JVM heap和操作系统的文件cache、磁盘等资源。在某些特定情况下,我们需要强制Elasticsearch进行segment merging,已释放其占用的大量系统、磁盘等资源。具体操作如下:

POST /index_name/_forcemerge

_forcemerge 命令可强制进行segment合并,并删除所有标记为删除的文档。Segment merging要消耗CPU,以及大量的I/O资源,所以一定要在你的ElasticSearch集群处于维护窗口期间,并且有足够的I/O空间的(如:SSD)的条件下进行;否则很可能造成集群崩溃和数据丢失.<这个非常重要>

_forcemergeAPI 有几个常用的参数:

max_num_segments 是表示将某个索引的每个分片强制合并为几个段的意思。

only_expunge_deletes 是表示仅将标记删除为文档的进行强制合并物理删除,不进行其它合并操作。

比如下面的API,表示:

POST /index_name/_forcemerge?max_num_segments=1

上面API的意思表示合并索引中的每个分片为一个单独的段,可以先设置大一点,10-5-1,一点一点慢慢降到1。一般推荐为1.

或者如下操作:

POST /index_name/_forcemerge?max_num_segments=1&only_expunge_deletes=true

四、Delete_by_query 、Forcemerge 数据操作实践

案例背景:

客户集群的索引没有预先规划大小,导致索引特别大,删除数据删除索引的形式进行,只能在原来的索引上进行数据删除操作。

实际情况如下图所示:

用户索引情况

在保证业务低峰期,我们进行delete_by_query操作,如下:

POST /index-name/_delete_by_query?slices=auto&conflicts=proceed&wait_for_completion=false
{         //多线程并发删除满足查询条件的数据
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must_not": [
            {
              "term": {     //查询条件,可以自定义
                "action": "XXXXXXX"
              }
            },
            {
              "exists": {
                "field": "XXXXXXXX"   //查询条件,可以自定义
              }
            }
          ]
        }
      }
    }
  }
}

执行如上程序,会生成一个TaskID,我们可以通过这个taskID去查看这个进程。

执行上面的API,后面的工作直接交给ES进程去调用处理,这个过程根据数据大小来定。接着,我们再执行强制合并,快速删除数据,释放系统资源,我们需要强制合并。如下操作:

POST /index_name/_forcemerge?max_num_segments=1&only_expunge_deletes=true
or
POST /index_name/_forcemerge?max_num_segments=1

执行上面2个步骤,整个流程就基本操作完毕,其它工作交给系统自动完成。时间待定。期间你会发现,磁盘空间会有一个反复变化的过程,磁盘使用率会先增长,然后在删除释放空间这样一个过程。这个过程无需紧张,都是正常现象。最终,流程执行完毕后会形成如下结果:

删除完毕后的文档

以上就是整个批量删除和强制段合并操作实列。

五、总结

ES删除数据共有如下几种方式:

1,删除指定文档:指定索引–>类型–>id的方式对文档进行删除

DELETE /index/type/1

2,批量删除:Delete_by_query 特点:麻烦,注意事项挺多,专业度高。

3,删除索引:Delete Index 特点:干净快速,一步到位。

4,Delete_by_query,定时任务,参考下文: https://blog.csdn.net/geekswg/article/details/107097322

5,本文鸣谢以下链接信息:

https://blog.csdn.net/u013200380/article/details/109163812

https://www.elastic.co/guide/en/elasticsearch/reference/7.2/indices-forcemerge.html#indices-forcemerge

https://www.jianshu.com/p/60a6ad164035

1361 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传