Hadoop 分散ファイルシステム (HDFS) へデータを書き込む際に、DataNode の過負荷によりファイルの閉じ処理に失敗することがあります。本トピックでは、この問題の根本原因を特定・診断し、解決する方法について説明します。
エラーメッセージ
java.io.IOException: Unable to close file because the last block xxx:xxx does not have enough number of replicas.
原因
DataNode への書き込み負荷が高すぎると、データブロックのレポートがタイムリーに行われなくなります。HDFS がブロックのレプリカ数が十分であることを確認できない場合、ファイルの閉じ処理に失敗します。
診断と解決
以下のチェック項目を順に実施してください。原因が特定された時点で、以降の手順は実施する必要はありません。
ステップ 1:リトライパラメーターの調整
hdfs-site.xml タブで、dfs.client.block.write.locateFollowingBlock.retries の値を確認します。このパラメーターは、データブロックの書き込み後にクライアントがファイルの閉じ処理を試行する回数を制御します。
| 設定 | 値 |
|---|---|
| デフォルト | 5 回(30 秒以内) |
| 推奨値 | 8 回(2 分以内) |
中程度の負荷がかかるクラスターでは、このパラメーターを 8 に設定してください。負荷が継続的に高いクラスターでは、さらに値を増加させることを検討してください。
この値を増加させると、ノードがビジー状態の際、ファイルを閉じるまでの待機時間が延長されます。ただし、データの書き込み処理自体には影響しません。
ステップ 2:DataNode とタスクノードの比率の確認
クラスターの DataNode 数が少なく、タスクノード数が多い場合、かつ多数のジョブが同時に送信されると、大量の JAR ファイルのアップロードが必要となり、DataNode に過大な負荷がかかる可能性があります。
この問題を解決するには、以下のいずれかの対応を行ってください:
-
dfs.client.block.write.locateFollowingBlock.retriesの値を増加させます。 -
書き込み負荷を分散させるため、コアノード(DataNode)を追加します。
ステップ 3:多数の小ファイルを生成するジョブの確認
特定のワークロードでは、HDFS 上に不均衡に多くの小ファイルが作成されることがあります。Flink のチェックポイントはその代表例であり、各チェックポイントで多数の小ファイルが作成・削除されるため、DataNode に大きな負荷がかかります。
この現象が原因である場合は、以下のいずれかの対応をご利用ください:
-
Flink を、専用の独立クラスター上で実行し、そのクラスターに独自の HDFS を構築することで、チェックポイント処理が共有クラスターに影響を与えないようにします。
-
HDFS の代わりに、Object Storage Service (OSS) または OSS-HDFS コネクターを Flink のチェックポイント先として使用します。