Hadoop: 分散キャッシュ展開

はじめに

MapReduceアプリケーションフレームワークには、分散キャッシュを介して新しいバージョンのMapReduceフレームワークを展開するための基本的なサポートがあります。適切な構成プロパティを設定することで、ユーザーはクラスターに最初に展開されたものとは異なるバージョンのMapReduceを実行できます。たとえば、クラスター管理者は複数のバージョンのMapReduceをHDFSに配置し、ジョブがデフォルトで使用するバージョンを指定するためにmapred-site.xmlを構成できます。これにより、管理者は特定の条件下でMapReduceフレームワークのローリングアップグレードを実行できます。

前提条件と制限事項

分散キャッシュを介したMapReduceフレームワークの展開のサポートは、現在、ジョブの送信とクエリに使用されるジョブクライアントコードには対応していません。また、各NodeManager内で補助サービスとして実行されるShuffleHandlerコードにも対応していません。その結果、ローリングアップグレード方式で分散キャッシュを介して正常に展開できるMapReduceバージョンには、次の制限が適用されます。

  • MapReduceバージョンは、ジョブの送信とクエリに使用されるジョブクライアントコードと互換性がある必要があります。互換性がない場合は、新しいMapReduceバージョンを使用するジョブが送信またはクエリされるノードで、ジョブクライアントを個別にアップグレードする必要があります。

  • MapReduceバージョンは、ジョブを送信するジョブクライアントで使用される構成ファイルと互換性がある必要があります。構成と互換性がない場合(例:新しいプロパティを設定する必要があるか、既存のプロパティ値を変更する必要がある場合)、最初に構成を更新する必要があります。

  • MapReduceバージョンは、クラスター内のノードで実行されているShuffleHandlerバージョンと互換性がある必要があります。互換性がない場合は、新しいShuffleHandlerコードをクラスター内のすべてのノードに展開し、新しいShuffleHandlerコードをピックアップするためにNodeManagerを再起動する必要があります。

分散キャッシュを介した新しい MapReduce バージョンの展開

新しいMapReduceバージョンを展開するには、3つのステップがあります。

  1. MapReduceアーカイブを、ジョブ送信クライアントがアクセスできる場所にアップロードします。理想的には、アーカイブはクラスターのデフォルトファイルシステムの、公開読み取り可能なパスにある必要があります。詳細については、以下のアーカイブの場所に関する説明を参照してください。フレームワークアップローダーツールを使用して、mapred frameworkuploader -target hdfs:///mapred/framework/hadoop-mapreduce-3.3.6.tar#mrframeworkのようにこのステップを実行できます。これにより、クラスパスにあるjarファイルが選択され、-targetおよび-fsオプションで指定されたtarアーカイブに配置されます。次に、このツールは、mapreduce.application.framework.pathおよびmapreduce.application.classpathを設定する方法の提案を返します。

    -fs:ターゲットファイルシステム。デフォルトは、fs.defaultFSで設定されたデフォルトのファイルシステムです。

    -targetは、フレームワークtarballのターゲットの場所で、オプションで、ローカライズされたエイリアスを持つ#が続きます。次に、tarを指定されたディレクトリにアップロードします。jarファイルはすでに圧縮されているため、gzipは必要ありません。ターゲットディレクトリはすべてのユーザーが読み取れるようにする必要がありますが、クラスターのセキュリティを保護するために管理者以外は書き込み可能にしないでください。

  2. アーカイブの場所を指すようにmapreduce.application.framework.pathを構成します。ジョブの分散キャッシュファイルを指定する場合と同様に、これはURLであり、URLフラグメントが指定されている場合はアーカイブのエイリアスを作成することもサポートします。たとえば、hdfs:///mapred/framework/hadoop-mapreduce-3.3.6.tar.gz#mrframeworkは、hadoop-mapreduce-3.3.6.tar.gzではなくmrframeworkとしてローカライズされます。

  3. 上記で構成したMapReduceアーカイブで使用する適切なクラスパスを設定するために、mapreduce.application.classpathを構成します。frameworkuploaderツールを使用すると、すべての依存関係がアップロードされ、ここで構成する必要がある値が返されます。注:mapreduce.application.framework.pathが構成されているが、mapreduce.application.classpathがアーカイブパスのベース名、またはエイリアスが指定されている場合はエイリアスを参照していない場合、エラーが発生します。

MapReduceアーカイブの場所は、ジョブの送信とジョブの起動パフォーマンスにとって重要になる可能性があることに注意してください。アーカイブがクラスターのデフォルトファイルシステムにない場合、各ジョブのジョブステージングディレクトリにコピーされ、ジョブのタスクが実行される各ノードにローカライズされます。これにより、ジョブの送信とタスクの起動パフォーマンスが低下します。

アーカイブがデフォルトファイルシステムにある場合、ジョブクライアントは各ジョブ送信のジョブステージングディレクトリにアーカイブをアップロードしません。ただし、アーカイブパスがすべてのクラスターユーザーが読み取れない場合、アーカイブはタスクが実行される各ノードでユーザーごとに個別にローカライズされます。これにより、分散キャッシュで不必要な重複が発生する可能性があります。

大規模なクラスターを使用する場合は、アーカイブの可用性を高めるためにレプリケーション係数を増やすことが重要になる場合があります。これにより、クラスター内のノードがアーカイブを初めてローカライズするときに負荷が分散されます。

上記で説明したframeworkuploaderツールには、パフォーマンスの調整に役立つ追加のパラメーターがあります。

-initialReplication:これは、フレームワークtarballが作成される際のレプリケーション数です。この値はデフォルトの3のままにしておくのが安全です。これはテスト済みのシナリオです。

