目录
red原因定位
排查过程
异常日志
分析
解决
red原因定位
es集群red是因为主分片异常(未分配)导致。此时该分片的数据已经不可以写入。该分片的读也不存在,所以此时可能会出现数据总量少了一个分片的情况。其他分片读写正常。
排查过程
GET _cluster/allocation/explain?pretty
查看具体某个索引,分片失败原因
异常日志
curl -XGET "http://0.0.0.0:9200/_cluster/allocation/explain?pretty"
{
"index" : "index_name",
"shard" : 9,
"primary" : true,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "ALLOCATION_FAILED",
"at" : "2022-02-09T17:19:27.134Z",
"failed_allocation_attempts" : 1,
"details" : "shard failure, reason [merge failed], failure NotSerializableExceptionWrapper[merge_exception: org.apache.lucene.index.CorruptIndexException: codec footer mismatch (file truncated?): actual footer=15794485 vs expected footer=-1071082520 (resource=BufferedChecksumIndexInput(MMapIndexInput(path="/mnt/storage00/esdata/nodes/0/indices/9Q1xXiIfTiezC_8-LN4_pA/9/index/_yh5b9.fdt")))]; nested: CorruptIndexException[codec footer mismatch (file truncated?): actual footer=15794485 vs expected footer=-1071082520 (resource=BufferedChecksumIndexInput(MMapIndexInput(path="/mnt/storage00/esdata/nodes/0/indices/9Q1xXiIfTiezC_8-LN4_pA/9/index/_yh5b9.fdt")))]; ",
"last_allocation_status" : "no_valid_shard_copy"
},
"can_allocate" : "no_valid_shard_copy",
"allocate_explanation" : "cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster"
}
curl -XGET "http://0.0.0.0:9200/_cluster/allocation/explain?pretty"
{
"index" : "index_name",
"shard" : 9,
"primary" : true,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "ALLOCATION_FAILED",
"at" : "2022-02-09T17:19:27.134Z",
"failed_allocation_attempts" : 1,
"details" : "shard failure, reason [merge failed], failure NotSerializableExceptionWrapper[merge_exception: org.apache.lucene.index.CorruptIndexException: codec footer mismatch (file truncated?): actual footer=15794485 vs expected footer=-1071082520 (resource=BufferedChecksumIndexInput(MMapIndexInput(path="/mnt/storage00/esdata/nodes/0/indices/9Q1xXiIfTiezC_8-LN4_pA/9/index/_yh5b9.fdt")))]; nested: CorruptIndexException[codec footer mismatch (file truncated?): actual footer=15794485 vs expected footer=-1071082520 (resource=BufferedChecksumIndexInput(MMapIndexInput(path="/mnt/storage00/esdata/nodes/0/indices/9Q1xXiIfTiezC_8-LN4_pA/9/index/_yh5b9.fdt")))]; ",
"last_allocation_status" : "no_valid_shard_copy"
},
"can_allocate" : "no_valid_shard_copy",
"allocate_explanation" : "cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster"
}
此刻可以先尝试 失败分片重试
POST /_cluster/reroute?retry_failed=true
大概率这个重试还是失败的。。。有可能成功,如果是一些node left的异常这种重试是可以成功的。
从异常日志来看,像是某些索引文件损坏。(索引文件损坏可能和磁盘坏道、linux系统异常、JVM虚拟机等异常引起)
此时可以尝试es自带的文件修复功能。(PS 注意这种修复会把异常的doc清除,存在丢数据的问题。)
可以参考这个:Corrupted elastic index - #5 by matw - Elasticsearch - Discuss the Elastic Stackmy instance of elasticsearch (5.6.1) stopped indexing because of the following error [2018-06-13T16:39:07,413][ERROR][o.e.i.e.InternalEngine$EngineMergeScheduler] [tracer-node-1] [tracer-default-logs-network-2018.06.13]…https://discuss.elastic.co/t/corrupted-elastic-index/135932/5
如果扫描后没发现文件损坏,可以尝试把异常分片下标记损坏的文件corrupted_*移动到另一个文件夹(相当于移除)再次尝试。
最终还是不能分片的话,只能尝试允许主分片为空 allocate_empty_primary的操作。这样会导致整个分片数据清空。(慎用)
此处再提一个架构设计方面的点,Es不能作为类似DB的稳定数据存储源,如果没有snapshot的es集群一定要支持数据重新同步,做好索引的幂等设计,索引拆分等。以防止出现es数据丢失出现无法补救的问题。
分析
看机器日志发现这个集群经常性的出现YELLOW,每次Yellow的报错基本都是类似的文件签名失败,或者空文件。然而我们的索引数据并不大,而且集群资源使用相对宽松,对比了另一个负载和数据量更高集群,发现他们基本没YELLOW,通过skywalk监控对比发现,问题集群refresh次数比另一个稳定集群的高很多,大概是10~100倍的样子。结合业务写入代码分析,发现是使用的spring-data-elasticSearch 低版本的save saveAll等方法 每次调用都会refresh导致refresh次数过多。大家知道每次es refresh都会刷新内存中的数据到文件缓存系统,是新数据可以被立即查询。触发一些merge。形成一个新的segment。虽然比flush消耗的资源少,但是频繁的refresh也会占用很多资源。es 索引的merge默认是1s触发一次。也能符合业务对数据实时性的要求。
解决
因此修改代码把save saveAll 这些写入操作统一改为bulk操作,观察监控refresh下来后。明显消失。关键错误日志也明显消失。
最后通过源码分析是refresh->flushAllThread()->生成segment->生成复合segment,会做源(segment)文件的完整性check,生成segment的filechannle和重新打开源(segment)文件的通道不是一个,refresh不符合flush的条件,文件未完整同步到磁盘,读取文件的通道可能由于某些原因(io延时,JVM bug,系统bug等)不能读取源(segment)的数据。导致该问题的出现。
参照以下issue,目前可以确定的是es 5.*、 6.* 的版本均存在改问题。https://github.com/elastic/elasticsearch/issues/40244https://github.com/elastic/elasticsearch/issues/40244



