ES shards达到上限引起应用日志停写

一、前言

 

     在Elasticsearch(ES)中,索引(index)是数据的逻辑集合,而分片(shard)是索引的物理分割。每个索引可以被分为多个分片,这些分片被分布在不同的节点上,从而提供了数据的并行处理和高可用性。索引和分片之间的关系是一对多的关系。

      针对这个问题而言,如果logback将maxDocs设置为一个很小的值,可能会导致同一个索引创建大量的分片。这是因为 Elasticsearch 在默认情况下会自动为每个索引分配一个主分片。当maxDocs很小时,Elasticsearch 将会频繁地滚动(rollover)索引,即创建新的分片来存储新的文档。

      滚动索引是为了处理索引中的大量文档而设计的机制,它通常在索引达到一定大小或文档数量时触发。然而,如果maxDocs设置得非常小,那么每写入maxDocs个文档,就会滚动并创建一个新的分片,这样会导致大量的分片被创建。

      而我们知道,ES对于每个节点的shards是存在限制的,默认是每个节点1000。

      如果shards达到上限,就会引发类似如下的报错:this action would add [10] total shards, but this cluster currently has [999]/[1000] maximum shards open; 此时ES停止写入。

      首先,我承认这属于产品的缺陷,并希望在后续版本更新时,项目组同步更新到我们已修复的镜像版本。但是针对目前的情况,我也提供一种手动解决这个问题的办法。

二、解决办法

 

      此时为了恢复写入我们需要做以下两个操作中的一个:

  • 删除部分log_run的索引,如: DELETE /log_run-2023-08*
  • 增加节点或者调大单节点的最大shards,增加节点此处不解释,增加shards可以rest调用ES如下接口:
 # PUT方法
_cluster/settings
{
"transient": {
"cluster": {
"max_shards_per_node": 1500
}
}
}

      但是此时只是恢复了ES的写入,问题并未得到根本解决,你需要在GeoSmarter服务器执行如下shell脚本:

#!/bin/bash
#
DockerRootDir=$(docker info --format='{{json .DockerRootDir}}' | sed 's/"//g')
# 遍历查找docker数据目录找到名为logback.xml且路径中包含merged的文件
find $DockerRootDir -type f -name "logback.xml" -path "*merged*" | while read -r file; do
# 替换文件中的7为100000
sed -i 's/<maxDocs>7<\/maxDocs>/<maxDocs>100000<\/maxDocs>/g' "$file"
done
#
docker restart $(docker ps -aq)
posted @ 2024-02-21 16:28  陶清刚  阅读(53)  评论(0)    收藏  举报