はじめに
前回の記事では、ログ分析基盤に残っていたHDFS入出力をAWS S3またはS3上のIcebergテーブルへ移行しました。
本記事では、その後にHDFSを安全に停止し、不要になったモジュールを撤去します。
HDFSだけを廃止する場合でも、hadoop-*という名前のパッケージや設定を一括削除してはいけません。SparkのS3Aアクセス、YARN、Hive Metastore、Kafka、Flinkなどが、HDFSサーバーとは別の目的でHadoopライブラリやZooKeeperを利用している可能性があるためです。
そのため、次の順序で進めます。
- HDFS依存を棚卸しする
- 書き込みを停止して最終データを確定する
- HDFSを停止したまま観察する
- モジュール単位で削除可否を判断する
- 最後にHDFSデータ領域を撤去する
本記事のコマンドは構成例です。サービス名、設定ディレクトリ、データディレクトリは実環境で確認してください。特にデータ削除は、変数やワイルドカードを使わず、確定した絶対パスを人手で再確認してから実施します。
前提条件
次の移行が完了していることを前提とします。
- Kafka ConnectのHDFS SinkをS3 Sinkへ切り替え済み
- Sparkバッチの入力を
hdfs://からs3a://へ切り替え済み - Flinkの出力先をAWS S3上のIcebergへ切り替え済み
- Flinkのcheckpoint/savepointをAWS S3へ切り替え済み
- IcebergカタログをAWS Glueへ切り替え済み
- Trino、Grafana、Zeppelinの参照先をAWS側へ切り替え済み
- HDFS上の過去データをAWS S3へ移行・検証済み
過去データには、Rawバックアップ記事のbucketと、Iceberg構築記事のS3 + Glue tableを使用する。確認時のprofileはそれぞれhome-rawlog-backupとhome-awsとし、撤去前に両方のcaller identity、bucket、件数、対象期間を再確認する。
移行手順は、前回の「ログ分析基盤に残るHDFS依存をAWS S3へ移行してみる」を参照してください。
1. HDFS依存を棚卸しする
設定ファイルとスクリプトを検索する
構成管理リポジトリ、ジョブ定義、運用スクリプトを対象に、HDFSのURIと関連設定を検索します。
rg -n 'hdfs://|fs\.defaultFS|dfs\.|HADOOP_CONF_DIR|core-site\.xml|hdfs-site\.xml' \
./config ./jobs ./scripts ./systemd
cronとsystemd timerも確認します。
crontab -l
systemctl list-timers --all
systemctl list-unit-files | rg -i 'hadoop|hdfs|yarn|hive|spark|flink'
検索結果は、少なくとも次の形式で台帳化します。
| 依存元 | HDFSパス・設定 | 用途 | AWS移行先 | 切替確認 | 撤去可否 |
|---|---|---|---|---|---|
| Kafka Connect | /logs/syslog |
生ログ保存 | s3://example-raw/raw/syslog/ |
済 | 可 |
| Sparkバッチ | hdfs://nameservice1/logs/* |
集計入力 | s3a://example-raw/raw/ |
済 | 可 |
| Flink | hdfs://nameservice1/flink-checkpoints |
checkpoint | s3://example-platform/flink/checkpoints/ |
済 | 可 |
実行中の処理を確認する
設定から参照が消えていても、古いプロセスが動き続けていることがあります。
jps
yarn application -list -appStates ALL
flink list -a
Kafka Connectの稼働中コネクターも確認します。
curl -fsS http://connect1:8083/connectors
HDFS上のデータを確認する
hdfs dfsadmin -report
hdfs dfs -du -h /
hdfs dfs -count -q /
各パスについて、所有ジョブ、最終更新日時、AWS側の格納先、件数・容量・期間、削除承認者を記録します。所有者不明のパスは削除対象にしません。
2. 最終同期のためにHDFSへの書き込みを止める
次の順で旧系への書き込みを停止します。
- Kafka ConnectのHDFS Sinkを停止または削除する
- HDFSへ書き込むSparkのcron/systemd timerを停止する
- HDFSへ書き込む旧Flinkジョブをsavepoint付きで停止する
- Hiveや運用スクリプトからの書き込みを停止する
- 最終差分をAWS S3へコピーする
停止後に、HDFSの対象パスでファイル数や使用量が増えていないことを複数回確認します。
date -Is
hdfs dfs -count /logs /warehouse /flink-checkpoints
hdfs dfs -du -s -h /logs /warehouse /flink-checkpoints
HDFS監査ログを有効にしている場合は、停止後に書き込み操作が発生していないことも確認します。
rg 'cmd=(create|append|delete|rename|mkdirs)' /var/log/hadoop-hdfs/*audit*
3. 既存S3バックアップの最終差分を同期して確認する
新しいbackup先は作らない。既存のRaw backup処理とIceberg日次同期を最終更新時刻まで実行し、home-rawlog-backupとhome-awsでS3側の最終日付、件数、時刻範囲を確認する。その後に、ローカル復旧用としてHDFS名前空間と設定を保存する。
HDFS名前空間を保存する
全書き込み停止後、NameNodeをセーフモードにして名前空間を保存します。
hdfs dfsadmin -safemode enter
hdfs dfsadmin -saveNamespace
hdfs dfsadmin -safemode get
その後、NameNodeのdfs.namenode.name.dirにあるfsimageとedits、JournalNodeを利用している場合はdfs.journalnode.edits.dirを、構成情報と一緒にバックアップします。
HA構成では、Active/Standby NameNodeとJournalNodeの役割および同期状態を確認してから取得します。ファイルを稼働中に直接コピーする方法は採らず、運用中のHadoopディストリビューションが定めるバックアップ手順を優先します。
設定とメタデータを保存する
次を世代管理されたバックアップ先へ保存します。
-
/etc/hadoop/相当のHadoop設定 -
/etc/hive/相当のHive設定 - HDFS、YARN、Hive関連のsystemd unitとEnvironmentFile
- Spark、Flink、Kafka Connectのジョブ定義
- HDFSパスとAWS S3パスの対応台帳
- Hive Metastoreを使用していた場合はMetastore DBのダンプ
- インストール済みパッケージ一覧
Debian/Ubuntu系では次のようにパッケージを確認できます。
dpkg -l | rg -i 'hadoop|hdfs|hive|spark|flink'
RPM系では次のように確認します。
rpm -qa | rg -i 'hadoop|hdfs|hive|spark|flink'
4. HDFSを停止して観察する
依存サービスを先に停止した状態で、Hadoopの管理スクリプトを使ってHDFSを停止します。
stop-dfs.sh
systemdで個別管理している環境では、実際のunit名を確認し、NameNode、DataNode、JournalNode、ZKFCなどHDFSに属するunitを停止します。
systemctl list-units --type=service | rg -i 'namenode|datanode|journalnode|zkfc'
停止後は、すぐにパッケージやデータを削除しません。最低でも通常のバッチ周期と月次・週次処理を含む観察期間を設け、次を確認します。
- Kafka Connect S3 Sinkが継続してAWS S3へ出力している
- SparkバッチがAWS S3から読み込み、Glue/Icebergへ書き込める
- Flinkジョブが再起動後もAWS S3のcheckpointから復旧できる
- TrinoからAWS側のIcebergテーブルを参照できる
- Grafana、Zeppelin、Athenaの結果が一致する
- HDFS停止に起因するアラート、再試行、タイムアウトがない
問題があれば、設定とHDFSデータを残したままサービスを再開し、依存元を特定します。
5. どのモジュールまで削除してよいか
削除可否の判定表
| モジュール・設定 | HDFS移行後の判定 | 削除できる条件 |
|---|---|---|
| Kafka Connect HDFS Sinkのコネクター定義 | 削除可 | S3 Sinkの出力と過去データ移行を検証済み |
| Kafka Connect HDFS Sinkプラグイン | 条件付きで削除可 | 同一Connectクラスタ上の全コネクターが未使用。再起動後のプラグイン一覧も確認済み |
| NameNode / DataNode | 削除可 | HDFS参照ゼロ、最終同期・バックアップ完了、観察期間終了 |
| JournalNode / ZKFC | 条件付きで削除可 | HDFS HA以外に利用しておらず、NameNodeを復旧対象から外した後 |
| HDFSデータディレクトリ | 最後に削除 | AWS側検証、バックアップ復元試験、削除承認、ロールバック期限終了後 |
core-site.xml / hdfs-site.xml
|
条件付きで削除可 | 各ホストでHDFSクライアントもYARNも使わない。Spark/Flinkの起動設定も確認済み |
| Hadoop Common・HDFSクライアントJAR | 原則保留 | Spark、Flink、Hive、Trino、保守ツールが参照していないことを依存関係で確認後 |
hadoop-awsとAWS SDK |
削除不可 |
s3a://を使うSparkなどに必要。HDFSサーバー撤去とは別物 |
| YARN ResourceManager / NodeManager | 自動的には削除不可 | 全ジョブをStandalone、Kubernetes等へ移行し、YARNアプリがゼロの場合のみ |
| MapReduce JobHistory Server | 条件付きで削除可 | MapReduceジョブがなく、履歴保持要件も満たした場合のみ |
| HiveServer2 | 条件付きで削除可 | JDBC利用者やHive SQLジョブがなく、Trino等へ完全移行済み |
| Hive Metastore | 条件付きで削除可 | 全IcebergカタログをGlue等へ移行し、HiveカタログやOzone側テーブルが残っていない |
| Hive Metastore用DB | 最後に削除 | 専用DBであり、ダンプ取得・復元確認済み。他システムが同じDBを使っていない |
| ZooKeeperサービス | 原則削除不可 | Kafka、Flink HA、HBase等を含む全利用者がいない場合だけ。共有サービスをHDFS廃止だけで消さない |
| ZooKeeperのHDFS HA用znode | 条件付きで削除可 | HDFSのロールバック期限終了後、対象パスを正確に特定した場合のみ |
| Spark | 削除不可 | AWS S3上のバッチ処理やIceberg保守を継続するため |
| Flink | 削除不可 | リアルタイム処理を継続するため |
| Kafka / Kafka Connect | 削除不可 | 入力ストリームとS3 Sinkを継続するため |
| Trino | 削除不可 | AWS S3上のIceberg参照を継続するため |
| Trinoの旧HDFS/Hiveカタログ設定 | 条件付きで削除可 | AWS用カタログへ全クエリを切替済みで、ロールバック期限終了後 |
| Apache Ozone | HDFS撤去とは別判定 | ローカルS3からAWS S3への切替・検証・ロールバック期限が完了した場合のみ別作業で撤去 |
特に残すべきモジュール
hadoop-awsはHDFSサーバーではない
Sparkで次のようにAWS S3を読む場合、hadoop-awsと互換性のあるAWS SDKが必要です。
s3a://example-raw/raw/syslog/
NameNodeとDataNodeを削除しても、SparkのS3Aクライアント依存は残します。SparkとHadoop AWSのバージョン不整合を避けるため、配布物に含まれる組み合わせを優先します。
YARNはHDFSとは独立して判定する
HDFSとYARNは同じHadoop配布物に含まれますが、役割は別です。SparkやFlinkをYARN上で動かしているなら、ResourceManagerとNodeManagerは削除できません。
yarn application -list -appStates ALL
この結果だけでなく、cron、CI/CD、月次処理が--master yarnやYARN Application Modeを使っていないことも確認します。
ZooKeeperは共有利用を確認する
HDFS HAでZooKeeperを使っていても、ZooKeeper自体をHDFS専用とは限りません。KafkaやFlink HAが同じensembleを利用している場合、サービスを削除してはいけません。
削除を検討できるのは、HDFS専用znodeだけです。それもロールバック期限後に、対象パスとACLを確認してから別作業として実施します。
6. 撤去を4段階に分ける
段階A: 設定を無効化する
- HDFS向けコネクター、cron、timerを無効化する
- Trinoの旧HDFSカタログを読み込ませない
- 旧設定ファイルは削除せず、変更履歴とともに退避する
- 監視からHDFS項目を消す前に、依存検知用アラートとして観察する
段階B: HDFSデーモンを停止する
- NameNode、DataNode、JournalNode、ZKFCを停止する
- 自動起動を無効化する
- データディレクトリと設定は保持する
- バッチ周期をカバーする期間、AWS側だけで運用する
段階C: HDFSサーバーパッケージを削除する
パッケージマネージャーの依存関係表示を使い、削除対象と一緒にSpark、Flink、YARN、Hiveのクライアントライブラリが削除されないことを確認します。
削除対象は、原則としてHDFSサーバー役割に限定します。
- NameNode
- DataNode
- JournalNode
- ZKFC
- HDFS専用のsystemd unitと監視設定
- 未使用になったHDFS Sinkプラグイン
一括指定でhadoop*を削除する操作は行いません。
段階D: HDFSデータ領域を削除する
データディレクトリの削除は最後です。次をすべて満たすまで実施しません。
- AWS S3上で件数、容量、期間、サンプル内容を照合済み
- IcebergのスナップショットとTrinoクエリを確認済み
- バックアップからの復元手順を試験済み
- ロールバック期限が終了済み
- 対象ホストと絶対パスについて複数名で承認済み
- 対象ファイルシステムが他サービスと共用されていない
削除前には、実際の設定値を表示して対象を確定します。
hdfs getconf -confKey dfs.namenode.name.dir
hdfs getconf -confKey dfs.datanode.data.dir
hdfs getconf -confKey dfs.journalnode.edits.dir
停止・パッケージ削除後はhdfs getconfが使えないため、バックアップした設定と台帳から照合します。記事中の例をそのまま削除コマンドへ置き換えず、環境ごとの変更申請で確定したパスだけを対象にします。
7. 撤去完了の確認
HDFS参照が残っていないことを確認する
rg -n 'hdfs://|fs\.defaultFS|dfs\.|HADOOP_CONF_DIR' \
./config ./jobs ./scripts ./systemd
意図的に保存したバックアップやドキュメント以外に一致がないことを確認します。
HDFSプロセスとポートを確認する
jps
systemctl list-units --type=service | rg -i 'namenode|datanode|journalnode|zkfc'
AWS側の処理を確認する
SELECT count(*)
FROM iceberg_aws.logs.syslog
WHERE event_time >= current_timestamp - INTERVAL '1' HOUR;
加えて、次を確認します。
- S3 Sinkのconsumer lagと失敗件数
- S3オブジェクトの継続作成
- Flink checkpointの成功時刻
- Iceberg snapshotの更新時刻
- Sparkバッチの終了状態
- Trino、Grafana、Zeppelinのクエリ成功率
- AWS CloudTrailとS3アクセスログ上の拒否エラー
8. ロールバック条件を決めておく
観察期間中は、HDFSの設定、パッケージ、データディレクトリを保持します。次のいずれかが発生した場合は、削除工程へ進まずHDFSを再開します。
- AWS側のデータ欠損が確認された
- FlinkがS3のcheckpointから復旧できない
- SparkまたはTrinoに未移行のHDFS参照が見つかった
- 過去データの監査・再計算要件をAWS側で満たせない
- S3やGlueの権限設計に重大な不足がある
ロールバックでは、書き込み元を二重起動しないようにします。AWS側ジョブを停止してからHDFS側を再開し、Kafkaのoffset、Flinkのsavepoint、対象期間を明示して復旧します。
まとめ
HDFSを撤去できる状態は、単にデータをAWS S3へコピーした状態ではありません。すべての書き込み元、読み取り元、メタデータ、checkpoint、運用スクリプト、可視化ツールがAWS側へ切り替わり、HDFSを停止したまま通常運用できる状態です。
削除してよい範囲は、まずNameNode、DataNode、JournalNode、ZKFCなどのHDFSサーバー役割と、未使用のHDFS Sinkです。一方、hadoop-aws、YARN、Hive Metastore、ZooKeeper、Spark、Flink、Kafka、Trinoは、名前や導入経緯だけで削除せず、それぞれの利用状況で判断します。
最後まで残すのはHDFSデータ領域です。停止、観察、パッケージ撤去、データ消去を別工程にすることで、依存の見落としがあっても復旧可能な状態を維持できます。
参考資料
- Apache Hadoop Cluster Setup - Operating the Hadoop Cluster
- Apache Hadoop HDFS Users Guide
- Apache Hadoop FileSystem Shell
関連記事
- 【導入編】HDFSログ分析基盤をAWS S3へ段階移行する全8編の構成を紹介する
- 【第5編】ログ分析基盤に残るHDFS依存をAWS S3へ移行してみる
- 【第7編】Amazon S3のrawログとApache Icebergに保持期間とメンテナンスを設定する
実機検証について
本記事の手順は、執筆時点では実機環境での一連の動作検証をまだ完了していない。掲載している設定値、command、service名、packageの削除範囲は設計例を含むため、利用するHadoop distribution、HA構成、共有service、各hostの依存関係に合わせた確認が必要である。
特にHDFSの停止、package削除、data directoryの削除は実環境へ影響する。検証環境でbackupとrestoreを確認し、停止状態で十分な観察期間を設け、対象pathと削除範囲の承認を得るまで実施しない。実機検証の結果に応じて本記事を更新する予定である。