-finalReplication:アップローダーツールは、すべてのブロックが収集されてアップロードされた後、レプリケーションを設定します。初期起動を迅速に行う必要がある場合は、これをコミッション済みノード数を2で割った値で、ただし512以下に設定することをお勧めします。これにより、HDFSを利用して、分散方式でtarballが分散されます。ジョブが開始されると、ローカライズのためにローカルHDFSノードにヒットするか、追加のソースノードの広いセットから選択する可能性があります。これが10などの低い値に設定されている場合、それらの複製されたノードの出力帯域幅は、最初のジョブの実行速度に影響を与えます。ディスク容量を節約するために、クラスターで開始されたすべてのジョブが完了したら、レプリケーション数を10などの低い値に手動で減らすことができます。

-acceptableReplication:このツールは、tarballがこの回数だけ複製されるまで待機してから終了します。これは、finalReplicationの値以下のレプリケーション数である必要があります。これは通常、finalReplicationの値の90%であり、ノードの障害に対応するためです。

-timeout:ツールが終了するまでにacceptableReplicationに達するのを待つタイムアウト時間(秒単位)。そうでない場合、ツールはエラーをログに記録して戻ります。

MapReduceアーカイブとクラスパスの構成

MapReduceアーカイブの適切なクラスパスの設定は、アーカイブの構成と、追加の依存関係があるかどうかによって異なります。たとえば、アーカイブにはMapReduce jarだけでなく、必要なYARN、HDFS、およびHadoop Common jar、およびその他のすべての依存関係を含めることができます。その場合、mapreduce.application.classpathは、次の例のようなものに構成されます。ここで、アーカイブのベース名はhadoop-mapreduce-3.3.6.tar.gzであり、アーカイブは標準のHadoopディストリビューションアーカイブと同様に内部的に編成されています。

$HADOOP_CONF_DIR,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/common/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/common/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/yarn/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/yarn/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/hdfs/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/hdfs/lib/*

別の考えられるアプローチとしては、アーカイブをMapReduceのjarのみで構成し、残りの依存関係をノードにインストールされたHadoopディストリビューションから取得するという方法があります。その場合、上記の例は次のように変わります。

$HADOOP_CONF_DIR,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/lib/*,$HADOOP_COMMON_HOME/share/hadoop/common/*,$HADOOP_COMMON_HOME/share/hadoop/common/lib/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*,$HADOOP_YARN_HOME/share/hadoop/yarn/*,$HADOOP_YARN_HOME/share/hadoop/yarn/lib/*

frameworkuploaderツールには、フレームワークのtarballにどのjarを含めるかを制御するための以下の引数があります。

-input: これは、反復処理される入力クラスパスです。見つかったjarファイルはtarballに追加されます。デフォルトでは、hadoop classpathコマンドによって返されるクラスパスになります。

-blacklist: これは、クラスパスから除外するjarファイル名をフィルタリングするための、カンマ区切りの正規表現配列です。たとえば、テストjarやローカライズに不要なHadoopサービスを除外するために使用できます。

-whitelist: これは、特定のjarファイルを含めるための、カンマ区切りの正規表現配列です。これは、ツール実行時に外部ソースがクラスパスに悪意のあるコードを含めることを防ぐための、追加のセキュリティを提供するために使用できます。

-nosymlink: このフラグは、同じディレクトリを指すシンボリックリンクを除外するために使用できます。これはあまり広くは使用されていません。たとえば、/a/foo.jar/a/foo.jarを指すシンボリックリンク/a/bar.jarがある場合、通常はfoo.jarbar.jarが別々のファイルとしてtarballに追加されますが、実際には同じファイルです。このフラグを使用すると、ツールは/a/bar.jarを除外し、ファイルのコピーが1つだけ追加されるようにします。

クラスタでシャッフル暗号化も有効になっている場合、MRジョブが以下のような例外で失敗するという問題が発生する可能性があります。

2014-10-10 02:17:16,600 WARN [fetcher#1] org.apache.hadoop.mapreduce.task.reduce.Fetcher: Failed to connect to junpingdu-centos5-3.cs1cloud.internal:13562 with 1 map outputs
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.setNewClient(AbstractDelegateHttpsURLConnection.java:81)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.setNewClient(AbstractDelegateHttpsURLConnection.java:61)
    at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:584)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1193)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
    at org.apache.hadoop.mapreduce.task.reduce.Fetcher.verifyConnection(Fetcher.java:427)
....

これは、MRクライアント(HDFSからデプロイ)が$HADOOP_CONF_DIRディレクトリ下のローカルFSにあるssl-client.xmlにアクセスできないためです。この問題を解決するには、前述のように「mapreduce.application.classpath」で指定されているMRのクラスパスにssl-client.xmlがあるディレクトリを追加できます。MRアプリケーションが他のローカル構成の影響を受けないように、ssl-client.xmlを配置するための専用ディレクトリを作成するのが良いでしょう。例えば、$HADOOP_CONF_DIRの下のサブディレクトリ(例:$HADOOP_CONF_DIR/security)などです。

フレームワークアップロードツールは、MapReduce AM、mapper、reducerが使用するクラスタjarを収集するために使用できます。推奨される設定値を提供するログを返します。

INFO uploader.FrameworkUploader: Uploaded hdfs://mynamenode/mapred/framework/mr-framework.tar#mr-framework
INFO uploader.FrameworkUploader: Suggested mapreduce.application.classpath $PWD/mr-framework/*

mapreduce.application.framework.pathを最初のログ値に、mapreduce.application.classpathを上記の2番目のログ値にそれぞれ設定します。