- はじめに
- 1. HDFS運用基準
- 2. HDFS容量計画とデータライフサイクル
- 3. YARNキュー設計とリソース管理
- 4. MapReduceジョブチューニング
- 5. クラスターモニタリングとアラート
- 6. 障害対応ガイド
- 7. 運用チェックリスト
- 8. まとめ
- クイズ

はじめに
Hadoopクラスターを構築することと安定的に運用することは全く別次元の問題である。インストールマニュアルは溢れているが、HDFSが90%に達したときどうすべきか、YARNキューが飽和したときプリエンプションポリシーをどう設定すべきか、MapReduceジョブがデータスキューで4時間も回っているときどこを見るべきかといった運用実務基準をまとめた文書は少ない。
本記事では、Hadoopエコシステム(HDFS、YARN、MapReduce)を本番環境で運用する観点から、容量計画、キュー設計、ジョブチューニング、モニタリング、障害対応までの実践基準を整理する。Hadoop 3.x基準で作成しており、各セクションに実際の設定例とコマンドを含めている。
1. HDFS運用基準
1.1 ブロックサイズ設定
HDFSのデフォルトブロックサイズは128MBであり、大容量ファイルを扱う環境では256MBに設定するのが一般的である。
<!-- hdfs-site.xml -->
<property>
<name>dfs.blocksize</name>
<value>268435456</value> <!-- 256MB -->
<description>大容量ETLファイル基準で256MB推奨。小さなファイルが多い場合は128MBを維持。</description>
</property>
ブロックサイズ選択基準:
| 基準 | 128MB | 256MB |
|---|---|---|
| 平均ファイルサイズ | 数百MB以下 | 数GB以上 |
| MapReduceマッパー数 | 多い(細分化) | 少ない(大型タスク) |
| NameNodeメモリ負荷 | 高い | 低い |
| ネットワーク活用 | 普通 | 効率的 |
運用ルール:NameNodeヒープではブロック1つが約150バイトのメモリを消費する。1億個のブロックでは約15GBのNameNodeヒープが必要になる。ブロック数の削減がNameNodeの安定性に直結する。
1.2 レプリケーションファクター管理
デフォルトのレプリケーションファクターは3である。この値を下げるとストレージ容量を節約できるが、耐障害性が低下する。
# クラスター全体のレプリケーションファクター確認
hdfs dfsadmin -report | grep "Default Replication"
# 特定ディレクトリのレプリケーションファクター変更(コールドデータアーカイブ時)
hdfs dfs -setrep -w 2 /data/archive/2024/
# レプリケーション不足ブロックの確認
hdfs fsck / -files -blocks -replicaDetails | grep "Under-replicated"
レプリケーションファクター運用ポリシー例:
/data/raw/(元データ):レプリケーションファクター 3/data/processed/(加工データ):レプリケーションファクター 2/data/tmp/(一時データ):レプリケーションファクター 1- Erasure Coding適用ディレクトリ:該当なし(別ポリシー)
1.3 NameNode管理
NameNodeはHDFSの単一障害点(SPOF)である。HA(High Availability)構成は必須であり、以下の項目を定期的に点検する必要がある。
<!-- hdfs-site.xml: NameNode HA設定 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>namenode1.example.com:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>namenode2.example.com:8020</value>
</property>
<property>
<name>dfs.namenode.handler.count</name>
<value>128</value>
<description>クライアントRPCリクエスト処理スレッド数。100台以上のノードでは128〜256推奨。</description>
</property>
# NameNodeの状態確認
hdfs haadmin -getServiceState nn1
hdfs haadmin -getServiceState nn2
# NameNodeのヒープ使用量確認
jstat -gcutil $(jps | grep NameNode | awk '{print $1}') 5000
# EditLogサイズ確認(トランザクションログが過度に蓄積すると問題)
hdfs dfsadmin -fetchImage /tmp/fsimage_check
ls -lh /tmp/fsimage_check
1.4 セーフモード管理
NameNodeがセーフモードにあると書き込み操作がブロックされる。ブロックレポートが十分に受信されるまで自動的に有効化される。
# セーフモードの状態確認
hdfs dfsadmin -safemode get
# セーフモードの強制解除(注意:ブロック整合性確認後にのみ実行)
hdfs dfsadmin -safemode leave
# セーフモード進入条件の確認
hdfs dfsadmin -report | grep -E "Safe mode|Missing blocks"
<!-- hdfs-site.xml: セーフモード閾値調整 -->
<property>
<name>dfs.namenode.safemode.threshold-pct</name>
<value>0.999</value>
<description>全ブロックの99.9%がレポートされたらセーフモード解除</description>
</property>
<property>
<name>dfs.namenode.safemode.extension</name>
<value>30000</value>
<description>セーフモード解除後の追加待機時間(30秒)</description>
</property>
1.5 HDFS Balancer運用
DataNode間のディスク使用率の偏りが大きくなると、特定のノードにホットスポットが発生する。Balancerを定期的に実行する必要がある。
# Balancer実行(デフォルト閾値10%)
hdfs balancer -threshold 5
# 帯域幅制限設定(運用時間帯には制限が必要)
hdfs dfsadmin -setBalancerBandwidth 52428800 # 50MB/s
# Balancerバックグラウンド実行(cron登録推奨)
nohup hdfs balancer -threshold 5 -idleiterations 5 > /var/log/hadoop/balancer.log 2>&1 &
Balancer運用ルール:
- 夜間(00:00〜06:00)にcronで実行
- 運用時間帯は帯域幅を20MB/s以下に制限
- thresholdは5〜10%の範囲で設定
- DataNode追加直後は必ず実行
2. HDFS容量計画とデータライフサイクル
2.1 HDFSクォータ管理
ディスク使用量の暴走を防ぐため、ディレクトリごとにクォータを必ず設定する。
# ネームクォータ設定(ファイル/ディレクトリ数制限)
hdfs dfsadmin -setQuota 1000000 /data/team-a/
# スペースクォータ設定(容量制限、レプリケーションファクター含む)
hdfs dfsadmin -setSpaceQuota 10T /data/team-a/
# クォータ状況確認
hdfs dfs -count -q -h /data/team-a/
# 出力: QUOTA REM_QUOTA SPACE_QUOTA REM_SPACE_QUOTA DIR_COUNT FILE_COUNT CONTENT_SIZE PATHNAME
# クォータ解除
hdfs dfsadmin -clrSpaceQuota /data/team-a/
チーム別クォータ設計例:
| チーム | パス | スペースクォータ | ネームクォータ | 備考 |
|---|---|---|---|---|
| データエンジニアリング | /data/de/ | 50TB | 5,000,000 | ETLパイプライン |
| MLチーム | /data/ml/ | 30TB | 2,000,000 | 学習データ |
| 分析チーム | /data/analytics/ | 20TB | 1,000,000 | 集計結果 |
| 一時領域 | /data/tmp/ | 5TB | 500,000 | 7日TTL |
2.2 データ圧縮戦略
HDFSで圧縮を適用するとストレージ容量とネットワークI/Oの両方を節約できる。
| 圧縮コーデック | 圧縮率 | 速度 | 分割可能 | 用途 |
|---|---|---|---|---|
| Snappy | 普通 | 非常に高速 | 不可(コンテナフォーマット使用時は可) | 中間データ、シャッフル |
| LZ4 | 普通 | 非常に高速 | 不可 | リアルタイム処理 |
| Gzip | 高い | 遅い | 不可 | アーカイブ、コールドデータ |
| Zstandard | 高い | 高速 | 不可 | Gzip代替、アーカイブ |
| Bzip2 | 非常に高い | 非常に遅い | 可 | 長期保管 |
<!-- core-site.xml: 圧縮コーデック登録 -->
<property>
<name>io.compression.codecs</name>
<value>
org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.SnappyCodec,
org.apache.hadoop.io.compress.ZStandardCodec,
org.apache.hadoop.io.compress.Lz4Codec
</value>
</property>
<!-- mapred-site.xml: MapReduce中間出力の圧縮 -->
<property>
<name>mapreduce.map.output.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.map.output.compress.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
2.3 Erasure Coding(EC)
Hadoop 3.xで導入されたErasure Codingは、レプリケーションファクター3と比較して約50%のストレージ容量を節約しつつ、同等の耐障害性を提供する。
# 利用可能なECポリシー確認
hdfs ec -listPolicies
# RS-6-3ポリシー有効化(6データブロック + 3パリティブロック)
hdfs ec -enablePolicy -policy RS-6-3-1024k
# ディレクトリにECポリシー適用
hdfs ec -setPolicy -path /data/archive -policy RS-6-3-1024k
# ECポリシー確認
hdfs ec -getPolicy -path /data/archive
EC適用時の注意事項:
- 最低9台のDataNodeが必要(RS-6-3基準)
- ランダム読み取り性能がレプリケーション方式より低い(エンコード/デコードオーバーヘッド)
- ホットデータよりもコールド/ウォームデータに適している
- 既存ファイルには適用不可(新規書き込みまたはdistcpで移動が必要)
2.4 Tiered Storage
HDFSのストレージポリシーを活用すると、SSD、HDD、アーカイブストレージを階層的に管理できる。
# ストレージポリシー確認
hdfs storagepolicies -listPolicies
# ホットデータ → SSD
hdfs storagepolicies -setStoragePolicy -path /data/hot -policy HOT
# ウォームデータ → 1 SSD + N HDD
hdfs storagepolicies -setStoragePolicy -path /data/warm -policy WARM
# コールドデータ → アーカイブ
hdfs storagepolicies -setStoragePolicy -path /data/cold -policy COLD
# ポリシーに従いデータ移動を実行
hdfs mover -p /data/
<!-- hdfs-site.xml: DataNodeストレージタイプ指定 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>[SSD]/ssd/hdfs/data,[DISK]/hdd1/hdfs/data,[DISK]/hdd2/hdfs/data,[ARCHIVE]/archive/hdfs/data</value>
</property>
2.5 データライフサイクル自動化
#!/bin/bash
# data_lifecycle.sh - データライフサイクル自動化スクリプト
DATE=$(date +%Y-%m-%d)
LOG="/var/log/hadoop/lifecycle_${DATE}.log"
echo "[${DATE}] データライフサイクル管理開始" >> ${LOG}
# 1. 90日以上経過した一時データの削除
echo "=== 一時データクリーンアップ ===" >> ${LOG}
hdfs dfs -find /data/tmp -name "*" -atime +90 -print >> ${LOG}
hdfs dfs -rm -r -skipTrash $(hdfs dfs -find /data/tmp -name "*" -atime +90) 2>> ${LOG}
# 2. 30日以上経過した処理データ → レプリケーションファクター2に変更
echo "=== レプリケーションファクター調整 ===" >> ${LOG}
for dir in $(hdfs dfs -ls /data/processed/ | awk '{print $8}' | tail -n +2); do
mod_date=$(hdfs dfs -stat "%Y" ${dir})
age_days=$(( ($(date +%s) - $(date -d "${mod_date}" +%s)) / 86400 ))
if [ ${age_days} -gt 30 ]; then
hdfs dfs -setrep 2 ${dir} >> ${LOG} 2>&1
fi
done
# 3. 180日以上経過したデータ → Erasure Codingディレクトリへ移動
echo "=== アーカイブ移行 ===" >> ${LOG}
hadoop distcp -skipcrccheck /data/processed/old/ /data/archive/ >> ${LOG} 2>&1
# 4. 容量レポート
echo "=== 容量状況 ===" >> ${LOG}
hdfs dfs -du -s -h /data/* >> ${LOG}
echo "[${DATE}] データライフサイクル管理完了" >> ${LOG}
3. YARNキュー設計とリソース管理
3.1 Capacity Scheduler vs Fair Scheduler
| 項目 | Capacity Scheduler | Fair Scheduler |
|---|---|---|
| デフォルト | Apache Hadoop | CDH |
| リソース保証 | キューごとの最小容量保証 | 重み付け均等分配 |
| プリエンプション | サポート | サポート |
| マルチテナンシー | 強い(階層型キュー) | 普通 |
| 設定の複雑さ | 高い | 普通 |
推奨:Hadoop 3.xではCapacity Schedulerが公式デフォルトであり、大規模マルチテナント環境に適している。
3.2 Capacity Schedulerキュー設計
<!-- capacity-scheduler.xml -->
<configuration>
<!-- ルートキューの子構造 -->
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>production,development,system</value>
</property>
<!-- productionキュー:全リソースの60% -->
<property>
<name>yarn.scheduler.capacity.root.production.capacity</name>
<value>60</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.production.maximum-capacity</name>
<value>80</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.production.queues</name>
<value>etl,realtime</value>
</property>
<!-- production > etlキュー -->
<property>
<name>yarn.scheduler.capacity.root.production.etl.capacity</name>
<value>70</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.production.etl.maximum-capacity</name>
<value>90</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.production.etl.user-limit-factor</name>
<value>2</value>
</property>
<!-- production > realtimeキュー -->
<property>
<name>yarn.scheduler.capacity.root.production.realtime.capacity</name>
<value>30</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.production.realtime.maximum-capacity</name>
<value>50</value>
</property>
<!-- developmentキュー:全リソースの30% -->
<property>
<name>yarn.scheduler.capacity.root.development.capacity</name>
<value>30</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.development.maximum-capacity</name>
<value>50</value>
</property>
<!-- systemキュー:全リソースの10%(モニタリング、メンテナンス) -->
<property>
<name>yarn.scheduler.capacity.root.system.capacity</name>
<value>10</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.system.maximum-capacity</name>
<value>20</value>
</property>
</configuration>
キュー構造図:
root (100%)
├── production (60%, max 80%)
│ ├── etl (productionの70%, max 90%)
│ └── realtime (productionの30%, max 50%)
├── development (30%, max 50%)
└── system (10%, max 20%)
3.3 プリエンプション設定
プリエンプションは、キューが保証されたリソースを取り戻すために他のキューのコンテナを強制終了するメカニズムである。
<!-- yarn-site.xml -->
<property>
<name>yarn.resourcemanager.scheduler.monitor.enable</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.monitor.policies</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy</value>
</property>
<!-- プリエンプション待機時間:15秒後に開始 -->
<property>
<name>yarn.resourcemanager.monitor.capacity.preemption.monitoring_interval</name>
<value>3000</value>
</property>
<property>
<name>yarn.resourcemanager.monitor.capacity.preemption.max_wait_before_kill</name>
<value>15000</value>
</property>
<!-- 1ラウンドあたりの最大プリエンプション割合 -->
<property>
<name>yarn.resourcemanager.monitor.capacity.preemption.total_preemption_per_round</name>
<value>0.1</value>
</property>
3.4 YARNリソース設定
<!-- yarn-site.xml: NodeManagerリソース設定 -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>65536</value> <!-- 64GB(全メモリの約80%) -->
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>24</value> <!-- 物理コア数の1.5〜2倍 -->
</property>
<!-- コンテナメモリ範囲 -->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>32768</value>
</property>
<!-- コンテナvcore範囲 -->
<property>
<name>yarn.scheduler.minimum-allocation-vcores</name>
<value>1</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-vcores</name>
<value>12</value>
</property>
# YARNキュー状態確認
yarn queue -status production
# 実行中のアプリケーション確認
yarn application -list -appStates RUNNING
# キューごとのリソース使用量確認
yarn queue -status production.etl
# YARNスケジューラー設定のリロード(再起動不要)
yarn rmadmin -refreshQueues
4. MapReduceジョブチューニング
4.1 Mapper/Reducer数の最適化
<!-- mapred-site.xml -->
<!-- マッパーメモリ:デフォルト1GB、大容量データでは2〜4GB推奨 -->
<property>
<name>mapreduce.map.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xmx1638m</value> <!-- memory.mbの80% -->
</property>
<!-- リデューサーメモリ:マッパーより大きく設定(集計演算が多いため) -->
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xmx3276m</value> <!-- memory.mbの80% -->
</property>
<!-- リデューサー数の明示(データサイズに応じて調整) -->
<property>
<name>mapreduce.job.reduces</name>
<value>100</value>
</property>
Mapper/Reducer数の算定公式:
マッパー数 ≈ 入力データサイズ / ブロックサイズ
例:1TB入力、256MBブロック → 約4,000マッパー
リデューサー数 ≈ 0.95 × (クラスター内の総reduceスロット数)
または実測に基づきリデューサー1つあたりの処理量が256MB〜1GBになるよう調整
4.2 シャッフル最適化
シャッフルはMapReduceで最もコストの高いフェーズである。ネットワークI/OとディスクI/Oが集中する。
<!-- mapred-site.xml: マップ側ソート/スピル設定 -->
<property>
<name>mapreduce.task.io.sort.mb</name>
<value>512</value>
<description>ソートバッファサイズ。デフォルト100MB → 512MBに増やすとスピル回数が減少。</description>
</property>
<property>
<name>mapreduce.task.io.sort.factor</name>
<value>100</value>
<description>同時マージ可能なストリーム数。デフォルト10 → 100に増加。</description>
</property>
<property>
<name>mapreduce.map.sort.spill.percent</name>
<value>0.80</value>
<description>ソートバッファが80%に達したらスピル開始</description>
</property>
<!-- リデュース側シャッフル設定 -->
<property>
<name>mapreduce.reduce.shuffle.parallelcopies</name>
<value>20</value>
<description>リデューサーがマッパー出力を取得する並列スレッド数</description>
</property>
<property>
<name>mapreduce.reduce.shuffle.input.buffer.percent</name>
<value>0.70</value>
<description>シャッフル入力に割り当てるヒープの割合</description>
</property>
<property>
<name>mapreduce.reduce.shuffle.merge.percent</name>
<value>0.66</value>
<description>インメモリマージ開始閾値</description>
</property>
4.3 データスキュー処理
データスキューとは、特定のキーにデータが集中し、一部のリデューサーだけが過負荷になる現象である。
スキューの診断:
# ジョブカウンターからリデューサーごとの入力レコード数の偏差を確認
yarn logs -applicationId application_1234567890_0001 | grep "Reduce input records"
# ジョブヒストリーサーバーからタスクごとの実行時間を確認
mapred job -history /path/to/job_history_file
スキュー解消方法:
- ソルティング:キーにランダムなプレフィックスを付けて分散
// マッパーでキーにソルトを追加
int salt = random.nextInt(10);
outputKey.set(salt + "_" + originalKey);
// 第1MR:ソルトキーで部分集計
// 第2MR:ソルト除去後に最終集計
- Combinerの適用:マッパー出力をローカルで事前集計
job.setCombinerClass(MyCombiner.class);
- パーティショナーのカスタマイズ:データ分布を考慮したパーティショニング
public class SkewAwarePartitioner extends Partitioner<Text, IntWritable> {
@Override
public int getPartition(Text key, IntWritable value, int numPartitions) {
String k = key.toString();
if (k.equals("HOT_KEY")) {
// ホットキーを複数リデューサーに分散
return (k.hashCode() + random.nextInt(10)) % numPartitions;
}
return (k.hashCode() & Integer.MAX_VALUE) % numPartitions;
}
}
4.4 投機的実行(Speculative Execution)
遅いタスク(ストラグラー)を検知すると、同一タスクを別ノードで並列実行し、先に完了した結果を採用する。
<!-- mapred-site.xml -->
<property>
<name>mapreduce.map.speculative</name>
<value>true</value>
</property>
<property>
<name>mapreduce.reduce.speculative</name>
<value>false</value>
<description>リデューサーはデータ消費量が多いため投機的実行無効化推奨</description>
</property>
注意:外部システムへの書き込みを行うタスク(DBインサート、API呼び出しなど)では必ず無効化すること。重複書き込みが発生する可能性がある。
4.5 JVM再利用
タスクごとにJVMを新規作成するとオーバーヘッドが大きい。小型タスクが多い場合に効果的である。
<!-- mapred-site.xml -->
<property>
<name>mapreduce.job.jvm.numtasks</name>
<value>10</value>
<description>1つのJVMで最大10タスク実行。-1で無制限。</description>
</property>
5. クラスターモニタリングとアラート
5.1 主要モニタリングメトリクス
HDFSコアメトリクス:
| メトリクス | 正常範囲 | 警告閾値 | 危険閾値 |
|---|---|---|---|
| DFS使用率 | < 70% | 80% | 90% |
| レプリケーション不足ブロック | 0 | > 100 | > 1,000 |
| 欠損ブロック | 0 | > 0 | > 10 |
| NNヒープ使用率 | < 70% | 80% | 90% |
| Dead DataNode数 | 0 | > 0 | > 2 |
| NN RPC平均処理時間 | < 10ms | > 50ms | > 200ms |
YARNコアメトリクス:
| メトリクス | 正常範囲 | 警告閾値 | 危険閾値 |
|---|---|---|---|
| クラスターメモリ使用率 | < 80% | 85% | 95% |
| Pendingコンテナ数 | < 50 | > 200 | > 1,000 |
| Unhealthyノード数 | 0 | > 0 | > 3 |
| キュー待ちアプリケーション数 | < 10 | > 50 | > 200 |
5.2 JMXによるメトリクス収集
# NameNode JMXメトリクス照会
curl -s http://namenode:9870/jmx | python3 -m json.tool | grep -A5 "CapacityUsed"
# ResourceManager JMXメトリクス照会
curl -s http://resourcemanager:8088/jmx | python3 -m json.tool | grep -A5 "AllocatedMB"
# DataNode JMXメトリクス照会
curl -s http://datanode:9864/jmx?qry=Hadoop:service=DataNode,name=FSDatasetState
5.3 Prometheus + Grafana連携
# prometheus.yml - Hadoop JMX Exporter設定
scrape_configs:
- job_name: 'hadoop-namenode'
scrape_interval: 30s
static_configs:
- targets: ['namenode1:7001', 'namenode2:7001']
labels:
cluster: 'production'
component: 'namenode'
- job_name: 'hadoop-datanode'
scrape_interval: 30s
static_configs:
- targets: ['datanode1:7002', 'datanode2:7002', 'datanode3:7002']
labels:
cluster: 'production'
component: 'datanode'
- job_name: 'hadoop-resourcemanager'
scrape_interval: 30s
static_configs:
- targets: ['resourcemanager:7003']
labels:
cluster: 'production'
component: 'resourcemanager'
- job_name: 'hadoop-nodemanager'
scrape_interval: 30s
static_configs:
- targets: ['datanode1:7004', 'datanode2:7004', 'datanode3:7004']
labels:
cluster: 'production'
component: 'nodemanager'
JMX Exporter起動設定(hadoop-env.sh):
# hadoop-env.sh
export HDFS_NAMENODE_OPTS="$HDFS_NAMENODE_OPTS -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent.jar=7001:/opt/jmx_exporter/namenode.yml"
export HDFS_DATANODE_OPTS="$HDFS_DATANODE_OPTS -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent.jar=7002:/opt/jmx_exporter/datanode.yml"
export YARN_RESOURCEMANAGER_OPTS="$YARN_RESOURCEMANAGER_OPTS -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent.jar=7003:/opt/jmx_exporter/resourcemanager.yml"
export YARN_NODEMANAGER_OPTS="$YARN_NODEMANAGER_OPTS -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent.jar=7004:/opt/jmx_exporter/nodemanager.yml"
5.4 Grafanaアラートルール例
# Grafana Alert Rules
groups:
- name: hadoop_alerts
rules:
- alert: HDFSCapacityCritical
expr: hadoop_namenode_capacity_used_gb / hadoop_namenode_capacity_total_gb > 0.9
for: 10m
labels:
severity: critical
annotations:
summary: 'HDFS容量90%超過'
description: 'HDFS使用率が{{ $value | humanizePercentage }}です。直ちにデータクリーンアップまたはノード追加が必要です。'
- alert: HDFSMissingBlocks
expr: hadoop_namenode_missing_blocks > 0
for: 5m
labels:
severity: critical
annotations:
summary: 'HDFS欠損ブロック発生'
description: '{{ $value }}個のブロックが欠損しています。'
- alert: YARNUnhealthyNodes
expr: hadoop_resourcemanager_unhealthy_nodes > 0
for: 5m
labels:
severity: warning
annotations:
summary: 'YARN Unhealthyノード発生'
description: '{{ $value }}個のノードがunhealthy状態です。'
- alert: YARNMemoryPressure
expr: hadoop_resourcemanager_allocated_mb / hadoop_resourcemanager_available_mb > 0.95
for: 15m
labels:
severity: warning
annotations:
summary: 'YARNメモリリソース不足'
description: 'クラスターメモリ使用率が95%を超過しました。'
5.5 Ambari / Cloudera Managerの活用
専用管理ツールを使用すると、設定管理、モニタリング、アラートを統合的に処理できる。
| 機能 | Ambari(Apache) | Cloudera Manager |
|---|---|---|
| 設定管理 | UIベース、バージョン履歴 | UIベース、ロールバック対応 |
| モニタリング | 内蔵ダッシュボード | 内蔵 + Grafana連携 |
| アラート | SMTP, SNMP | SMTP, SNMP, Webhook |
| サービス管理 | 個別サービス制御 | ローリング再起動対応 |
| ライセンス | Apache(無料) | 商用(CDP) |
6. 障害対応ガイド
6.1 DataNode障害
症状:DataNodeプロセスダウン、ネットワーク切断、ディスク障害
# ステップ1:Dead DataNodeの確認
hdfs dfsadmin -report | grep -A3 "Dead datanodes"
# ステップ2:該当DataNodeのログ確認
tail -500 /var/log/hadoop/hdfs/hadoop-hdfs-datanode-*.log | grep -E "ERROR|WARN|FATAL"
# ステップ3:ディスク状態確認
df -h # ディスク容量
smartctl -a /dev/sda # ディスク健全性
dmesg | grep -i "error\|fail\|i/o" # カーネルログでディスクエラーを確認
# ステップ4:DataNode再起動または除去
# 再起動可能な場合:
hdfs --daemon start datanode
# 除去が必要な場合(Decommission):
# 1) dfs.hosts.excludeにノードを追加
# 2) 設定リフレッシュ
hdfs dfsadmin -refreshNodes
# 3) データマイグレーション進行状況のモニタリング
hdfs dfsadmin -report | grep "Decommission Status"
DataNode Decommission設定:
<!-- hdfs-site.xml -->
<property>
<name>dfs.hosts.exclude</name>
<value>/etc/hadoop/conf/dfs.exclude</value>
</property>
# /etc/hadoop/conf/dfs.exclude
datanode-bad-01.example.com
datanode-bad-02.example.com
6.2 NameNodeフェイルオーバー
HA環境ではActive NameNode障害時に自動フェイルオーバーが動作する必要がある。
# NameNode状態確認
hdfs haadmin -getAllServiceState
# 出力例:
# nn1 active
# nn2 standby
# 手動フェイルオーバー(緊急時)
hdfs haadmin -failover nn1 nn2
# ZKFCプロセス確認(自動フェイルオーバーの核心)
jps | grep DFSZKFailoverController
# ZooKeeperセッション状態確認
echo "stat" | nc zookeeper1 2181
# フェイルオーバーが動作しない場合:ZKFC再起動
hdfs --daemon stop zkfc
hdfs --daemon start zkfc
自動フェイルオーバー設定:
<!-- hdfs-site.xml -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- core-site.xml -->
<property>
<name>ha.zookeeper.quorum</name>
<value>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</value>
</property>
6.3 ディスク障害対応
DataNodeで特定のディスクが障害を起こした場合、DataNode全体を停止せずに該当ディスクだけを除外できる。
<!-- hdfs-site.xml: ディスク障害許容設定 -->
<property>
<name>dfs.datanode.failed.volumes.tolerated</name>
<value>2</value>
<description>最大2つのボリューム障害までDataNodeを維持。全ボリューム数の1/3以下推奨。</description>
</property>
# ディスク交換手順
# 1. 障害ディスクの確認
hdfs dfsadmin -getDatanodeInfo datanode01:9866
# 2. 該当ボリュームをdfs.datanode.data.dirから除去
# 3. DataNodeの再設定(Hadoop 3.xではライブリコンフィグ可能)
hdfs dfsadmin -reconfig datanode datanode01:9866 start
# 4. リコンフィグ状態確認
hdfs dfsadmin -reconfig datanode datanode01:9866 status
# 5. 新しいディスクをマウント後、data.dirに追加して再度リコンフィグ
6.4 YARN ResourceManager障害
# RM HA状態確認
yarn rmadmin -getAllServiceState
# RM手動切り替え
yarn rmadmin -transitionToActive rm2
# NodeManagerがRMに接続できない場合
# NMログ確認
tail -200 /var/log/hadoop/yarn/hadoop-yarn-nodemanager-*.log | grep "ERROR"
# NM再起動
yarn --daemon stop nodemanager
yarn --daemon start nodemanager
7. 運用チェックリスト
7.1 日次チェックリスト
#!/bin/bash
# daily_health_check.sh
echo "========== HDFS日次点検 =========="
# HDFSステータスサマリー
hdfs dfsadmin -report | head -20
# 欠損/レプリケーション不足ブロックの確認
hdfs fsck / -list-corruptfileblocks
# NameNodeセーフモード確認
hdfs dfsadmin -safemode get
echo "========== YARN日次点検 =========="
# YARNノード状態
yarn node -list -all | head -20
# 失敗したアプリケーション確認(直近24時間)
yarn application -list -appStates FAILED
# キュー使用状況
yarn queue -status root
echo "========== システム点検 =========="
# ディスク使用量
df -h | grep -E "/data|/hdfs"
# メモリ/CPU
free -g
uptime
7.2 週次チェックリスト
| 項目 | コマンド/アクション | 基準 |
|---|---|---|
| HDFS fsck全体実行 | hdfs fsck / -files -blocks | Corruptブロック 0 |
| Balancer実行 | hdfs balancer -threshold 5 | ノード間偏差 < 5% |
| YARNログ整理 | yarn logs -applicationId ... -am | 30日以上のログ削除 |
| GCログ分析 | NN/RM GCログレビュー | Full GC < 5回/日 |
| ディスクSMART点検 | smartctl -a /dev/sd* | エラー 0 |
7.3 月次チェックリスト
| 項目 | 説明 |
|---|---|
| 容量トレンド分析 | 月別HDFS使用量増加率計算、3ヶ月後の容量予測 |
| キューリソース再調整 | チーム別の実際使用量に基づきcapacity再設定 |
| パフォーマンスベースライン更新 | 主要ETLジョブの実行時間トレンド確認 |
| セキュリティ監査 | アクセス権限、サービスアカウント点検 |
| Hadoopバージョン/パッチ確認 | セキュリティパッチ、バグ修正の適用状況確認 |
7.4 容量計画スプレッドシート
現在のクラスター状態:
- 総DataNode数:N
- ノードあたりのディスク:12 × 4TB HDD = 48TB
- 総RAW容量:N × 48TB
- HDFS利用可能容量(レプリケーションファクター3基準):N × 48TB / 3 = N × 16TB
- 現在のHDFS使用量:X TB
- 使用率:X / (N × 16) × 100 = Y%
月間増加量:Z TB/月
ノード追加時期の計算:
- 安全閾値:80%
- 残り容量:(N × 16 × 0.8) - X = W TB
- 現在の増加速度で W / Z = Mヶ月後に80%到達
- ノード発注リードタイム考慮 → M - 2ヶ月前に発注が必要
8. まとめ
Hadoopクラスターの運用は、初期構築よりも継続的な管理とチューニングにはるかに多くの労力を要する。本記事で取り上げた要点を整理すると以下の通りである。
HDFS:ブロックサイズとレプリケーションファクターをデータ特性に合わせて設定し、NameNodeヒープ管理とBalancer実行を定期ルーティンとして確立する。Erasure CodingとTiered Storageを活用してストレージコストを最適化する。
YARN:Capacity Schedulerベースの階層型キューを設計し、プリエンプションポリシーを有効化してリソースの公平性を保証する。キューのcapacityは実際の使用パターンに合わせて定期的に再調整する。
MapReduce:シャッフルの最適化(ソートバッファ、スピル閾値)とデータスキュー処理がジョブパフォーマンスの鍵である。JVM再利用と投機的実行は状況に応じて設定する。
モニタリング:JMX + Prometheus + Grafanaのパイプラインを構築し、HDFS容量/ブロック状態、YARNリソース/キュー状態のアラートを設定する。
障害対応:NameNode HAフェイルオーバー、DataNode Decommission、ディスクホットスワップの手順を事前に文書化し訓練する。
運用チェックリストを日次/週次/月次に分けて実行し、容量計画をデータに基づいて策定すれば、大部分の運用課題を先制的に防止できる。
クイズ
Q1: 「Hadoopエコシステム実践ガイド:HDFS・YARN・MapReduce運用基準」の主なトピックは何ですか?
HDFSの容量管理、YARNキュー設計、MapReduceジョブチューニングなど、Hadoopクラスターを安定運用するための実践基準とチェックリスト。
Q2: HDFS運用基準とは何ですか?
1.1 ブロックサイズ設定
HDFSのデフォルトブロックサイズは128MBであり、大容量ファイルを扱う環境では256MBに設定するのが一般的である。
ブロックサイズ選択基準: 1.2 レプリケーションファクター管理
デフォルトのレプリケーションファクターは3である。この値を下げるとストレージ容量を節約できるが、耐障害性が低下する。
Q3: HDFS容量計画とデータライフサイクルの核心的な概念を説明してください。
2.1 HDFSクォータ管理 ディスク使用量の暴走を防ぐため、ディレクトリごとにクォータを必ず設定する。
チーム別クォータ設計例: 2.2 データ圧縮戦略
HDFSで圧縮を適用するとストレージ容量とネットワークI/Oの両方を節約できる。 2.3 Erasure Coding(EC)
Hadoop 3.xで導入されたErasure
Codingは、レプリケーションファクター3と比較して約50%のストレージ容量を節約しつつ、同等の耐障害性を提供する。
Q4: YARNキュー設計とリソース管理について説明してください。
3.1 Capacity Scheduler vs Fair Scheduler 3.2 Capacity Schedulerキュー設計 キュー構造図: 3.3
プリエンプション設定
プリエンプションは、キューが保証されたリソースを取り戻すために他のキューのコンテナを強制終了するメカニズムである。
3.4 YARNリソース設定
Q5: MapReduceジョブチューニングはどのように実現できますか?
4.1 Mapper/Reducer数の最適化 Mapper/Reducer数の算定公式: 4.2 シャッフル最適化
シャッフルはMapReduceで最もコストの高いフェーズである。ネットワークI/OとディスクI/Oが集中する。
4.3 データスキュー処理
データスキューとは、特定のキーにデータが集中し、一部のリデューサーだけが過負荷になる現象である。