提高Elasticsearch性能的几个建议

本文分享了提升Elasticsearch性能的实战经验,包括关注集群状态信息大小,合理分配节点角色,禁用内存交换以提高效率,利用docvalues避免OOM,调整集群分配相关属性以优化资源使用,以及设置合适的恢复属性和线程池参数。建议根据集群硬件配置进行测试以确定最佳值,确保数据安全和性能最大化。
摘要由CSDN通过智能技术生成

下面是根据自己工作中的一些经验总结出来一些影响Elasticsearch(以下简称ES)性能的建议。

集群状态信息

大部分人会注意到索引,分片的大小。我们在官网或者很多博客文章上都能看到建议的分片大小。但是集群的状态信息大小往往容易被忽略。

集群的状态信息保存着所有索引的mapping信息(当然还有其它信息)。如果mapping定义的过大会导致状态信息过大。而这些状态信息会在集群的所有节点之间同步。我的建议尽量使你的索引mapping保持合理大小。不需要的字段不要加入索引。

集群的节点角色

在这里插入图片描述

ES中的节点可以配置不同的角色,分别有

  • master (node.master = true)
  • data (node.data = true)
  • master (node.master = true)
  • ingest (node.ingest = true)
  • coordinating (上面都为false)

开发环境往往一个节点承担多种角色,但是生产环境不建议这么做。每个节点最好根据配置承担一个不同的角色。

master节点主要负责维护集群状态(上面提到的),不负责读写。所以配置可以低一些。data节点是数据存储和读写的节点,需要很高的配置。ingest节点主要负责数据的预处理,对磁盘要求不高,但是对CPU要求比较高。coordinating节点主要是为了负载均衡,对配置要求也不高。

禁用内存交换

ES官方一般会建议我们关闭内存交换。内存交换是操作系统的概念,简单来讲它提供一种机制,当内存空间不够用时,使用部分磁盘的空间交换到内存中暂用。

因为磁盘的访问速度远远不及内存,所以开启这个会降低集群的性能。我们可以通过在elasticsearch.yml文件中增加如下的配置:

bootstrap.memory_lock: true

是否锁住内存,避免交换(swapped)带来的性能损失,默认值是: false。设置完成后,需要重启ES。然后我们可以通过以下命令实时查看请求的输出中的 mlockall 值来查看是否成功应用了此设置。

GET _nodes?filter_path=**.mlockall

如果看到 mlockall 为 false ,则表示 mlockall 请求已失败。您还将在日志中看到一行包含更多信息的行,内容为“无法锁定 JVM 内存”。

利用doc values

关于什么是doc values,这个文章就不多讲了。我以前写过一篇专门的文章,感兴趣的可以看看这个:

一文带你彻底弄懂ES中的doc_values和fielddata

doc_values用来给文档建立正排索引,并且它是存储在磁盘的。虽然速度稍慢,doc_values的优势还是非常明显的。一个很显著的点就是他不会随着文档的增多引起OOM问题。正如前面说的,doc_values在磁盘创建排序和聚合所需的正排索引。这样我们就避免了在生产环境给ES设置一个很大的HEAP_SIZE,也使得JVM的GC更加高效,这个又为其它的操作带来了间接的好处。

所以 ES2.x 之后,支持聚合的字段属性默认都使用doc_values。实际项目中如果text字段需要支持聚合或者排序,可以显示的打开这个属性。

集群分配相关的属性

cluster.routing.allocation.cluster_concurrent_rebalance

这个属性允许控制群集范围内允许的并发分片重新平衡数。默认为2。请注意,此设置仅控制由于群集中的不平衡而导致的并发分片重定位数。我们应该关注这个值,不同的集群配置和业务场景应该考虑这个值的大小。大部分情况下这个小一些会有好处,这个也好理解,并发执行的分片数多了肯定会影响性能。

cluster.routing.allocation.disk.threshold_enabled

上面这个属性,表示的是ES可以根据磁盘使用情况来决定是否继续分配shard。默认设置是开启的(true)。

在开启的情况下,有两个重要的设置:

  • cluster.routing.allocation.disk.watermark.low:控制磁盘最小使用率。默认85%.说明es在磁盘使用率达到85%的时候将会停止分配新的shard。也可以设置为一个绝对数值,比如500M。

  • cluster.routing.allocation.disk.watermark.high:控制磁盘的最大使用率。默认90%.说明在磁盘使用率达到90%的时候es将会relocate shard去其他的节点。同样也可以设置为一个绝对值。

在某些场景下,有时候这个默认开启的值会比较保守,我们可以根据实际情况适当调整。

集群回复相关的一些属性

ES includes several recovery properties which improve both Elasticsearch cluster recovery and restart times. The value that will work best for you depends on the hardware you have in use (disk and network being the usual bottlenecks), and the best advice we can give is to test, test, and test again.

To control how many shards can be simultaneously in recovery on a single node, use:

cluster.routing.allocation.node_concurrent_recoveries

这个属性,控制多少个分片可以在单个节点上同时恢复。恢复分片是一个IO非常密集的操作,所以应当谨慎调整该值。默认值是2。

我之前看到过一个生产上的案例,作者为了加快集群的分片恢复速度,把这个值改成一个三位数,结果集群就卡死了。

To control the number of primary shards initialized concurrently on a single node, use:

cluster.routing.allocation.node_initial_primaries_recoveries

这个属性初始化数据恢复时,并发恢复线程的个数。一个未被分配的primary shard会在node重启之后使用本地磁盘上的数据,这个过程因为是使用本地的数据,因此会比较快,默认值是4.

indices.recovery.max_bytes_per_sec

这个是在有节点掉了,重新恢复的时候,各个节点之间的传输恢复速度。默认是40mb。如果你的网络环境配置比较高,可以适当的提高这个值。

上面的这几个参数都需要根据集群的硬件配置来决定合适的值,建议就是测试后再决定。

线程池属性防止数据丢失

threadpool.bulk.queue_size: 5000

这个属性用来提高批量操作线程池任务队列的大小。这个属性对于防止因批量重试而可能引起的数据丢失是极其关键的。

这个属性决定了当没有可用线程来执行一个批量请求时,可排队在该节点执行的分片请求的数量。该值应当根据批量请求的负载来设置。如果批量请求数量大于队列大小,就会得到一个下文展示的RemoteTransportException异常。

这个值如果设置的太高,会占用JVM的堆内存。设置的太小在并发量大的场景又容易引起异常。如果不处理该异常,将会丢失数据。


参考:

https://www.loggly.com/blog/nine-tips-configuring-elasticsearch-for-high-performance/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值