如何提高Elasticsearch 集群写入性能

问题描述

想要提高/改善 Elasticsearch 写入性能,有哪些对应的方法?

问题分析

Elasticsearch 写入过程大致可以分为如下阶段:

  1. coordinator 节点接受请求,找到 primary shard
  2. Refresh:文档写入到 index buffer,以 refresh_interval 为周期,清空 index buffer 并生成 segment,此时数据在文件系统缓存中,此时文档可以被搜索。refresh 是一个比较重的操作。
  3. Translog: Elasticsearch 使用translog来记录所有的操作, 概念类似于 MySQL 中的redo log。Elasticsearch 使用 Translog 和 replica 保证数据的安全性
  4. Flush:删除旧的 translog,生成 新的 Segment 并写入磁盘, 更新 commit point 并写入磁盘。
  5. 发送同样的请求给 replica,replica 执行的动作和 primary 是类似的。

了解了 Elasticsearch 写入流程之后,我们可以针对写入流程中的步骤,找出对应的解决方案。

解决方案

1. 提高 refresh_interval

前面我们提到 refresh 是一个很重的操作,如果我们将 refresh 的周期调整的长一些,如60s,会显著提高写入速度。调整此参数负面影响是 搜索的实时性降低,因此调整此参数适用于对数据实时性要求不高的场景。

2. 将副本数修改为0

由于副本分片同样会有refresh, flush 操作,如果在大批量数据写入/数据迁移过程中,可以先将副本数修改为0,待索引完成后,再打开,将显著提高集群写入能力。

3. 批量写入数据

Elasticsearch 提供了批量写入数据的 bulk API,ES 将一批数据进行组装,异步发送给各个分片所在的节点,可以降低网络交互次数,提高吞吐量。通常建议一次 bulk 在 10 MB左右。具体性能依照测试而定。

4. 写入数据时不指定 doc_id

如果我们手动指定doc_id,ES 写入过程中会多一层判断,如果该doc_id 存在,则进行更新操作,如果不存在,则进行插入操作。建议让ES自动生成 doc_id,这样可提升一定的写入性能。

5. 调整 translog 相关配置

控制 translog 刷新有如下三个参数:

  1. Index.translog.durability:默认是 request,即每个请求都落盘。可以设置成 async 来进行异步写入。

  2. Index.translog.sync_interval translog 刷盘策略,可以设置为 60s,每分钟执行一次。

  3. Index.translog.flush_threshod_size: 默认 512 MB,可以适当调大。 当 translog 超过该值,会触发flush。

调整这三个参数的优点是降低写磁盘的频率,但是会降低数据的安全性。

6. 提前创建索引,并使用 index mapping

创建索引以及新增字段都涉及到元数据操作,同时也需要将此信息同步给所有节点。在集群负载较大的情况下,很容易出现集群元数据更新超时的问题。

7. 监控集群性能,提高集群配置

需要实时监控集群是否有性能瓶颈,可以全方位提高集群配置,来达到提升写入性能的目的。

8. 其他建议

  1. 减少不必要的分词
  2. 避免不需要的doc_value
  3. 文档的字段尽量保证相同的顺序,可以提高文档的压缩率
  4. 避免 dynamic mapping, 避免字段数量过多。
总结

通常来说,提高写入性能的时候,会牺牲部分数据可靠性以及实时搜索性,具体如下:

  1. 牺牲可靠性:将副本分片设置为 0,写入完毕再调整回去

  2. 牺牲搜索实时性:增加 Refresh Interval 的时间

  3. 牺牲可靠性:修改 Translog 的配置

对于提高 Elasticsearch 的一切优化手段,都基于高质量的数据建模,同时结合业务特点进行分析,才能达到最优的效果。

参考文档

[1] https://www.elastic.co/guide/en/elasticsearch/guide/2.x/indexing-performance.html#_using_and_sizing_bulk_requests

如果您有其他问题,欢迎您联系火山引擎技术支持服务

178
1
0
0
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论