ジョブリソース要件の推定は、エンタープライズクラスターにとって重要かつ困難な問題です。これは、ワークロードの複雑さが増大していること、つまり従来のバッチジョブからインタラクティブクエリ、ストリーミング、そして最近では機械学習ジョブへと変化していることによって、さらに増幅されています。そのため、ジョブは Tez、MapReduce、Spark などの複数の計算フレームワークに依存するようになり、クラスターの共有性によって問題はさらに複雑化しています。現在の最先端のソリューションは、ジョブのリソース要件(例:リデューサーの数やコンテナのメモリサイズなど)の推定にユーザーの専門知識に依存しており、これは面倒で非効率的です。
クラスターワークロードの分析に基づくと、ジョブの大部分(60%以上)が繰り返しジョブであることが観察されており、ジョブの履歴実行に基づいてジョブリソース要件を自動的に推定できる可能性があります。ジョブは通常、異なる計算フレームワークから発生し、バージョンも実行ごとに変更される可能性があることに注意することが重要です。したがって、繰り返しジョブのリソース要件推定を自動的に行うための、フレームワークに依存しないブラックボックスソリューションを考案する必要があります。
次の図は、リソース推定機能の実装アーキテクチャを示しています。
Hadoop-resourceestimator は、主に Translator、SkylineStore、Estimator の 3 つのモジュールで構成されています。
ResourceSkyline
は、ジョブのライフサイクル中のリソース使用量を特徴付けるために使用されます。具体的には、RLESparseResourceAllocation
(https://github.com/apache/hadoop/blob/b6e7d1369690eaf50ce9ea7968f91a72ecb74de0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/RLESparseResourceAllocation.java) を使用して、コンテナの割り当て情報を記録します。 RecurrenceId
は、繰り返しパイプラインの特定の実行を識別するために使用されます。パイプラインは複数のジョブで構成され、それぞれにリソース使用量を特徴付ける ResourceSkyline
があります。Translator
はジョブログを解析し、それらの ResourceSkylines
を抽出して SkylineStore に格納します。 SingleLineParser
は、ログストリームの 1 行を解析し、ResourceSkyline
を抽出します。 LogParser
は、SingleLineParser
を使用してログストリームの各行を再帰的に解析します。ログはさまざまなストレージ形式を持つ可能性があるため、LogParser
は File やその他の形式ではなく、文字列のストリームを入力として受け取ります。ジョブログはさまざまな形式を持つ可能性があり、それぞれ異なる SingleLineParser
実装が必要になるため、LogParser
はユーザー設定に基づいて SingleLineParser
を初期化します。現在、Hadoop-resourceestimator は SingleLineParser
の 2 つの実装を提供しています。NativeSingleLineParser
は最適化されたネイティブ形式をサポートし、RMSingleLineParser
は Hadoop システムで生成された YARN ResourceManager ログを解析します。RM ログは広く利用可能であるためです(本番環境のデプロイメント)。SkylineStore
は Hadoop-resourceestimator のストレージ層として機能し、2 つの部分で構成されています。 HistorySkylineStore
は、Translator
によって抽出された ResourceSkylines
を格納します。 addHistory、deleteHistory、updateHistory、getHistory の 4 つのアクションをサポートしています。 addHistory は、繰り返しパイプラインに新しい ResourceSkylines
を追加し、updateHistory は特定の繰り返しパイプラインのすべての ResourceSkylines
を削除し、新しい ResourceSkylines
を再挿入します。 PredictionSkylineStore
は、Estimator によって生成された予測された RLESparseResourceAllocation
を格納します。 addEstimation と getEstimation の 2 つのアクションをサポートしています。
現在、Hadoop-resourceestimator は SkylineStore のインメモリ実装を提供しています。
Estimator
は、履歴実行に基づいて繰り返しパイプラインのリソース要件を予測し、予測を SkylineStore
に格納し、YARN に繰り返しリソース予約を行います(YARN-5326)。 Solver
は、特定の繰り返しパイプラインのすべての履歴 ResourceSkylines
を読み取り、RLESparseResourceAllocation
にラップされた新しいリソース要件を予測します。現在、Hadoop-resourceestimator は予測を行うために LPSOLVER
を提供しています(線形計画法モデルの詳細は論文を参照してください)。また、予測されたリソース要件を ReservationSubmissionRequest
に変換する BaseSolver
もあります。これは、YARN で繰り返しリソース予約を行うために、さまざまなソルバー実装で使用されます。ResourceEstimationService
は、Hadoop-resourceestimator をマイクロサービスとしてラップし、クラスターに簡単にデプロイできます。指定されたジョブログの解析、パイプラインの履歴 ResourceSkylines
のクエリ、パイプラインの予測リソース要件のクエリ、予測が存在しない場合の SOLVER
の実行、SkylineStore
内の ResourceSkylines
の削除をユーザーが行うための一連の REST API を提供します。このセクションでは、リソース推定サービスの使用方法について説明します。
ここで、$HADOOP_ROOT
は Hadoop のインストールディレクトリを表すとします。Hadoop を自分でビルドする場合、$HADOOP_ROOT
は hadoop-dist/target/hadoop-$VERSION
です。リソース推定サービスの場所である $ResourceEstimatorServiceHome
は、$HADOOP_ROOT/share/hadoop/tools/resourceestimator
です。これには、bin
、conf
、data
の 3 つのフォルダーが含まれています。ユーザーはデフォルト設定でリソース推定サービスを使用できることに注意してください。
bin
には、リソース推定サービスの実行スクリプトが含まれています。
conf
:リソース推定サービスの設定ファイルが含まれています。
data
には、リソース推定サービスの例を実行するために使用されるサンプルログが含まれています。
まず、設定ファイル($ResourceEstimatorServiceHome/conf/
にあります)を $HADOOP_ROOT/etc/hadoop
にコピーします。
推定機能を起動するためのスクリプトは start-estimator.sh
です。
$ cd $ResourceEstimatorServiceHome $ bin/start-estimator.sh
Web サーバーが起動され、ユーザーは REST API を介してリソース推定サービスを使用できます。
リソース推定サービスの URI は http://0.0.0.0
で、デフォルトのサービスポートは 9998
です($ResourceEstimatorServiceHome/conf/resourceestimator-config.xml
で設定されています)。 $ResourceEstimatorServiceHome/data
には、tpch_q12 クエリジョブの 2 回の実行のログが含まれているサンプルログファイル resourceEstimatorService.txt
があります。
ジョブログの解析:POST http://URI:port/resourceestimator/translator/LOG_FILE_DIRECTORY
POST http://0.0.0.0:9998/resourceestimator/translator/data/resourceEstimatorService.txt
を送信します。基盤となる推定機能は、ログファイルから ResourceSkylines を抽出し、jobHistory SkylineStore に格納します。
ジョブの履歴 ResourceSkylines のクエリ:GET http://URI:port/resourceestimator/skylinestore/history/{pipelineId}/{runId}
GET http://0.0.0.0:9998/resourceestimator/skylinestore/history/*/*
を送信すると、基盤となる推定器は履歴 SkylineStore 内のすべてのレコードを返します。tpch_q12 の 2 回の実行(tpch_q12_0 と tpch_q12_1)の ResourceSkylines を確認できるはずです。pipelineId
フィールドと runId
フィールドはどちらもワイルドカード操作をサポートしていることに注意してください。
ジョブのリソーススカイライン要件を予測する: GET http://URI:port/resourceestimator/estimator/{pipelineId}
http://0.0.0.0:9998/resourceestimator/estimator/tpch_q12
を送信すると、基盤となる推定器は履歴 ResourceSkylines に基づいて新しい実行のジョブリソース要件を予測し、予測されたリソース要件を jobEstimation SkylineStore に保存します。
ジョブの推定リソーススカイラインを照会する: GET http://URI:port/resourceestimator/skylinestore/estimation/{pipelineId}
http://0.0.0.0:9998/resourceestimator/skylinestore/estimation/tpch_q12
を送信すると、基盤となる推定器は tpch_q12 ジョブの履歴リソース要件推定を返します。jobEstimation SkylineStore では、ワイルドカード操作はサポートされていないことに注意してください。
ジョブの履歴リソーススカイラインを削除する: DELETE http://URI:port/resourceestimator/skylinestore/history/{pipelineId}/{runId}
http://0.0.0.0:9998/resourceestimator/skylinestore/history/tpch_q12/tpch_q12_0
を送信すると、基盤となる推定器は tpch_q12_0 の ResourceSkyline レコードを削除します。GET http://0.0.0.0:9998/resourceestimator/skylinestore/history/*/*
を再送信すると、基盤となる推定器は tpch_q12_1 の ResourceSkyline のみを返します。
推定器を停止するスクリプトは stop-estimator.sh
です。
$ cd $ResourceEstimatorServiceHome $ bin/stop-estimator.sh
ここでは、リソース推定サービスの使用例を紹介します。
まず、tpch_q12 ジョブを 9 回実行し、各実行でジョブのリソーススカイラインを収集します(この例では、「割り当てられたコンテナの数」情報のみを収集していることに注意してください)。
次に、リソース推定サービスのログパーサーを実行して、ログから ResourceSkylines を抽出し、SkylineStore に保存します。ジョブの ResourceSkylines は、デモンストレーションのために以下にプロットされています。
最後に、リソース推定サービスの推定器を実行して、新しい実行のリソース要件を予測します。これは RLESparseResourceAllocation(https://github.com/apache/hadoop/blob/b6e7d1369690eaf50ce9ea7968f91a72ecb74de0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/reservation/RLESparseResourceAllocation.java)にラップされています。予測されたリソース要件は、デモンストレーションのために以下にプロットされています。
このセクションでは、リソース推定サービスの設定について説明します。設定ファイルは $ResourceEstimatorServiceHome/conf/resourceestimator-config.xml
にあります。
resourceestimator.solver.lp.alpha
リソース推定器には、予測を行うための統合線形計画法ソルバーが組み込まれています(詳細については、https://www.microsoft.com/en-us/research/wp-content/uploads/2016/10/osdi16-final107.pdf を参照してください)。このパラメーターは、線形計画法モデルにおけるリソースの過剰割り当てと過少割り当てのトレードオフを調整します。このパラメーターは 0 から 1 の範囲で変化し、alpha 値が大きいほど、モデルは過剰割り当てをより適切に最小化します。デフォルト値は 0.1 です。
resourceestimator.solver.lp.beta
このパラメーターは、線形計画法モデルの一般化を制御します。このパラメーターは 0 から 1 の範囲で変化します。デフォルト値は 0.1 です。
resourceestimator.solver.lp.minJobRuns
予測を行うために必要なジョブ実行の最小数。デフォルト値は 2 です。
resourceestimator.timeInterval
ジョブ実行をインターバルに離散化するために使用される時間の長さ。推定器は各インターバルのリソース割り当て予測を行うことに注意してください。時間間隔が小さいほど、予測の粒度が細かくなりますが、予測にかかる時間とスペースも増加します。デフォルト値は 5(秒)です。
resourceestimator.skylinestore.provider
skylinestore プロバイダーのクラス名。デフォルト値は、skylinestore のメモリ内実装である org.apache.hadoop.resourceestimator.skylinestore.impl.InMemoryStore
です。ユーザーが独自の skylinestore 実装を使用する場合、この値を適宜変更する必要があります。
resourceestimator.translator.provider
トランスレータープロバイダーのクラス名。デフォルト値は、ログストリームから resourceskylines を抽出する org.apache.hadoop.resourceestimator.translator.impl.BaseLogParser
です。ユーザーが独自のトランスレーター実装を使用する場合は、この値を適宜変更する必要があります。
resourceestimator.translator.line-parser
ログの 1 行を解析するトランスレーターの単一行パーサークラス名。デフォルト値は、サンプルログの 1 行を解析できる org.apache.hadoop.resourceestimator.translator.impl.NativeSingleLineParser
です。Hadoop Resource Manager(https://hadoop.dokyumento.jp/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html)ログを解析する場合は、値を org.apache.hadoop.resourceestimator.translator.impl.RmSingleLineParser
に設定する必要があることに注意してください。カスタマイズされたログファイルを解析するための単一行パーサーを実装する場合は、この値を適宜変更する必要があります。
resourceestimator.solver.provider
ソルバープロバイダーのクラス名。デフォルト値は、予測を行うために線形計画法モデルを組み込んだ org.apache.hadoop.resourceestimator.solver.impl.LpSolver
です。ユーザーが独自のモデルを実装する場合は、この値を適宜変更する必要があります。
resourceestimator.service-port
ResourceEstimatorService が listen するポート。デフォルト値は 9998 です。
SkylineStore については、永続ストアの実装を提供する予定です。将来のスケール要件に対応するために、HBase を検討しています。
Translator モジュールについては、安定した API に依存したいと考えており、ログは不安定であるため、Timeline Service v2 をプライマリソースとしてサポートしたいと考えています。
ジョブリソース要件は、歪み、競合、入力データまたはコードの変更などにより、実行間で異なる場合があります。実行時にジョブの進捗状況を動的に監視し、進捗状況が予想よりも遅い場合にパフォーマンスボトルネックを特定し、ReservationUpdateRequest を使用してジョブのリソース割り当てを動的に調整する Reprovisioner モジュールを設計したいと考えています。
Estimator がジョブリソース要件を予測する場合、推定誤差(過剰割り当てと過少割り当ての組み合わせ)などに応じて、予測に関連付けられた信頼レベルを提供したいと考えています。
Estimator モジュールについては、強化学習などの機械学習ツールを統合して、より良い予測を行うことができます。また、PerfOrator などのドメイン固有のソルバーと統合して、予測品質を向上させることもできます。
Estimator モジュールについては、新しいログのみに基づいてジョブリソース要件を増分的に更新できる増分ソルバーを設計したいと考えています。