Elasticsearch冷数据段合并

Posted by Turing Byte on July 3, 2019

什么是段合并

elasticsearch中每个索引都会创建一个到多个分片和零个到多个副本,这些分片或副本实质上都是lucene索引。lucene索引是基于多个索引段创建,索引文件中绝大部分数据都是只写一次,读多次,而只有用于保存文档删除信息的文件才会被多次更改。在某些时刻,当某种条件满足时,多个索引段会被拷贝合并到一个更大的索引段,而那些旧的索引段会被抛弃并从磁盘中删除,这操作叫做段合并(segment merging)。

为什么要进行段合并

  • 索引段的个数越多,搜索性能越低且消耗内存更多。
  • 索引段是不可变的,物理上你并不能从中删除信息(如果你碰巧从索引中删除了大量文档,但这些文档只是做了删除标记,物理上并没有被删除)而当段合并发送时,这些标记为删除的文档并没有被复制到新的索引段中。

段合并的好处

  • 当多个索引段合并为一个的时候,会减少索引段的数量并提高搜索速度
  • 同时也会减少索引的容量(文档数)

段合并的代价

IO操作代价,在速度较慢的系统中,段合并会显著影响性能。

如何进行段合并

利用curator进行段合并,如对xx_%Y.%m.%d类型的index,对2天前的index都进行强制合并,配置如下:

actions:
  1:
    action: forcemerge
    description: >-
      Perform a forceMerge on selected indices to 'max_num_segments' per shard.
    options:
      max_num_segments: 1
      delay:
      timeout_override: 10000000
      continue_if_exception: True
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: xx_
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 2
      exclude:

如果出现以下错误:

Failed to complete action: forcemerge.  <class 'curator.exceptions.FailedExecution'>: Exception encountered.  Rerun with loglevel DEBUG and/or check Elasticsearch logs for more information. Exception: TransportError(403, u'cluster_block_exception', u'blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];')

则可以通过修改配置,允许read-only的index被delete:

curl -XPUT -H "Content-Type: application/json" {host}:{port}/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'

forcemerge的过程比较漫长,需要等待。

参考资料

https://www.elastic.co/guide/en/elasticsearch/client/curator/current/forcemerge.html