【问题标题】:ElasticSearch - How to merge indexes into one index?ElasticSearch - 如何将索引合并为一个索引?
【发布时间】:2017-09-11 10:38:54
【问题描述】:

自几个月前以来,我的集群每天都有一个索引, 每个索引 5 个分片(默认), 而且我无法在整个集群上运行查询,因为分片太多(超过 1000 个)。

文档 ID 会自动生成。

如何将索引合并为一个索引、处理冲突的 id(如果甚至可能发生冲突)以及更改类型?

我使用的是 ES 版本 5.2.1

【问题讨论】:

  • 你用的是哪个版本的ES?
  • 我使用的是 ES 版本 5.2.1

标签: elasticsearch


【解决方案1】:

只有在使用 ELK 堆栈和 filebeat 每天创建索引几个月后才能看到的常见问题。这里有几个选项可以解决性能问题。

_forcemerge

首先您可以使用_forcemerge 来限制Lucene 索引中的段数。操作不会限制或合并索引,但会提高 Elasticsearch 的性能。

curl -XPOST 'localhost:9200/logstash-2017.07*/_forcemerge?max_num_segments=1'

这将贯穿整个月的索引并强制合并段。如果每个月都完成,它应该会大大提高 Elasticsearch 的性能。在我的情况下,CPU 使用率从 100% 下降到 2.7%。

很遗憾,这并不能解决分片问题。

_reindex

请阅读_reindex 文档并在继续之前备份您的数据库。

正如tomas 提到的。如果您想限制分片或索引的数量,除了使用_reindex 将几个索引合并为一个之外别无选择。这可能需要一段时间,具体取决于您拥有的索引的数量和大小。

目的地索引

您可以预先创建目标索引并指定它应该包含的分片数量。这将确保您的最终索引具有您需要的分片数量。

curl -XPUT 'localhost:9200/new-logstash-2017.07.01?pretty' -H 'Content-Type: application/json' -d'
{
    "settings" : {
        "index" : {
            "number_of_shards" : 1 
        }
    }
}
'

限制分片数量

如果您想限制每个索引的分片数量,您可以一对一运行_reindex。在这种情况下,不应删除任何条目,因为它将是精确副本,但分片数量较少。

curl -XPOST 'localhost:9200/_reindex?pretty' -H 'Content-Type: application/json' -d'
{
    "conflicts": "proceed",
    "source": {
        "index": "logstash-2017.07.01"
    },
    "dest": {
        "index": "logstash-v2-2017.07.01",
        "op_type": "create"
    }
}
'

此操作后,您可以删除旧索引并使用新索引。不幸的是,如果您想使用旧名称,您需要再次使用新名称_reindex。如果你决定这样做

不要忘记为新索引指定分片数!默认情况下,它将回退到 5。

合并多个索引并限制分片数量

curl -XPOST 'localhost:9200/_reindex?pretty' -H 'Content-Type: application/json' -d'
{
    "conflicts": "proceed",
    "source": {
        "index": "logstash-2017.07*"
    },
    "dest": {
        "index": "logstash-2017.07",
        "op_type": "create"
    }
}
'

完成后,您应该将所有从logstash-2017.07.01logstash-2017.07.31 的条目合并到logstash-2017.07。请注意,旧索引必须手动删除。

根据您选择的conflictsop_type 选项,可以覆盖或合并某些条目。

进一步的步骤

用一个分片创建新索引

您可以设置每次创建新的logstash 索引时都会使用的index template

curl -XPUT 'localhost:9200/_template/template_logstash?pretty' -H 'Content-Type: application/json' -d'
{
    "template" : "logstash-*",
    "settings" : {
        "number_of_shards" : 1
    }
}
'

这将确保创建的与名称中的logstash- 匹配的每个新索引都只有一个分片。

按月分组日志

如果您不流式传输太多日志,您可以将您的 logstash 设置为按月对日志进行分组。

// file: /etc/logstash/conf.d/30-output.conf

output {
    elasticsearch {
        hosts => ["localhost"]
        manage_template => false
        index => "%{[@metadata][beat]}-%{+YYYY.MM}"
        document_type => "%{[@metadata][type]}"
    }
}

最后的想法

修复初始错误配置并不容易!祝您优化 Elastic 搜索顺利!

【讨论】:

  • 这是非常好的信息。当涉及到应用到一个特定的 ELK 实例时,官方文档可能很难理解。像许多人一样,在我更好地了解了 Shard 的真正含义后,我开始需要知道如何组合索引。
  • 合并多个索引后,你可以给新索引一个别名。无需重新索引即可使用旧名称。
  • a comment, "op_type": "create" 不创建索引当你reindex你需要预先创建目标索引。
【解决方案2】:

您可以使用reindex api

POST _reindex
{
 "conflicts": "proceed",
 "source": {
   "index": ["twitter", "blog"],
   "type": ["tweet", "post"]
  },
  "dest": {
  "index": "all_together"
 }
}

【讨论】:

  • 我试过了,但我认为来自不同索引的一些文档具有相同的 ID,因此并非所有文档最终都在新索引中:\
猜你喜欢
  • 2016-07-19
  • 1970-01-01
  • 2021-09-25
  • 2020-08-15
  • 2017-09-30
  • 1970-01-01
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多