故障排除损坏
edit故障排除损坏
editElasticsearch 期望从磁盘读取的数据与之前写入的数据完全一致。如果检测到磁盘上的数据与写入的数据不同,它将报告某种异常,例如:
-
org.apache.lucene.index.CorruptIndexException -
org.elasticsearch.gateway.CorruptStateException -
org.elasticsearch.index.translog.TranslogCorruptedException
通常这些异常是由于校验和不匹配引起的。大多数Elasticsearch写入磁盘的数据都会跟随一个使用简单算法(称为CRC32)计算的校验和,该算法计算速度快,并且擅长检测在使用故障存储时可能发生的随机损坏。CRC32校验和不匹配肯定表明某些地方出现了故障,尽管当然匹配的校验和并不能证明没有发生损坏。
验证校验和是昂贵的,因为它涉及读取文件的每个字节,这需要大量的工作,并且可能会将更有用的数据从文件系统缓存中驱逐出去,因此系统通常不会经常验证文件的校验和。这就是为什么你通常只在发生异常情况时才会遇到损坏异常。例如,损坏通常在合并、分片移动和快照期间被检测到。这并不意味着这些过程正在导致损坏:它们是读取整个文件是必要的罕见情况的例子。Elasticsearch利用这个机会同时验证校验和,这就是检测到并报告损坏的时候。它并不表明损坏的原因或发生的时间。损坏可能会在许多个月内未被检测到。
构成Lucene索引的文件是从头到尾依次写入的,并且之后不再被修改或覆盖。这种访问模式意味着校验和的计算非常简单,可以在文件最初写入时实时进行,同时也使得由于用户空间错误导致校验和不正确的可能性非常低。Elasticsearch中计算校验和的部分非常直接、广泛使用且经过充分测试,因此您可以非常确信,校验和不匹配确实表明从磁盘读取的数据与Elasticsearch之前写入的数据不同。
如果文件头损坏,那么Elasticsearch可能无法确定如何开始读取文件,这可能导致如下异常:
-
org.apache.lucene.index.IndexFormatTooOldException -
org.apache.lucene.index.IndexFormatTooNewException
如果Elasticsearch需要的文件完全丢失,它也可能报告损坏,并抛出如下异常:
-
java.io.FileNotFoundException -
java.nio.file.NoSuchFileException
构成Lucene索引的文件在可以使用之前会完整地写入。如果需要在重启后恢复索引时需要某个文件,那么您的存储系统之前已经向Elasticsearch确认该文件已持久同步到磁盘。在Linux上,这意味着fsync()系统调用成功返回。Elasticsearch有时会报告索引损坏,因为恢复所需的文件丢失,或者文件存在但已被截断或缺少其尾部。这可能表明您的存储系统错误地确认了持久写入。
有许多可能的原因导致Elasticsearch检测到集群中的损坏。像Elasticsearch这样的数据库会产生具有挑战性的I/O工作负载,这可能会发现其他测试可能忽略的细微基础设施问题。Elasticsearch已知会以下列问题暴露为文件损坏:
- 文件系统错误,特别是在较新且非标准的文件系统中,这些文件系统可能没有经过足够的实际生产使用,无法确信它们能正常工作。
- 内核错误。
- 在驱动器或RAID控制器上运行的固件中的错误。
-
配置错误,例如在所有持久写入完成之前配置
fsync()报告成功。 - 故障硬件,可能包括驱动器本身、RAID控制器、您的RAM或CPU。
- 修改Elasticsearch写入文件的第三方软件。
数据损坏通常不会导致其他问题的证据,除了校验和不匹配。不要将此解释为您的存储子系统工作正常的指示,因此认为Elasticsearch本身导致了损坏。有问题的存储很少会显示除数据损坏之外的任何问题的证据,但数据损坏本身是一个非常强烈的指示,表明您的存储子系统没有正常工作。
为了排除 Elasticsearch 作为数据损坏的来源,使用除 Elasticsearch 之外的工具生成 I/O 负载,并查找数据完整性错误。在 Linux 上,fio 和 stress-ng 工具都可以生成具有挑战性的 I/O 负载,并验证它们写入的数据的完整性。使用 0.12.01 或更新版本的 stress-ng,因为早期版本没有足够强的完整性检查。使用类似于 diskchecker.pl 的脚本来验证持久写入在断电后是否仍然存在。或者,使用 strace 等工具观察 Elasticsearch 在写入数据时进行的系统调用序列,并确认该序列不会解释报告的损坏。
为了缩小损坏源的范围,系统地更改集群环境中的组件,直到损坏停止。具体细节将取决于您的环境的确切配置,但可能包括以下内容:
- 尝试使用不同的文件系统或不同的内核。
- 依次尝试更换每个硬件组件,理想情况下更换为不同型号或制造商的组件。
- 尝试为每个硬件组件使用不同的固件版本。
- 移除任何可能修改Elasticsearch数据路径内容的第三方软件。