YARNでのSparkの構成

こんにちは、こんにちは! 昨日、Rambler&CoのメンバーからのApache Sparkミーティングで、このツールの構成に関連する参加者からの質問がかなりありました。 私たちは彼の経験から彼らの経験を共有することにしました。 トピックは単純ではありません。したがって、コメントで経験を共有することをお勧めします。何かを誤解して使用することもできます。



小さな紹介-Sparkの使用方法。 3か月のプログラム「ビッグデータスペシャリスト」と2番目のモジュール全体があり、参加者はこのツールに取り組んでいます。 したがって、オーガナイザーとしてのタスクは、そのような場合に使用するクラスターを準備することです。



私たちの使用の特殊性は、Sparkで同時に作業する人の数がグループ全体に等しくなる可能性があることです。 たとえば、セミナーで、全員が同時に何かを試して、教師の後に繰り返します。 そして、これは少し、たくさんです-時々40人未満。 おそらく、このようなユースケースに直面している企業は世界中にあまりありません。



次に、これらまたは他の構成パラメーターを選択した方法と理由を説明します。



最初から始めましょう。 Sparkには、クラスターで作業するための3つのオプションがあります。スタンドアロン、Mesosの使用、YARNの使用です。 私たちにとっては論理的であるため、3番目のオプションを選択することにしました。 すでにhadoopクラスターがあります。 参加者はすでにそのアーキテクチャに精通しています。 糸を使いましょう。



spark.master=yarn
      
      





さらに興味深い。 これら3つの展開オプションにはそれぞれ、クライアントとクラスターの2つの展開オプションがあります。 インターネット上のドキュメントとさまざまなリンクに基づいて、クライアントは対話型の作業に適していると結論付けることができます。たとえば、jupyterノートブックを使用し、クラスターは実稼働ソリューションに適しています。 私たちの場合、インタラクティブな仕事に興味がありました。



 spark.deploy-mode=client
      
      





一般的に、これからはSparkがYARNで何らかの形で機能しますが、これでは十分ではありませんでした。 ビッグデータに関するプログラムがあるため、参加者はリソースの均一なカットの一部として得られたものを欠いている場合がありました。 そして、ここで興味深いことがわかりました-リソースの動的な割り当て。 要するに、結論は次のとおりです。困難なタスクがあり、クラスターが空いている場合(たとえば午前中)、このオプションを使用すると、追加のリソースが得られます。 必要性は巧妙な公式によってそこに考慮されます。 詳細は説明しません-うまくいきます。



 spark.dynamicAllocation.enabled=true
      
      





このパラメーターを設定しましたが、起動時にSparkは呪われて起動しませんでした。 ドキュメントを注意深く読む必要があるためです。 すべてが正常であるためには、追加のパラメーターも有効にする必要があると記載されています。



 spark.shuffle.service.enabled=true
      
      





なぜ必要なのですか? ジョブがそれほど多くのリソースを必要としなくなったら、Sparkはそれらを共通プールに戻す必要があります。 ほとんどすべてのMapReduceタスクで最も時間のかかるステージはシャッフルステージです。 このパラメーターを使用すると、この段階で生成されたデータを保存し、それに応じてエグゼキューターを解放できます。 また、executorはワーカーのすべてを計算するプロセスです。 一定数のプロセッサコアと一定量のメモリがあります。



このオプションを追加しました。 すべてが機能しているように見えました。 参加者には、必要なときに本当に多くのリソースが与えられるようになったことが明らかになりました。 しかし、別の問題が発生しました-ある時点で、他の参加者が目を覚まし、Sparkを使用したかったため、すべてが忙しく、不満でした。 それらは理解できます。 彼らはドキュメントを見始めました。 プロセスに影響を与えることができるいくつかのパラメーターがまだあることが判明しました。 たとえば、エグゼキュータがスタンバイモードの場合-エクゼキュータは何時間後にそこからリソースを取得できますか?



 spark.dynamicAllocation.executorIdleTimeout=120s
      
      





私たちの場合、エグゼキュータが2分間何もしない場合は、一般的なプールに返してください。 しかし、このパラメーターは必ずしも十分ではありませんでした。 人が長い間何もしておらず、リソースが解放されていないことは明らかでした。 特別なパラメーターがまだあることが判明しました-その後、キャッシュされたデータを含むエグゼキューターを選択します。 デフォルトでは、このパラメーターは-無限大です! 彼を修正しました。



 spark.dynamicAllocation.cachedExecutorIdleTimeout=600s
      
      





