HDFSのメンテナンスステート
原文: http://blog.cloudera.com/blog/2017/05/hdfs-maintenance-state/
はじめに:
OSの更新、セキュリティパッチの適用、修正プログラムなどのシステムのメンテナンス作業は、どのデータセンターでも日常的な作業です。 このようなメンテナンス作業を行っている最中のDataNodeは、数分から数時間の間オフラインになる可能性があります。 設計上、Apache HadoopのHDFSはDataNodeのダウンに対応できますが、同時に複数のDataNodeで調整されていないメンテナンス操作があれば、一時的にデータ可用性の問題を引き起こす可能性があります。 HDFSは現在、計画された保守作業を実行するために次の機能をサポートしています:
- ローリングアップグレード
- デコミッション
- メンテナンスステート (CDH 5.11以降)
ローリングアップグレードの処理は、クラスタをオフラインにすることなく、クラスタのソフトウェアを更新するのに役立ちます。同じラック、または異なるラックの多数のDataNodeが更新のためにダウンした場合、ブロックおよびファイルのレプリカの可用性が損なわれないようにDataNodeを選択することが望ましいです。しかし、それを実現する簡単な方法はありません。
HDFSはデコミッション機能をサポートし、バッチでのローリングアップグレードのシナリオの間に発生したデータの可用性の問題を軽減します。DataNodeに対してデコミッションが要求されると、NameNodeは、それらのブロックのすべてが他の生存している(ライブの)DataNodeに複製され、グローバルのブロック複製の設定、 dfs.replication
プロパティまたはファイル固有の複製の設定を満たすようにdecommission in-progress(デコミッション進行中)の状態に遷移させます。これらのレプリカのすべてが他のDataNodeに十分に複製されると、Decommission in-progressのDataNodeは、最終的にDecommissioned(デコミッション完了)状態に遷移します。
デコミッションが複数のDataNodeで同時に実行されるようなケースでは、実行対象となるそれらのDataNodeのすべてのブロックに対して十分な複製を完了するため、時間がかかることがあります。この一例は、ラック全体でメンテナンス作業を行う場合です。また、クラスタ内のネットワーク使用量が増え、パフォーマンスのSLAに影響する可能性があります。
メンテナンスステート
Upstream JIRA: HDFS-7877
設計: ドキュメント
新しい機能である「HDFSのメンテナンスステート」は、ローリングアップグレードとデコミッション機能の欠点を克服し、計画されたメンテナンス作業をよりシームレスに行うことを目指しています。メンテナンスステート機能は HDFSのDataNodeロールにのみ適用されます。
メンテナンスステート機能は、ブロック複製係数が一時的に設定されているレベル未満になることを許容することで、ブロックの不必要な複製を回避します。つまり、メンテナンス作業を要求するDataNodeのブロックに対して、すぐに複製をスケジュールすることはありません。これらのDataNodeがメンテナンスのために停止しても、クラスターは、グローバルのブロック複製係数またはファイル固有の複製係数によって設定されている望ましいレベルではなく、レプリカの最小複製係数(設定可能、後述)を用いて実行を継続します。
バッチでのローリングアップグレードやトップオブラックスイッチの修復のような短いメンテナンス作業は、この機能に最適なユースケースの一つです。
この機能の詳細の前に、まずは設定を見てみましょう。
設定:
dfs.namenode.maintenance.replication.min:
このNameNodeの設定は、メンテナンス中のDataNodeのすべてのブロックが満たす必要のある生存しているレプリカの最小数を定義します。メンテナンス状態のDataNodeは、これらのブロックのすべてが、他の稼動中のDataNodeに少なくともこの最小数のレプリカがある場合、複製はトリガーされません。 それ以外の場合、この基準を満たすために複製がトリガーされます。 このプロパティに設定できる値の範囲は[0
から dfs.replication
]です。
dfs.namenode.maintenance.replication.min
が1の場合、メンテナンス中のDataNodeに属するブロックが設定された期間、レプリカがどこかに一つ生存していればクラスタが機能できることを意味します。メンテナンス状態に移行しようとしているDataNodeにのみブロックが存在するような場合、この機能によって別のDataNodeに確実にブロックを複製し、可用性を担保します。
dfs.namenode.maintenance.replication.min
がグローバルの複製係数と等しい場合、DataNodeがメンテナンス中であっても、クラスタはdfs.replication
のレプリカのブロックを必要とします。メンテナンスステート機能は、再複製をトリガするデコミッション機能のように動作します。
dfs.namenode.maintenance.replication.min
が0の場合、NameNodeはメンテナンス中のDataNodeのブロックの最小複製係数を確認しません。レプリカのスキャンを避けることでメンテナンス作業を高速化するために、管理者はdfs.namenode.maintenance.replication.min
に0を設定することを好むかもしれませんが、これによりデータに到達できなくなるリスクが高くなります。
dfs.namenode.hosts.provider.classname:
このNameNodeの設定は、ホストのファイルへのアクセスを提供するクラスを指定します。メンテナンスステート機能に先立って、DataNodeは dfs.hosts
設定プロパティで、指定されたインクルードホストファイルを用いてDataNodesを(再)コミッションし、 dfs.hosts.exclude
設定プロパティを用いて指定されたエクスクルードファイルでDataNodeをデコミッションします。これらのファイルは値にカンマ区切りのホスト名やIPアドレスを使用する単純なフォーマットです。org.apache.hadoop.hdfs.server.blockmanagement.HostFileManager
がデフォルトで使用され dfs.hosts
と dfs.hosts.exclude
に指定されたファイルをロードします。
これらの古いファイル形式は後方互換性のため拡張できません。新しいメンテナンスステート機能は、DataNodeをインクルードおよびエクスクルード(exclude)(デコミッションとメンテナンスステート)の両方に用いることができる、JSON形式の新しい結合ホストファイル(combined hosts file)を使用します。メンテナンスステート機能は、この新しい結合ホストファイルでのみサポートされます。dfs.hosts
に定義されるJSONファイルをロードするために、プロバイダのクラス名は org.apache.hadoop.hdfs.server.blockmanagement.CombinedHostFileManager
である必要があります。
これは結合ホストファイルの形式です。
adminState
はhostName
のDataNodeが遷移したい状態を示します。許可される状態は次の通りです:
NORMAL
DECOMMISSIONED
IN_MAINTENANCE
maintenanceExpireTimeInMS
はメンテナンスの有効期限であり、有効期限に達すると、対応するDataNodeの内部状態はNameNode内でNORMAL
に戻り、メンテナンスの最小値はもはや有効ではないため複製が発生する可能性があります。このメンテンスの有効期限の設定はDataNode固有であり、DataNode毎に異なる場合があります。完全なOSの更新が必要なDataNodeは、ホットフィックスのために素早い再起動を必要とするDataNodeに比べ、長い有効期限が必要かもしれません。 メンテナンスの有効期限はエポックからのミリ秒単位で表現されます。
実際の操作:
ユースケース、信頼性、およびパフォーマンスの要件に基づいて、dfs.namenode.maintenance.replication.min
に最適な値を特定します。 dfs.namenode.maintenance.replication.min
は次の例のように構成する必要があります。
メンテナンスステート機能は新しい結合ホストファイル形式でのみサポートされます。ホストファイルプロバイダを設定して下さい:
dfs.hosts
プロパティを用いて結合ホストファイルの場所を指定します。
上記のすべての値の変更を有効にするにはNameNodeの再起動が必要です。メンテナンス作業の前に上記のパラメータを決定することを推奨します。 下記のように、メンテナンス操作を必要とするDataNodeの結合ホストファイル/etc/hadoop/conf/maintenance
を更新します。
datanode-100、datanode-101、およびdatanode-102の1時間のメンテナンスウィンドウでは、メンテナンスの有効期限は次のように計算されます。
結合ホストファイルを更新した後、次のコマンドを実行して、NameNodeがノードリストをリフレッシュし、指定されたDataNodeのメンテナンスステートの遷移を開始するようにトリガーします。
namenode-host$ hdfs dfsadmin -refreshNodes
メンテナンスステートに遷移するDataNodeの状態はNameNodeのWebUIのsummaryページで監視できます。DataNodeが IN_MAINTENANCE
状態に遷移すると、メンテナンス作業を行うためにクラスタから安全に外すことができます。
メンテナンス操作を完了したDataNodeをクラスタに再び参加できるようにするには、同じ結合ホストファイルでrefreshNodes 管理操作を繰り返しますが、以下のようにDataNodeのadminState
をNORMAL
に更新します。
メンテナンス機能の詳細:
NameNodeは、メンテナンス操作を要求しているDataNodeにあるブロックが、メンテナンスステートの最小複製の設定 dfs.namenode.maintenance.replication.min
に従って十分に複製されていることを確認します。この一時的な待機期間は、ENTERING_MAINTENANCE
状態と呼ばれます。ブロックが十分に複製されると、DataNodeは最終的な安全状態に移行し、クラスタから削除できる状態になります。この最終的な安全状態はIN_MAINTEANCE
状態と呼ばれます。
dfs.namenode.maintenance.replication.min
を0にセットした場合、DataNodeはIN_MAINTENANCE
に直接遷移します。状態の遷移の観点から、ENTERING_MAINTENANCE => IN_MAINTENANCE
は DECOMMISSION_INPROGRESS => DECOMMISSIONED
と似ています。メンテナンスステートの場合は十分な複製を確認するためにdfs.namenode.replication.maintenance.min
プロパティが使用され、デコミッションの場合はファイルの複製係数が使用されます。
非常に単純化した状態遷移を下記の絵に示します。状態遷移とイベントの詳細の図は設計ドキュメントを参照してください。
ENTERING_MAINTENANCE
、IN_MAINTENANCE
、DECOMMISSION_INPROGRESS
、またはDECOMMISSIONED
の4つの状態のいずれかにあるDataNodeは、サービスを提供できないノードと呼ばれます。
- 書き込み要求の場合、アウトオブサービスノードは完全に遮断されます。 デフォルトのブロック配置ポリシーは、すべてのアウトオブサービスのDataNodeをレプリカの候補からスキップします。読み込み要求の場合、アウトオブサービスノードは部分的に遮断されます。ブロック読み出し要求に対して、BlockManagerは
IN_MAINTENANCE
ノードは除外してLocatedBlock
を返しますが、依然として生存しているENTERING_MAINTENANCEノードは含むことができます。ENTERING_MAINTENANCE
のDataNodeは、進行中の読み取りおよび書き込み要求を引き続き提供します。 - NameNodeのBlockMapは
ENTERING_MAINTENANCE
およびIN_MAINTENANCE
のDataNodeからのすべてのブロックを保持し続けるため、ブロックレプリケーションの観点からは有効なレプリカと見なされます。NameNodeは、これらのノードが死んでいるか生きているかにかかわらず、メンテナンスステート満了期限前にこれらのDataNodeのブロックを無効にしません。 - ディスクバランサーとMoverは、ブロック移動ではアウトオブサービスのDataNodeを回避します。
主な欠点:
dfs.namenode.maintenance.replication.min
が1の場合、唯一のレプリカをホストするDataNodeが一時的にダウンすると、データの可用性の問題が発生する可能性があります。また、レプリカに対するすべての読み取り要求を処理する単一のDataNodeがパフォーマンスの問題を引き起こす可能性があります。したがって、多くのDataNodeで同時にメンテナンス作業を行う場合、上記の問題を回避するために、dfs.namenode.maintenance.replication.min
を2に設定することを推奨します。
結論:
メンテナンスステート機能のHDFS-7877は、DataNodeの迅速なメンテナンス作業を行う際、ローリングアップグレードとデコミッションの機能の複雑さとパフォーマンスの不利益を克服しています。CDH5.11に含まれているHDFSのバージョンではこのメンテナンスステート機能を完全にサポートしています。
謝辞:
HDFS-7877はTwitterのMing Ma、およびClouderaのManoj Govindasamy, Lei (Eddy) Xuによって共同開発されました。