LabHub

ブログ

Hadoopエコシステム実践ガイド:HDFS・YARN・MapReduce運用基準

한국어English日本語

Hadoopエコシステム実践ガイド:HDFS・YARN・MapReduce運用基準

はじめに

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>

ブロックサイズ選択基準:

基準128MB256MB
平均ファイルサイズ数百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"

レプリケーションファクター運用ポリシー例:

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運用ルール:


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/50TB5,000,000ETLパイプライン
MLチーム/data/ml/30TB2,000,000学習データ
分析チーム/data/analytics/20TB1,000,000集計結果
一時領域/data/tmp/5TB500,0007日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適用時の注意事項:

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 SchedulerFair Scheduler
デフォルトApache HadoopCDH
リソース保証キューごとの最小容量保証重み付け均等分配
プリエンプションサポートサポート
マルチテナンシー強い(階層型キュー)普通
設定の複雑さ高い普通

推奨: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

スキュー解消方法:

  1. ソルティング:キーにランダムなプレフィックスを付けて分散
// マッパーでキーにソルトを追加
int salt = random.nextInt(10);
outputKey.set(salt + "_" + originalKey);

// 第1MR:ソルトキーで部分集計
// 第2MR:ソルト除去後に最終集計
  1. Combinerの適用:マッパー出力をローカルで事前集計
job.setCombinerClass(MyCombiner.class);
  1. パーティショナーのカスタマイズ:データ分布を考慮したパーティショニング
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, SNMPSMTP, 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 -blocksCorruptブロック 0
Balancer実行hdfs balancer -threshold 5ノード間偏差 < 5%
YARNログ整理yarn logs -applicationId ... -am30日以上のログ削除
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 データスキュー処理 データスキューとは、特定のキーにデータが集中し、一部のリデューサーだけが過負荷になる現象である。

コメント

まだコメントはありません。

ログインするとコメントできます