個別のストレージ システム間(たとえば、複数の Apache Hadoop 分散ファイル システム(HDFS)クラスタ間)や、HDFS と Cloud Storage の間でデータをコピーまたは移動する際は、データの整合性を保証するために、なんらかの検証を行うことをおすすめします。データが転送中に変更されていないことを確認するには、こうした検証が不可欠です。
さまざまなメカニズムによって、転送中のポイントツーポイントのデータ整合性がすでに保証されていますが(Cloud Storage とのすべての通信で TLS が使用されるなど)、明示的なエンドツーエンドのデータの整合性検証を行うことによって、通常の転送メカニズムでは検出されないようなケースに対しても保護が追加されます。これは、ノイズの多いネットワーク リンク、データの転送経路上にあるサーバー コンピュータやルーターのメモリエラー、ソフトウェアのバグ(お客様が使用するライブラリなど)などによって起こりかねないデータ破損を検出するのに役立ちます。
Cloud Storage では、cp
や rsync
などの Google Cloud CLI コマンドを使用する際に、この検証がクライアント側で自動的に行われます。これらのコマンドでは、ローカル ファイルのチェックサムが計算されます。その後、各オペレーションの最後にこのチェックサムと Cloud Storage によって計算されたチェックサムとの間で検証が行われます。チェックサムが一致しない場合、gcloud CLI は無効なコピーを削除し、警告メッセージを出力します。この不一致はめったに起こりません。発生した場合はオペレーションを再試行できます。
HDFS や Cloud Storage などの異種の Hadoop 互換ファイル システムをまたいで、Apache Hadoop でエンドツーエンドのクライアント側の検証を自動的に実行する方法もあります。この記事では、新機能によってファイルのチェックサムを効率的かつ正確に比較する方法について説明します。
HDFS によるファイル チェックサムの実行方法
HDFS では、Castagnoli 多項式に基づく 32 ビットの巡回冗長検査(CRC)である CRC32C を使用して、さまざまなコンテキストでデータの整合性を維持します。
- データが静止しているときに、Hadoop DataNode はデータと保存されている CRC を継続的に検証し、ビット劣化を検出して修復します。
- データ転送時に、DataNode は対応するバルクデータとともに既知の CRC を送信します。HDFS クライアント ライブラリはこれと連携してチャンクごとの CRC を計算し、DataNode から受信した CRC と比較します。
- HDFS の管理目的では、DataNode 上の個々のブロック ファイルに対して低レベルの手動の整合性チェックを行うために、ブロックレベルのチェックサムが使用されます。
- 任意のアプリケーション層のユースケースでは、
FileSystem
インターフェースによってgetFileChecksum
が定義されます。HDFS の実装では、保存されている詳細な CRC を使用してファイルレベルのチェックサムが定義されます。
日々のほとんどの使用では、CRC はアプリケーション層に関して透過的に使用されます。使用される唯一の CRC はチャンクごとの CRC32C です。これは、事前計算されてブロックデータとともにメタデータ ファイル内に保存されます。チャンクサイズは dfs.bytes-per-checksum
によって定義され、デフォルト値は 512 バイトです。
Hadoop のデフォルトのファイル チェックサム タイプの欠点
Hadoop を使用する場合、デフォルトでは、すべての公開される API のチェックサムは、チャンクの CRC32C を連結した MD5 の形式を取ります。これは、ブロックレベルでは低レベルの DataTransferProtocol
を通じて、ファイルレベルでは最上位の FileSystem
インターフェースを通じて提供されます。ファイルレベルのチェックサムは、すべてのブロック チェックサムを連結した MD5 として定義されます。各ブロック チェックサムはチャンクの CRC を連結した MD5 であるため、MD5MD5CRC32FileChecksum
と呼ばれます。これは事実上、オンデマンドの 3 層 Merkle ツリーです。
ファイルレベルのチェックサムのこの定義は、HDFS の実装とデータ レイアウトの詳細、つまりチャンクサイズ(デフォルトでは 512 バイト)とブロックサイズ(デフォルトでは 128 MB)に左右されます。したがって、このデフォルトのファイル チェックサムは、次のような状況には適していません。
- HDFS 内の同じファイルの 2 つのコピー。ただし、ファイルごとのブロックサイズの構成が異なっている。
- ブロックサイズまたはチャンクサイズの構成が異なっている 2 つの HDFS インスタンス。
- HDFS と、Cloud Storage などの HDFS 以外の Hadoop 互換ファイル システム(HCFS)の組み合わせ。
次の図は、ファイル システムの構成によって、同じファイルのチェックサムが異なる状況を示しています。
Hadoop の fs -checksum
コマンドを使用して、HDFS 内のファイルのデフォルト チェックサムを表示できます。
hadoop fs -checksum hdfs:///user/bob/data.bin
ブロックサイズが 64 MB(dfs.block.size=67108864
)の HDFS クラスタでは、このコマンドは次のような結果を表示します。
hdfs:///user/bob/data.bin MD5-of-131072MD5-of-512CRC32C 000002000000000000020000e9378baa1b8599e50cca212ccec2f8b7
ブロックサイズが 128 MB(dfs.block.size=134217728
)の別のクラスタ内に同じファイルがある場合、出力結果は異なります。
hdfs:///user/bob/data.bin MD5-of-0MD5-of-512CRC32C 000002000000000000000000d3a7bae0b5200ed6707803a3911959f9
これらの例から、2 つの同じファイルでチェックサムが異なることがわかります。
Hadoop の新しいコンポジット CRC ファイル チェックサムの仕組み
これらの欠点に対処するために、HDFS-13056 で追跡されている新しいチェックサムのタイプが Apache Hadoop 3.1.1 でリリースされました。この新しいタイプは dfs.checksum.combine.mode=COMPOSITE_CRC
によって構成され、新しいコンポジット ブロック CRC とコンポジット ファイル CRC を、格納されているチャンクの CRC 全体にわたって数学的に構成された CRC として定義します。チャンク CRC の低レベルの粒度に依存しない、ブロック全体またはファイル全体を表す単一の CRC を計算する場合において、このタイプはコンポーネント CRC の MD5 の使用に代わるものです。
CRC のコンポジションには多くの利点があります。まず、効率的です。また、生成されるチェックサムを完全にチャンクやブロックに依存しないようにすることができます。さらには、ストライプ化ファイルや複製ファイル間、異なる HDFS インスタンス間、HDFS と他の外部ストレージ システム間の比較も可能です(こちらの PDF をダウンロードして、CRC アルゴリズムに関する詳細を学ぶことができます)。
次の図は、異種ファイル システム構成間での転送後に、ファイルのチェックサムの整合性がどのように保たれるかを示しています。
この機能の影響は最小限です。既存のブロック メタデータと互換性を維持しながら追加可能であり、通常のチャンク検証パスを変更する必要はありません。つまり、既存の大規模な HDFS デプロイメントであっても、この機能を採用して、過去に遡ってデータを同期することが可能であることを意味します。詳細については、PDF の全文をダウンロードしてご確認ください。
新しいコンポジット CRC チェックサム タイプの使用
Hadoop 内で新しいコンポジット CRC チェックサム タイプを使用するには、dfs.checksum.combine.mode
プロパティをデフォルト値の MD5MD5CRC
ではなく、COMPOSITE_CRC
に設定します。ファイルをある場所から別の場所にコピーするときは、チャンクレベルのチェックサム タイプ(dfs.checksum.type
プロパティによって指定、デフォルトは CRC32C
)も両方の場所で一致する必要があります。
HDFS 内のファイルの新しいチェックサム タイプを表示するには、Hadoop の fs -checksum
コマンドに引数 -Ddfs.checksum.combine.mode=COMPOSITE_CRC
を渡します。
hadoop fs -Ddfs.checksum.combine.mode=COMPOSITE_CRC -checksum hdfs:///user/bob/data.bin
HDFS クラスタのブロックサイズの構成に関係なく、次のように同じ出力が表示されます。
hdfs:///user/bob/data.bin COMPOSITE-CRC32C c517d290
Cloud Storage の場合は、Cloud Storage コネクタの fs.gs.checksum.type
プロパティも明示的に CRC32C
に設定する必要があります。こうしないと、このプロパティはデフォルトの NONE
に設定され、ファイル チェックサムはデフォルトで無効になります。Cloud Storage コネクタによるこのデフォルトの動作は、チェックサム タイプが不一致の場合に安全に失敗するのではなく例外が発生するという distcp
の問題を回避するための予防策です。コマンドは次のようになります。
hadoop fs -Ddfs.checksum.combine.mode=COMPOSITE_CRC -Dfs.gs.checksum.type=CRC32C -checksum gs://[BUCKET]/user/bob/data.bin
このコマンドは、前の HDFS の例と同じ出力を表示します。
gs://[BUCKET]/user/bob/data.bin COMPOSITE-CRC32C c517d290
これらのコマンドで返されるコンポジット CRC チェックサムは、ブロックサイズに関係なく一致し、HDFS と Cloud Storage の間でも一致することがわかります。コンポジット CRC チェックサムを使用することで、あらゆるタイプの Hadoop クラスタ構成間でファイルを転送するときに、データの整合性が維持されることを保証できます。
次の例のように distcp
を実行する場合、検証は自動的に実行されます。
hadoop distcp -Ddfs.checksum.combine.mode=COMPOSITE_CRC -Dfs.gs.checksum.type=CRC32C hdfs:///user/bob/* gs://[BUCKET]/user/bob/
コピー中に distcp
がコピー元とコピー先のファイルのチェックサムの不一致を検出すると、オペレーションは失敗して警告を返します。
この機能へのアクセス
新しいコンポジット CRC チェックサム機能は、Apache Hadoop 3.1.1 で利用可能です(リリースノートを参照)。バージョン 2.7、2.8、2.9 へのバックポートは現在作業中です。2018 年後半から、Cloud Dataproc 1.3 のサブマイナー バージョンにはデフォルトで含まれています。