【摘要】Elasticsearch除了静态配置以外,还存在可灵活调整的动态配置,在日常运维,排障,优化等场景下使用较为频繁。本篇从集群、索引GC等方面对部分Elasticsearch的动态配置参数进行讲解,帮助大家灵活运用。【作者】搁浅沉默 某金融行业技术研发专员
一、引言
笔者在今年4月份写过一篇文章,对Elasticsearch的静态配置文件进行一个简单的介绍,包括常用的参数,及其为什么如此设置(点击可阅读:某银行日志平台Elasticsearch运维静态配置篇)。对于Elasticsearch而言,除了静态配置以外,还存在可灵活调整的动态配置,此类配置在日常运维,排障,优化等场景下使用较为频繁。
本篇将会从集群,索引GC等方面对部分Elasticsearch的动态配置参数进行一个简单介绍,告诉大家,如何调整配置,可以使得Elasticsearch集群更为健壮;遇到分片不均衡的场景,如何通过配置进行rebalance;如何调整索引的配置,可优化数据读写能力等,希望对阅读本篇文章的人有所帮助与启发。二、集群级别分片相关配置
1.cluster.routing.allocation.enable
Elasticsearch 中用于控制分片分配行为的一个集群级别的设置。它决定了集群在不同条件下是否允许分片的分配和重新分配。这一设置主要用于维护操作期间(例如节点下线、扩展、故障恢复)控制分片分配策略。
all(默认值):允许所有分片(包括主分片和副本分片)的分配。这是默认配置,表示分片可以正常分配到可用的节点上。
primaries:只允许主分片的分配,不允许副本分片分配。当集群处于部分恢复状态时,此配置可以确保主分片优先恢复。
new_primaries:只允许尚未分配的主分片进行分配,用于在发生灾难性故障时控制分片的分配行为。
none:不允许分片的分配或重新分配。常用于维护操作期间,如升级或维护特定节点时,防止分片的自动重新分配。
设置示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "none"
}
}
2.cluster.routing.allocation.cluster_concurrent_rebalance
用于控制集群中允许并发进行的分片重平衡(rebalance)操作的最大数量。默认值为2,使用场景如下:
集群扩展:当添加新节点时,Elasticsearch可能会触发分片重平衡操作。通过控制 cluster.routing.allocation.cluster_concurrent_rebalance,可以限制同时进行的分片重平衡任务的数量,从而避免集群在短时间内进行大量的分片迁移,影响查询和索引性能。
恢复节点后:在节点恢复后,Elasticsearch可能会启动分片的重新分配和同步。过多的重平衡任务会占用大量I/O和CPU资源,从而影响正常的操作。此时,可以调低该参数以限制重平衡操作的数量。
示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.cluster_concurrent_rebalance": 3
}
}
3. cluster.routing.allocation.node_initial_primaries_recoveries
用于控制每个节点在启动时同时恢复的主分片(primary shard)的最大数量。当一个节点加入集群或重启时,Elasticsearch会自动将存储在该节点上的主分片恢复到活动状态。然而,过多的分片恢复操作可能会给系统带来较大的 I/O负载,特别是在节点启动或故障恢复期间。因此,该参数用于限制每个节点同时恢复的主分片数量,防止系统性能下降。默认值为4,使用场景如下:
示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.node_initial_primaries_recoveries": 3
}
}
4. cluster.routing.allocation.node_concurrent_recoveries
控制每个节点同时进行的分片恢复操作的最大数量。这包括从其他节点恢复主分片和副本分片。此参数可以防止分片恢复时对节点的I/O和网络资源造成过多负载,从而影响集群的整体性能。默认值为2,使用场景如下:
示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.node_concurrent_recoveries": 3
}
}
5.cluster.routing.allocation.node_concurrent_outgoing_recoveries
用于控制每个节点同时进行的出站分片恢复操作的最大数量。这一参数具体影响的是当节点将分片数据复制到其他节点时,每个节点上允许并发的出站恢复(outgoing recovery)的数量。默认值为2,使用场景如下:
副本分片分配:当 Elasticsearch 集群需要将分片副本分配到新节点时,源节点会通过出站恢复将分片数据发送到目标节点。
节点重新加入集群:如果节点重启或加入集群,源节点需要将分片数据传输给其他需要恢复数据的节点。
如果硬件资源(如网络带宽和磁盘 I/O)充足,且需要更快地将分片恢复到其他节点,可以增加该值至 4-6。尤其是在集群扩展或需要快速恢复大量分片时,此调整有助于加快恢复速度。
示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.node_concurrent_outgoing_recoveries": 3
}
}
6. cluster.routing.allocation.allow_rebalance
用于控制集群何时允许进行分片重平衡(shard rebalancing)。分片重平衡是指在集群节点间重新分配现有分片,以确保数据均衡分布和集群性能的稳定性。然而,频繁的分片重平衡会导致不必要的开销,影响查询和写入的性能。
默认值:always,使用场景如下:
可选值如下:
always:集群始终允许分片重平衡。适用于不太敏感的集群环境,确保集群始终保持分片分布均衡。
indices_primaries_active:只有在所有主分片都处于活动状态时才允许分片重平衡。
indices_all_active:只有当所有主分片和副本分片都处于活动状态时才允许重平衡。
示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.allow_rebalance": "indices_primaries_active"
}
}
三、GC (垃圾回收) ,内存配置
1. indices.memory.index_buffer_size
决定了在索引过程中,每个节点可以为索引操作分配的内存缓冲区大小。该缓冲区用于暂时存放待写入磁盘的数据,特别是倒排索引、文档值等结构,缓冲区满时会触发刷盘(flush)操作,将数据从内存写入磁盘中的段文件,默认值为10%的JVM堆内存。使用场景如下:
高并发索引操作:在大规模数据索引或高并发写入场景下,增大索引缓冲区可以减少刷盘频率,从而提高写入性能。但过大的缓冲区也可能导致内存占用过多,影响搜索性能和其他操作的响应。
资源有限的场景:如果内存资源有限,可能需要减小缓冲区大小,以确保有足够的内存分配给其他操作,防止JVM内存不足或垃圾回收频繁触发。
示例:
PUT /_cluster/settings
{
"persistent": {
"indices.memory.index_buffer_size": "15%"
}
}
2. indices.memory.min/max_shard_index_buffer_size
min_shard_index_buffer_size:
用于为每个分片在写入操作时设置一个最小/最大的索引缓冲区大小。min_shard_index_buffer_size这个参数控制每个分片在进行索引操作时,可以使用的最小内存量。当Elasticsearch为节点分配内存缓冲时,如果index_buffer_size参数计算出的每个分片的内存分配低于这个最小值,Elasticsearch会强制分配这个最小内存。默认值为4mb,使用场景如下:
确保索引性能:在节点上有很多小分片的场景中,如果每个分片分配的内存缓冲区过小,可能会导致频繁的刷盘(flush),降低索引性能。因此,设置一个合理的最小缓冲区大小可以避免这种情况,确保分片有足够的内存来进行批量写入操作。
小型集群或低内存环境:在内存较为有限的环境中,可能需要调整这个参数以确保分片有足够的内存分配,而不会因为缓冲区过小导致过多的刷盘操作。
示例:
PUT /_cluster/settings
{
"persistent": {
"indices.memory.min_shard_index_buffer_size": "8mb"
}
}
max_shard_index_buffer_size:
决定了每个分片可以分配的最大内存索引缓冲区大小。这个参数用来控制在索引操作过程中,单个分片能使用的最大缓冲区量,防止某个分片占用过多内存资源,影响其他分片或操作。默认值为512mb,使用场景如下:
防止单个分片占用过多资源:在一些高写入负载的场景中,如果不设置该上限,某些分片可能会使用非常大的缓冲区,从而影响其他分片的写入和查询性能。因此,这个参数可以确保资源合理分配,防止单个分片占用过多内存。
大规模索引写入:对于一些大索引(例如TB级数据量),适当调整max_shard_index_buffer_size,以平衡分片的内存使用和刷盘频率。增大缓冲区可能有助于减少刷盘次数,提高写入效率。
示例:
PUT /_cluster/settings
{
"persistent": {
"indices.memory.max_shard_index_buffer_size": "1gb"
}
}
3. indices.breaker.total.limit
用于设置 内存断路器(memory circuit breaker)的总内存限制,帮助防止节点在超出可用内存时发生内存溢出或崩溃。该参数控制Elasticsearch为各类操作(如索引、聚合、排序等)分配的总内存上限。默认值为95%的 JVM 堆内存。
工作机制:
Elasticsearch中的内存断路器系统用于防止节点由于内存超负荷而崩溃。当内存使用超过某个限制时,内存断路器会中断当前操作并抛出异常。是一个总开关,控制Elasticsearch所有内存断路器的总体内存限制。
内存断路器通常应用于以下几种场景:
示例:
PUT /_cluster/settings
{
"persistent": {
"indices.breaker.total.limit": "70%"
}
}
4. indices.breaker.fielddata.limit
用于为字段数据(fielddata)的内存使用设置限制。它决定了Elasticsearch加载字段数据到内存时可以使用的最大内存量。字段数据主要用于内存密集型操作,比如排序、聚合和脚本过滤等。此参数通过内存断路器(circuit breaker)防止字段数据过多地占用堆内存,进而保护集群稳定性。默认值为JVM堆内存的40%。
示例:
PUT /_cluster/settings
{
"persistent": {
"indices.breaker.fielddata.limit": "30%"
}
}
5. indices.breaker.request.limit
用于限制单个查询请求能够使用的最大内存。它决定了每个查询操作(例如聚合、排序等)能分配的内存上限,以防止单个查询耗尽过多内存资源,从而保护集群稳定性。默认值为JVM堆内存的60%。
示例:
PUT /_cluster/settings
{
"persistent": {
"indices.breaker.request.limit": "50%"
}
}
四、协调相关配置
1.cluster.publish.timeout
用于设置集群状态变更(如节点加入、离开、分片重新分配等)在发布给集群中的所有节点时的超时时间。这个参数直接影响到集群在执行状态变更操作时的容错能力和响应时间。默认值为30s,使用场景如下:
增大超时时间:如果你有较大的集群,或者网络状况不稳定,主节点可能需要更多的时间等待所有节点确认集群状态变更。在这种情况下,可以将该值增大到60s或更长的时间,以确保变更能够成功传播到所有节点。
减少超时时间:在某些环境中,为了减少主节点在网络异常时的等待时间,可以将该超时时间缩短。如果网络较差且超时时间过长,主节点可能会花费较长时间去尝试发布变更,影响集群的响应速度。缩短超时时间可以使主节点更快地处理这些失败情况。
示例:
PUT /_cluster/settings
{
"persistent": {
"cluster.publish.timeout": "60s"
}
}
五、结语
本篇主要介绍了Elasticsearch集群的部分动态配置参数情况,一家之言,仅供参考。
觉得本文有用,请转发或点击“在看”,让更多同行看到
欢迎关注社区 "数据库"技术主题 ,将会不断更新优质资料、文章。地址:
https://www.talkwithtrend.com/Channel/597/
下载 twt 社区客户端 APP
长按识别二维码即可下载
或到应用商店搜索“twt”
*本公众号所发布内容仅代表作者观点,不代表社区立场