つまり、executorが5分間何もしない場合は、それらを共有プールに渡します。 このモードでは、多数のユーザーに対してリソースを解放および発行する速度が適切になりました。 不満の量は減少しました。 しかし、さらに先に進み、エグゼキュータの最大数を1つのアプリケーション、実際にはプログラムの1人の参加者に制限することにしました。



 spark.dynamicAllocation.maxExecutors=19
      
      





今、もちろん、不満が現れました-「クラスターはアイドル状態で、19人のエグゼキューターしかいません」が、何をすべきか-何らかの適切なバランスが必要です。 みんなを幸せにするのはうまくいきません。



そして、私たちのケースの詳細に関連するもう1つの小さな話です。 どういうわけか、実際のレッスンに遅れた人が何人かいましたが、どういうわけかSparkは彼らから始めませんでした。 無料のリソースの量を調べました-そこにあるようです。 Sparkが起動します。 幸いなことに、その時点までにドキュメントはすでに皮質下のどこかに記録されていました。Sparkの起動時に、起動するポートを探していたことを思い出しました。 範囲内の最初のポートがビジーの場合、次のポートに順番に移動します。 無料であれば、それは刺激的です。 そして、これの最大試行回数を示すパラメーターがあります。 デフォルトは16です。この数は、レッスンのグループの人数よりも少ないです。 したがって、16回の試行の後、Sparkはこのケースをスローし、開始できないと言いました。 このパラメーターを修正しました。



 spark.port.maxRetries=50
      
      





次に、ケースの詳細とはもはや関係のない設定について説明します。



Sparkをすばやく起動するには、SPARK_HOMEホームディレクトリのjarsフォルダーをアーカイブしてHDFSに配置することをお勧めします。 その後、彼はこれらのdzharnikを労働者にロードするのに時間を費やしません。



 spark.yarn.archive=hdfs:///tmp/spark-archive.zip
      
      





また、操作を高速化するために、kryoをシリアライザーとして使用することをお勧めします。 デフォルトよりも最適化されています。



 spark.serializer=org.apache.spark.serializer.KryoSerializer
      
      





また、Sparkには、メモリから頻繁に落ちるという長年の問題があります。 多くの場合、これは労働者がすべてを計算し、結果をドライバーに送信した瞬間に発生します。 このパラメーターをさらに増やしました。 デフォルトでは、1GBでした-3。



 spark.driver.maxResultSize=3072
      
      





そして最後に、デザートとして。 HortonWorksディストリビューションでHDをバージョン2.1にアップグレードする方法-HDP 2.5.3.0。 このバージョンのHDPにはプリインストールされたバージョン2.0が含まれていますが、Sparkが非常に活発に開発されていると判断すると、新しいバージョンごとにいくつかのバグが修正され、Python APIなどの追加機能が提供されるため、更新に必要なもの。



Hadoop 2.7の公式サイトからバージョンをダウンロードします。 解凍し、HDPでフォルダーに入れます。 必要に応じてシンボリックリンクを配置します。 実行-開始しません。 非常に分かりにくい間違いを書きます。



 java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig
      
      





グーグルでは、SparkがHadoopが生まれるまで待たないことを決定し、新しいバージョンのジャージを使用することを決定しました。 彼ら自身がJIRAでこのトピックについて互いに議論しています。 解決策は、 ジャージバージョン1.17.1をダウンロードすることでした 。 SPARK_HOMEのjarsフォルダーにドロップし、再度圧縮してHDFSにドロップします。



このエラーを回避しましたが、新しく合理化されたエラーが発生しました。



 org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master
      
      





この場合、バージョン2.0を実行しようとします-すべて問題ありません。 何が問題なのか推測してみてください。 このアプリケーションのログを調べてみると、次のようなものが見つかりました。



 /usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jar
      
      





一般に、何らかの理由で、hdp.versionは解決しませんでした。 グーグル、解決策を見つけた。 AmbariのYARN設定に移動し、カスタムヤーンサイトにパラメーターを追加する必要があります。



 hdp.version=2.5.3.0-37
      
      





この魔法が助けになり、Sparkが飛び立ちました。 いくつかのjupyterラップトップをテストしました。 すべてが機能します。 土曜日(明日)のSparkの最初のレッスンの準備ができました!



UPD レッスンでは、別の問題が明らかになりました。 ある時点で、YARNはSparkのコンテナーの発行を停止しました。 YARNでは、パラメーターを修正する必要がありました。デフォルトは0.2です。



 yarn.scheduler.capacity.maximum-am-resource-percent=0.8
      
      





つまり、リソースの20%だけがリソースの配布に参加しました。 パラメータを変更し、YARNを再起動しました。 問題は解決され、他の参加者もスパークコンテキストを実行できました。



All Articles