データ破損のトラブルシューティング

Elasticsearchは、ディスクから読み取るデータが以前に書き込んだデータと正確に一致することを期待しています。ディスク上のデータが書き込んだものと異なることを検出した場合、次のような例外を報告します:

  • 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ワークロードを生成し、書き込むデータの整合性を検証できます。stress-ngのバージョン0.12.01以降を使用してください。以前のバージョンは十分な整合性チェックを持っていません。電源障害の間に耐久性のある書き込みが持続することを確認するために、diskchecker.plのようなスクリプトを使用します。あるいは、straceのようなツールを使用して、Elasticsearchがデータを書き込む際に行うシステムコールのシーケンスを観察し、このシーケンスが報告された破損を説明しないことを確認します。

破損の原因を特定するために、クラスターの環境内のコンポーネントを体系的に変更し、破損が停止するまで続けます。詳細は環境の正確な構成によって異なりますが、次のようなことが含まれる場合があります:

  • 別のファイルシステムまたは別のカーネルを試してみてください。
  • 各ハードウェアコンポーネントを順番に変更し、理想的には異なるモデルまたはメーカーに変更します。
  • 各ハードウェアコンポーネントの異なるファームウェアバージョンを試してください。
  • Elasticsearchデータパスの内容を変更する可能性のあるサードパーティ製ソフトウェアを削除します。