YARN での Spark の構成

ハブル、こんにちは! 昨日の Apache Spark 専用のミートアップRambler&Co の担当者からは、このツールの設定に関連して参加者から非常に多くの質問がありました。 私たちは彼の足跡をたどり、私たちの経験を共有することにしました。 このトピックは簡単ではありません。そのため、コメントであなたの経験を共有してください。おそらく私たちも何か間違ったことを理解して使用しているかもしれません。

Spark の使用方法を少し紹介します。 XNUMXヶ月間のプログラムがあります 「ビッグデータスペシャリスト」、XNUMX 番目のモジュール全体を通して、参加者はこの機器に取り組みます。 したがって、主催者としての私たちの仕事は、そのような場合に使用できるようにクラスターを準備することです。

私たちの使用の特徴は、Spark で同時に作業する人の数がグループ全体と同じになる可能性があることです。 たとえば、セミナーで、全員が同時に何かに挑戦し、先生の後に同じことを繰り返すとき。 そしてこれは多くはありません - 時には最大40人です。 おそらく、このようなユースケースに直面している企業は世界中に多くありません。

次に、特定の構成パラメータを選択した方法と理由について説明します。

最初から始めましょう。 Spark には、クラスター上で実行する 3 つのオプションがあります。スタンドアロン、Mesos の使用、YARN の使用です。 私たちにとっては理にかなっていたので、XNUMX 番目のオプションを選択することにしました。 すでに Hadoop クラスターがあります。 参加者はすでにそのアーキテクチャについてよく知っています。 YARNを使ってみましょう。

spark.master=yarn

さらに面白い。 これら 3 つの展開オプションにはそれぞれ、クライアントとクラスターという 2 つの展開オプションがあります。 ベース ドキュメンテーション インターネット上のさまざまなリンクを考慮すると、クライアントは jupyter Notebook などのインタラクティブな作業に適しており、実稼働ソリューションにはクラスターの方が適していると結論付けることができます。 私たちの場合、インタラクティブな作業に興味があったため、次のようになります。

spark.deploy-mode=client

一般に、今後 Spark は何らかの形で YARN で動作するようになりますが、これでは十分ではありませんでした。 私たちはビッグデータに関するプログラムを行っているため、リソースを均等にスライスする枠組みでは、参加者が得られた情報を十分に得られないことがありました。 そして、動的なリソース割り当てという興味深いものを発見しました。 つまり、重要な点は次のとおりです。難しいタスクがあり、クラスターが空いている場合 (たとえば、午前中)、このオプションを使用すると、Spark により追加のリソースが提供される可能性があります。 そこでは必要性が狡猾な公式に従って計算されます。 詳細は説明しませんが、うまく機能します。

spark.dynamicAllocation.enabled=true

このパラメータを設定しましたが、起動時に Spark がクラッシュして起動しませんでした。 そうです、読まなければならなかったので ドキュメンテーション もっと慎重に。 すべてを正常に行うには、追加のパラメーターも有効にする必要があると記載されています。

spark.shuffle.service.enabled=true

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

このパラメータが追加されました。 すべてがうまくいくように見えました。 参加者が実際に必要なときに、より多くのリソースを提供されることが顕著になりました。 しかし、別の問題が発生しました。ある時点で他の参加者も目覚めて、Spark を使用したいと考えましたが、そこではすべてがビジーであり、彼らは不満を感じていました。 それらは理解できます。 私たちはドキュメントを見始めました。 プロセスに影響を与えるために使用できるパラメーターが他にも多数あることが判明しました。 たとえば、エグゼキュータがスタンバイ モードの場合、どれくらいの時間が経過するとエグゼキュータからリソースを取得できますか?

spark.dynamicAllocation.executorIdleTimeout=120s

私たちの場合、執行者が XNUMX 分間何もしなかった場合は、執行者を共通プールに戻してください。 しかし、このパラメータだけでは必ずしも十分ではありませんでした。 その人が長い間何もしていなかったことが明らかで、リソースが解放されていませんでした。 キャッシュされたデータを含むエグゼキュータを選択する時間を指定するという特別なパラメータもあることが判明しました。 デフォルトでは、このパラメータは無限大でした。 修正させていただきました。

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

つまり、エグゼキュータが 5 分間何もしなかった場合、それらを共通プールに渡します。 このモードでは、多数のユーザーに対するリソースの解放と発行の速度がかなり速くなりました。 不満の量は減りました。 しかし、私たちはさらに進んで、アプリケーションごと、つまりプログラム参加者ごとに実行者の最大数を制限することにしました。

spark.dynamicAllocation.maxExecutors=19

もちろん、反対側には「クラスターはアイドル状態で、実行者は 19 人しかいない」という不満を持つ人々がいますが、何ができるでしょうか? ある種の正しいバランスが必要です。 全員を幸せにすることはできません。

そして、私たちの事件の詳細に関連するもう 16 つの小さな話。 どういうわけか、数人が実践的なレッスンに遅刻し、何らかの理由で Spark が開始されませんでした。 無料リソースの量を確認しました - 存在するようです。 スパークが開始されるはずです。 幸いなことに、その時までにドキュメントはサブコーテックスのどこかにすでに追加されており、Spark が起動時に起動するポートを探すことを思い出しました。 範囲内の最初のポートがビジーの場合、順番に次のポートに移動します。 無料であればキャプチャします。 そして、これに対する最大試行回数を示すパラメータがあります。 デフォルトは 16 です。この数は、クラスのグループの人数よりも少ないです。 したがって、XNUMX 回試みた後、Spark は諦めて、開始できないと言いました。 この設定を修正しました。

spark.port.maxRetries=50

次に、今回のケースの詳細とはあまり関係のないいくつかの設定について説明します。

Spark をより速く起動するには、SPARK_HOME ホーム ディレクトリにある jars フォルダーをアーカイブし、HDFS に配置することをお勧めします。 そうすれば、労働者がこれらのジャーニクを積み込む時間を無駄にすることはなくなります。

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

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

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

また、Spark には、頻繁にメモリからクラッシュするという長年の問題もあります。 多くの場合、これは作業員がすべてを計算し、結果をドライバーに送信した瞬間に発生します。 私たちはこのパラメータを自分たちで大きくしました。 デフォルトでは 1GB ですが、3 にしました。

spark.driver.maxResultSize=3072

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

Hadoop 2.7 のバージョンを公式 Web サイトからダウンロードしました。 解凍して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 設定に移動し、そこにパラメータをカスタム Yarn-site に追加する必要があります。

hdp.version=2.5.3.0-37

この魔法が役に立ち、スパークは飛び立ちました。 私たちはいくつかの Jupyter ラップトップをテストしました。 すべてが機能しています。 土曜日(明日)の最初の Spark レッスンの準備ができています。

UPD。 授業中にまた別の問題が発覚した。 ある時点で、YARN は Spark 用のコンテナーの提供を停止しました。 YARN では、パラメータを修正する必要がありました。デフォルトでは 0.2 でした。

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

つまり、リソースの 20% のみがリソースの配布に参加しました。 パラメータを変更した後、YARN をリロードしました。 問題は解決され、残りの参加者も Spark コンテキストを実行できるようになりました。

出所: habr.com

DDoS 保護機能を備えた信頼性の高いサイト用ホスティング、VPS VDS サーバーを購入する 🔥 DDoS攻撃対策付きの信頼性の高いウェブサイトホスティング、VPS/VDSサーバーを購入しましょう | ProHoster