ElasticSearch 初始批量导入的最佳实践

Best practices for ElasticSearch initial bulk import

我 运行 受 Elastic Docker Compose 启发,使用 ElasticSearch、Logstash、Filebeat 和 Kibana 进行了 docker 设置。我需要将 15 GB og 日志文件初始加载到系统中 (Filebeat->Logstash->ElasticSearch),但我遇到了一些性能问题。

似乎 Filebeat/Logstash 为 ElasticSearch 输出了太多的工作。一段时间后,我开始在 ElasticSearch 中看到一堆这样的错误:

[INFO ][o.e.i.IndexingMemoryController] [f8kc50d] now throttling indexing for shard [log-2017.06.30]: segment writing can't keep up

我找到了这篇关于如何禁用合并限制的旧文档文章:https://www.elastic.co/guide/en/elasticsearch/guide/master/indexing-performance.html#segments-and-merging

PUT /_cluster/settings
{
    "transient" : {
        "indices.store.throttle.type" : "none" 
    }
}

但在当前版本 (ElasticSearch 6) 中,它给了我这个错误:

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "transient setting [indices.store.throttle.type], not dynamically updateable"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "transient setting [indices.store.throttle.type], not dynamically updateable"
  },
"status": 400
}

如何解决上述问题?

VM 有 4 个 CPU 内核(Intel Xeon E5-2650),ElasticSearch 分配了 4GB 内存,Logstash 和 Kibana 各分配了 1GB。使用 "swapoff -a" 禁用交换。 X-pack 和监控已启用。这个日志服务器我只有一个ES节点。对于这个初始批量导入,我需要有多个节点吗?

编辑 1:

更改 number_of_replicasrefresh_interval 似乎可以使其性能更好。仍在测试中。

PUT /log-*/_settings
{
    "index.number_of_replicas" : "0",
    "index.refresh_interval" : "-1"
}

瓶颈多半是IO(这个运行iostat你可以确认一下,如果你postES监控截图也有用),需要减轻一下压力。

默认 ES 配置导致在批量加载期间生成许多索引段。要解决此问题,对于批量加载,增加 index.refresh_interval(或将其设置为 -1)- 请参阅 doc。默认值是 1 秒,这会导致每 1 秒创建一个新段,也尝试增加批处理大小,看看是否有帮助。

此外,如果您使用旋转磁盘,请将 index.merge.scheduler.max_thread_count 设置为 1。这将只允许一个线程执行段合并,并将减少段合并之间的 IO 争用和索引。