Elasticsearch写入速度优化[翻译版]

在上一篇文章「程序员英语学习指北: 阅读篇」中提到了学习英语需要用起来,假期尝试对Elasticsearch文档进行了翻译,最终成果如下。

原文链接:https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html

1.使用批处理请求接口(bulk requests)

批处理接口的性能要远优于单文档写入接口。为了确定批处理最适合的大小,基准测试应该基于单节点、单分片。首先尝试一次写入100个文档,然后加大到200个、400个,以此类推。每次跑基准测试时将写入数量加倍。当写入速度趋于平稳时,说明已经达到了单次写入的最适合批次大小。在同等情况下,文档数量不宜过多。值得注意的是,大数据量的批处理请求在并发高时,会加大集群的内存压力,因此需要尽量避免一次请求超过几十兆的数据量,就算是效率更高。

2.使用多线程实现写入数据

单线程发送批处理请求,并不能最大化Elasticsearch集群的写入效率。为了集群资源的最大化利用,你应该使用多线程来进行处理。除了更好的利用集群资源,还能够降低数据同步的成本。

当出现 TOO_MANY_REQUESTS (429) 返回码(在Java客户端是 EsRejectedExecutionException 异常)时,说明 Elasticsearch 无法承载当前的写入速率。此时,你需要降低写入的速率,最好能够使用指数级的降级策略。

和批处理大小类似,确定并发线程数量只能通过不断的测试。测试方式是通过逐步增加线程数量,直到 I/0 或者 CPU资源达到饱和为止。

3.不设置或者增大刷新间隔

通过 refresh 操作,数据才能被搜索到,执行成本较高,当数据正在写入时,频繁的 refresh 会影响写入速度。

默认情况下,Elasticsearch每秒刷新一次索引,但是只有在最近30s内收到一次或者多次搜索请求时才会生效。

如果你的搜索请求量非常小(例如,5分钟内少于一次),或者想要优化写入速度,有相应的配置可以进行支持。默认情况是这没有搜索执行时,可以自动优化批量写入速度。可以通过设置刷新间隔参数来显式的进行设置。

另一方面,如果你的索引有比较稳定的请求流量,Elasticsearch将默认每秒刷新一次数据。如果你能够接受文档从写入完成到可以被搜索到有较大的延迟时间,可以将

index.refresh_interval 参数设置为一比较大的值,例如30s,可以改善文档写入速度。

4.在初始化时不开启备份

如果你有大批量的数据想要一次性导入到Elasticsearch,将 index.number_of_replicas 参数设置为0将有利于提升写入速度。缺少备份意味着存在数据丢失的风险,所以很重要的一点是,在其他地方有存储这份数据以便在意外的情况下可以进行重试操作。一旦数据初始化工作完成,可以将index.number_of_replicas 参数恢复为原始值。

如果index.refresh_interval 参数是配置在索引上的,在初始化数据的场景下不进行设置,在初始化完成后恢复原始值,将会是一个很有帮助的特性。

5.关闭swapping

你应该通过关闭操作系统的swapping的功能,来确保Java进程的内存不会被超额使用。

6.留足文件系统内存

文件系统内存用于数据的 I/O 操作。你应该确保运行Elasticsearch的机器上至少有一半的内存可以被文件系统内存使用。

7.使用自增ID

当写入一份带有id属性的文档时,Elasticsearch需要检查在同一个分片上是否已经存在具有相同id的文档,而这个操作随着文档数量的增加将耗费更多的时间。使用自增id,Elasticsearch可以跳过检查的这一步,加快写入速度。

8.使用更快的硬件

如果数据写入达到了I/O瓶颈,可以考虑增加文件系统的内存或者使用更快的存储设备。Elasticsearch在创建单个文件时是使用顺序写入。然而,并发写入多个文件时,会涉及到随机读和顺序读操作,因此SSD要比机械硬盘有更好的性能。

通过设置RAID 0磁盘阵列,将索引分布着多个SSD磁盘上。这样会增加失败的风险,当任一SSD磁盘毁坏了索引数据时。然而,常用的权衡利弊的做法是,将单个分片的性能提升到极致,然后通过副本的方式在其他分片上设置冗余数据,来解决任意节点失败的情况。为了更加保险,可以通过设置快照的方式来进行备份数据。

9.写入的缓存大小

如果你的节点在进行大量数据写入,确保 indices.memory.index_buffer_size 参数足够大到每个分片有最多512M的indexing buffer(超过这个值写入性能不会有明显的改善)。Elasticsearch将这个设置(java heap的百分比或者具体的数值)作为共享内存提供给所有活跃的分片使用。更加活跃的分片会占用更多的内存。

默认值10%通常上足够的,例如,jvm内存设置为10G,index buffer就上1G了,足够2个分片进行大量数据的写入。

10.使用多集群实现读写分离

在单个集群中,读写需要竞争资源。设置2个集群,通过跨集群复制将数据从一个集群复制到另外一个,将查询请求都路由到从索引,查询操作将不会占用主索引节点的资源了。

11.避免热点问题

当节点资源、分片、请求不均衡时可能会出现热点问题。Elasticsearch通过跨节点来同步集群状态,热点问题将引发集群能力的退化。

12.其他优化策略

在磁盘的使用方面也有很多可以提升写入速度的策略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值