记一次Elasticsearch节点状态red的整改过程

问题起因

自己负责审计日志模块的管理功能,同事突然对我说,写入的日志数据全部不能用了,我立即答复(回怼)“不可能”。
说罢,还是去登录系统查看,能查出数据,只是偶现查询速度特别慢,看控制台,原因是部分请求一直挂起直到超时。
于是登录服务器查看日志,好家伙,果然报错了。

{
    
    
	"took":60000,
	"errors":true,
	"items":[
		{
    
    
			"index":{
    
    
				"_index":"xxx",
				"_type":"xxx",
				"_id":"ohNNCIABQ5H_8lZrABim",
				"status":503,
				"error":{
    
    
					"type":"unavailable_shards_exception",
					"reason":"[xxx][4] primary shard is not active Timeout: ..."
				}
			}
		}
	]
}

查询挂起,和写入日志数据失败,均为该错误引起,这哪能忍,直接开干。

Round 1

错误原因也写的很清楚了,主分片不可用
于是查看集群健康状态

//request
{
    
    {
    
    host}}/_cat/indices

//response
{
    
    
    "error": {
    
    
        "root_cause": [
            {
    
    
                "type": "security_exception",
                "reason": "current license is non-compliant for [security]",
                "license.expired.feature": "security"
            }
        ],
        "type": "security_exception",
        "reason": "current license is non-compliant for [security]",
        "license.expired.feature": "security"
    },
    "status": 403
}

淦,第一反应就是之前加入X-Pack插件时,说过该插件需要付费证书来授权,第一次申请可以免费试用一个月,到期后部分功能会受限。
经过一番查阅资料,得到结果需要如下操作方可接触限制:

1、到Elasticsearch官方申请免费证书;
2、将证书PUT到受限的服务器以将到普通版本;
该方法也就是放弃使用X-Pack的安全功能,回退到普通功能。

于是又是一顿如虎的操作

//申请并下载好证书
{
    
    
	"license":{
    
    
		"uid":"xxx",
		"type":"basic",
		"issue_date_in_millis":1649376000000,
		"expiry_date_in_millis":1680998399999,
		"max_nodes":100,
		"issued_to":"hoew",
		"issuer":"Web Form",
		"signature":"xxx",
		"start_date_in_millis":1649376000000
	}
}

//将证书PUT到受限服务器
{
    
    {
    
    host}}/_xpack/license' -d @my.json

//却得到如下结果
{
    
    
    "error": {
    
    
        "root_cause": [
            {
    
    
                "type": "illegal_argument_exception",
                "reason": "Installing basic licenses is no longer allowed. Use the POST /_xpack/license/start_basic API to install a basic license that does not expire."
            }
        ],
        "type": "illegal_argument_exception",
        "reason": "Installing basic licenses is no longer allowed. Use the POST /_xpack/license/start_basic API to install a basic license that does not expire."
    },
    "status": 400
}

看起来就是PUT /_xpack/license方法已经废弃了,需要使用POST /_xpack/license/start_basic方法来进行。那还等什么呢,改了调用呗。

Round 2

经过上回合的折腾,总算把证书问题解决了,这下再次调用GET /_cat/indices得到如下信息

red		open xxx xxx 5 0        0       0   1.2kb   1.2kb
red		open xxx xxx 5 0     3975       0   4.7mb   4.7mb
yellow	open xxx xxx 5 0        0       0   1.2kb   1.2kb
...

总之就是好一片红黄交错的胜景,那我们进一步看看是什么原因导致节点的健康状态为red/yellow,于是我们看具体的分片情况

//请求分片情况
GET {
    
    {
    
    host}}/_cat/shards

//得到如下响应
xxx                     1 p STARTED		367523  60.4mb 10.240.50.103 node-1
xxx                     3 p UNASSIGNED  366494  60.1mb 10.240.50.103 node-1
...

说明这些不健康索引的分片没有都启动起来。当时因为天气炎热,到这步有点冲昏头脑了,折腾了好久,最后突然想到之前该服务器启动ES的时候报存储空间不足,于是思考有没可能是因为存储空间满了导致的呢。
查看错误原因GET { {host}}/_cluster/allocation/explain,得到如下错误信息

cannot allocate because allocation is not permitted to any of the nodes 

于是尝试清除服务器空间

-rw-r--r--. 1 mysql    mysql 14514122752 Dec 30 09:28 mysqld.log

这也日志文件也忒大了,于是将该日志备份到其他未满的分区后,将该日志文件清空。
其实后来据非官方信息了解到,当剩余空间小于10%时,分片无法成功启动。
再次重启ES,以为胜利的曙光已经在召唤了,哪成想…

Round 3

节点还是一片红黄交错,这次强行清醒了,虽然现象一样,但原因可能不一样,于是再次查看错误原因

failed shard on node [xxx]: failed recovery, failure RecoveryFailedException[[xxx][1]: Recovery failed on {
    
    node-1}{
    
    xxx}{
    
    xxxlA}{
    
    x.x.x.x}{
    
    x.x.x.x:9300}{
    
    ml.machine_memory=25334550528, xpack.installed=true, ml.max_open_jobs=20, ml.enabled=true}]; nested: IndexShardRecoveryException[failed to recover from gateway]; nested: AccessDeniedException[/xx/elasticsearch/data/nodes/0/indices/xxx/1/index/_23b.fdt]; 

好家伙,访问拒绝,熟悉的味道啊。但怎么产生的呢,脑海中立马想到原因可能是之前有一次启动时用的是root用户造成的。
于是立马去看这个受限文件的权限信息,果不其然,属于root用户

//xx为你的es用户
chown -R xx:xx /xx/elasticsearch/data

走你,翻滚吧,阿信!不好意思,串词了。运行完成后,所有数据文件都具有访问权限了,于是再次重启ES…

Round 4

既然看到了第四回合,那你已经知道,前面的battle都没能彻底解决掉我们的问题,但这里有个小小惊喜的是,red状态的索引都已经没了,现在只剩下yellow状态的了,也就是说截止目前,我们的功能已经是能正常使用了。
于是赶紧让文章开头的那个同事(问题源)来重试,果然,他没有再哔哔了。可本着本农追根溯源的优良精神,怎么能止步于此,我一定要让所有索引都是green才行!
那么还是进一步查看问题原因

the shard cannot be allocated to the same node on which a copy of the shard already exists [[xxx][3], node[xxx], [P], s[STARTED], a[id=xxx]]

错误信息也很明显,就是分片副本不能和分片本身分配到同样的节点上。但这个问题刚开始还是迷惑了我,因为我以为分片多的情况可能刚启动时没分配过来,于是准备通过

index.unassigned.node_left.delayed_timeout

参数来延时分配这些未被分配的分片。
一番操作下来,错误信息不断地变,但是结果却始终没有好转,终于当错误产生循环后,终于意识到方向不对了。
这里补充个小知识,ES的分片副本肯定要和分片本身要分配到不同的节点的,也就说每个主分片的副本数要少于群集中的节点数,也就是我们熟知的NR公式

//N代表节点数,R代表所有索引的最大分片复制因子
N >= R + 1

于是我只需要将副本数量进行控制即可

number_of_replicas

一番操作后,总算一片green了

总结

查资料的过程中,还看到有解决办法让哪个索引为yellow/red直接将该索引DELETE即可。WTF?如果解决不了问题就解决提出问题的人吗?
其实总结下来就一句话,遇事不着急,细细看日志,万事必有因,逐破自搞定!(强行银湿一手[doge])

猜你喜欢

转载自blog.csdn.net/aa54682002/article/details/124047858