MiHoYo ビッグデータ クラウド ネイティブ プラクティス

近年、コンテナ、マイクロサービス、Kubernetesなどのさまざまなクラウドネイティブテクノロジーがますます成熟しており、ますます多くの企業がクラウドネイティブの採用を選択し始め、AIや大規模アプリケーションなどのエンタープライズアプリケーションを導入および実行し始めています。クラウドネイティブのデータ。Spark を例に挙げると、クラウド上で Spark を実行すると、パブリック クラウドの柔軟なリソース、運用保守管理、ストレージ サービスを最大限に活用でき、業界では Kubernetes 上での Spark の優れたプラクティスが数多く登場しています。

終了したばかりの 2023 Yunqi Conference で、MiHoYo データ プラットフォーム グループのビッグ データ テクノロジ専門家である Du Anming 氏は、MiHoYo のビッグ データ アーキテクチャをクラウドネイティブにアップグレードするプロセスにおける目標、探索、実践、および Alibaba の使用方法について共有しました。サービス ACK をベースとした K8s アーキテクチャ上の Spark へのクラウド コンテナは、エラスティック コンピューティング、コスト削減、ストレージとコンピューティングの分離において価値を獲得します。

01 背景紹介

MiHoYo のビジネスの急速な発展に伴い、ビッグ データのオフライン データ ストレージとコンピューティング タスクの量が急速に増加し、初期のビッグ データ オフライン アーキテクチャでは新しいシナリオやニーズを満たすことができなくなりました。

元のアーキテクチャの弾力性の欠如、複雑な運用と保守、リソース使用率の低さの問題を解決するために、2022 年後半にビッグ データ インフラストラクチャのクラウド ネイティブ化の検討を開始し、最終的に K8s で Spark を開始しました。 + OSS- on Alibaba Cloud: HDFS ソリューションは約 1 年間実稼働環境で安定して実行されており、柔軟なコンピューティング、コスト削減、ストレージとコンピューティングの分離という 3 つの大きな利点を達成しています。

1. 弾性計算

ゲーム ビジネスでは定期的なバージョン アップデート、活動の開始、新しいゲームの発売に伴い、オフライン コンピューティング リソースの需要と消費量は大きく変動し、通常のレベルの数十倍から数百倍になる可能性があります。K8s クラスターの自然な弾力性を利用し、K8s 上で実行されるように Spark コンピューティング タスクをスケジュールすると、このようなシナリオでのリソース消費のピークの問題を比較的簡単に解決できます。

2. コスト削減

Alibaba Cloud Container Service for Kubernetes ACK クラスターの強力な弾力性に依存して、すべてのコンピューティング リソースはオンデマンドで適用され、使用後にリリースされます。Spark コンポーネントのカスタマイズされた変換と ECI スポット インスタンスのフル活用と組み合わせることで、同じコンピューティングタスクとリソース消費の下で、コスト削減は 50% に達します。

3. 記憶と計算の分離

Spark は K8s 上で実行され、K8s クラスターのコンピューティング リソースを最大限に活用します。アクセスされるデータは、HDFS および OSS から OSS-HDFS に段階的に切り替えられます。中間の Shuffle データは、Celeborn を使用して読み書きされます。アーキテクチャ全体が、コンピューティングと OSS の統合を実現します。分離されているため、メンテナンスと拡張が簡単です。

02 K8s アーキテクチャの進化に関するスパーク

ご存知のとおり、Spark エンジンは、Yarn、K8s、Mesos などのさまざまなリソース マネージャーをサポートし、その上で実行できます。ビッグデータのシナリオでは、ほとんどの国内企業の Spark タスクは依然として Yarn クラスター上で実行されており、Spark はバージョン 2.3 で初めて K8s をサポートし、2021 年 3 月にリリースされた Spark 3.1 バージョンは正式に GA になりました。

Yarn に比べて、Spark は K8s でのスタートが遅く、成熟度や安定性の点でまだ一定の欠陥がありますが、K8s 上の Spark はエラスティック コンピューティングやコスト削減などの優れたメリットを達成できるため、大手企業も常に試行錯誤を続けており、プロセスに合わせて、K8s 上の Spark のオペレーティング アーキテクチャも常に反復的に進化しています。

1. オフラインミキシング

現在、ほとんどの企業は依然としてオンラインとオフラインのハイブリッド展開方法を使用して、K8 上で Spark タスクを実行しています。アーキテクチャ設計は、ビジネス システムが異なればビジネス ピーク時間も異なるという原則に基づいています。ビッグデータオフライン業務システムの一般的な業務ピーク時間帯は午前0時から9時までですが、各種アプリケーションマイクロサービスやWebで提供されるBIシステムなどは日中が業務ピーク時間帯となります。また、ビジネス システムのマシン ノードを Spark が使用する K8s NameSpace に追加することもできます。以下の図に示すように、Spark およびその他のオンライン アプリケーション サービスは K8s クラスターにデプロイされます。

このアーキテクチャの利点は、混合デプロイメントとオフライン サービスのオフピーク操作を通じてマシン リソースの使用率を向上させ、コストを削減できることですが、アーキテクチャの実装が複雑で、メンテナンス コストが高くなるという欠点も明らかです。リソースの分離、特にネットワークレベルでの分離は、ビジネス間で一定の相互影響を与えることは避けられず、また、このアプローチはクラウドネイティブや将来の概念にも沿わないと考えられます。開発傾向。

2. K8s + OSS-HDFS での Spark

オフライン ハイブリッド展開の欠点を考慮して、クラウド ネイティブに近い新しい実装アーキテクチャを設計および採用しました。基盤となるストレージは OSS-HDFS (JindoFs) を使用し、コンピューティング クラスターは Alibaba Cloud のコンテナ サービス ACK を使用し、Spark を選択しました。機能が比較的豊富で安定したバージョン 3.2.3。

OSS-HDFS は、HDFS プロトコルと完全な互換性があります。無制限の OSS 容量とデータのホットおよびコールド ストレージのサポートという利点に加えて、ディレクトリ アトミック性とミリ秒レベルの名前変更操作もサポートしています。オフライン データ ウェアハウスに非常に適しています。 HDFSとOSSがあります。

Alibaba Cloud ACK クラスターは、エンタープライズレベルの Kubernetes コンテナー化アプリケーションのライフサイクル管理をサポートできる、高性能でスケーラブルなコンテナー アプリケーション管理サービスを提供します。ECS はよく知られた Alibaba Cloud サーバーであり、エラスティック コンテナー インスタンス ECI はサーバーレスの一種ですサービスを実行する場合、数秒でサービスの申請とリリースを行うことができます。

アーキテクチャはシンプルで保守が容易です。最下層は ECI の弾力性機能を利用しています。Spark タスクはピーク トラフィックに簡単に対処できます。Spark の Executor を ECI ノード上で実行するようにスケジュールすることで、コンピューティング タスクの柔軟性を最大化し、最高のコスト削減効果を達成できます。A全体的なアーキテクチャの概略図を以下に示します。

03 クラウドネイティブアーキテクチャの設計と実装

1. 基本原則

具体的な実装について詳しく説明する前に、K8 上で実行される Spark の基本原理を簡単に紹介しましょう。ポッドは、K8s の最小スケジューリング単位です。Spark タスクのドライバーとエグゼキューターは両方とも別個のポッドです。各ポッドには一意の IP アドレスが割り当てられます。ポッドには、ドライバー JVM プロセスかエグゼキューター JVM プロセスであるかに関係なく、1 つ以上のコンテナーを含めることができます。 、すべてコンテナ内で起動、実行、破棄されます。

Spark タスクが K8s クラスターに送信された後、ドライバー ポッドが最初に開始されます。その後、ドライバーは Apiserver からオンデマンドでエグゼキューターを申請し、エグゼキューターは特定のタスクを実行します。ジョブが完了すると、ドライバーはすべての Executor Pod のクリーンアップを担当します。以下は、これらの間の関係の簡単な概略図です。

2. 実行プロセス

次の図は、完全なジョブ実行プロセスを示しています。ユーザーが Spark ジョブの開発を完了した後、タスクをスケジューリング システムに公開し、関連する操作パラメータを構成します。スケジューリング システムは、定期的にタスクを自社開発のランチャー ミドルウェアに送信します。ミドルウェアはspark-k8s-cliを呼び出し、最終的にCliはタスクをK8sクラスターに送信します。タスクが正常に送信された後、Spark Driver Pod が最初に開始され、Executor Pod の割り当てのためにクラスターに適用されます。特定のタスクを実行すると、Executor は外部 Hive、Iceberg、OLAP などの多くのビッグ データ コンポーネントを含むデータにアクセスします。データベース、OSS-HDFS などと相互作用し、Spark Executor 間のデータ シャッフルは CeleBorn によって実装されます。

3. タスクの提出

Spark タスクを K8s クラスターに送信する方法については、企業によってさまざまな方法がとられていますが、以下では現在の一般的な方法を簡単に説明し、その後、現在オンラインで使用しているタスクの送信と管理方法を紹介します。

3.1 ネイティブのspark-submitを使用する

Spark-submit コマンドを使用して直接送信します。Spark はこの方法をネイティブにサポートしています。統合は比較的簡単で、ユーザーの習慣に沿っています。ただし、ジョブ ステータスの追跡と管理には不便です。Spark UI のサービスと Ingress は使用できません。タスクの完了後、リソースなどを自動的にクリーンアップすることもできないため、運用環境には適していません。

3.2 使用 spark-on-k8s-operator

これは、ジョブを送信するために一般的に使用される方法です。K8s クラスターには、事前に spak-operator をインストールする必要があります。クライアントは、kubectl を介して yaml ファイルを送信して、Spark ジョブを実行します。本質的に、これはネイティブ メソッドの拡張です。最終的なジョブの送信では、依然として spar-submit メソッドが使用されます。拡張機能には、ジョブ管理、サービス/Ingress の作成とクリーンアップ、タスクの監視、ポッドの拡張などが含まれます。この方法は運用環境でも使用できますが、ビッグ データ スケジューリング プラットフォームと十分に統合されていないため、K8s に慣れていないユーザーにとっては、使用方法が複雑で、使い始める敷居が比較的高くなります。

3.3 スパーク-k8s-cli の使用

実稼働環境では、spark-k8s-cli を使用してタスクを送信します。Spark-k8s-cli は本質的には実行可能ファイルであり、Alibaba Cloud emr-spark-ack 送信ツールをベースに、リファクタリング、機能強化、および徹底的なカスタマイズが行われています。

Spark-k8s-cli は、spark-submit とspark-operator という 2 つのジョブ送信方法の利点を組み合わせているため、すべてのジョブが sparper-operator を通じて管理でき、対話型の spak-shell とローカル依存関係の送信の実行をサポートし、使いやすいです。ネイティブのspark-submit構文と完全に一致しています。

オンライン使用の初期の頃、すべてのタスクの Spark Submit JVM プロセスはゲートウェイ ポッドで開始されました。一定期間使用した後、この方法は十分に安定していないことがわかりました。ゲートウェイ ポッドが異常になると、その上で実行されているすべての Spark タスクが失敗するだけでなく、Spark タスクのログ出力の管理も困難です。この状況を考慮して、タスクごとに個別の送信ポッドを使用するようにspark-k8s-cliを変更しました。送信ポッドはタスクを開始するドライバーに適用されます。送信ポッドとドライバーポッドは両方とも固定ECSノードで実行されます。オン, Submit Pod は互いに完全に独立しており、Submit Pod はタスクが完了すると自動的に解放されます。以下の図にspark-k8s-cliのサブミットと動作原理を示します。

Spark-k8s-cli に関しては、上記の基本的なタスクの送信に加えて、その他のいくつかの拡張およびカスタマイズ機能も作成しました。

  • 同じリージョン内の複数の異なる K8s クラスターへのタスクの送信をサポートし、クラスター間のロード バランシングとフェイルオーバー スイッチングを実現します。
  • Yarnリソースが不足した場合と同様の自動キューイングおよび待機機能を実装します(K8sがリソースQuotaを設定している場合、Quotaが上限に達するとタスクは直接失敗します)
  • K8 とのネットワーク通信、作成または起動失敗時の再試行などの例外処理を追加し、時折発生するクラスターのジッターやネットワーク異常に対するフォールト トレランスを実行します。
  • 部門や事業分野に応じた大規模な補完タスク向けに電流制限および制御機能をサポート
  • 埋め込みタスクの送信失敗、コンテナの作成や起動の失敗、実行タイムアウトなどのアラーム機能

4. ログの収集と表示

K8s クラスタ自体には Yarn のような自動ログ集計や表示機能は用意されていないため、Driver や Executor のログ収集はユーザーが行う必要があります。現在、より一般的なソリューションは、各 K8s ノードにエージェントをデプロイし、エージェントを使用してログを収集し、ES、SLS などのサードパーティのストレージに保存することです。ただし、これらの方法は、次のようなユーザーや開発者にとって困難です。 Yarn ページでクリックしてログを表示することに慣れているユーザーにとって、これは非常に使いにくく、ログを取得して表示するにはサードパーティのシステムにジャンプする必要があります。

K8s Sparkのタスクログを快適に閲覧できるように、DriverとExecutorのログが最終的にOSSに出力されるようにSparkのコードを修正し、Spark UIやSpark Jobhistory上でログファイルを直接クリックして閲覧できるようにしました。

上の図は、ログの収集と表示の原理を示しています。Spark タスクが開始されると、ドライバーとエグゼキューターは最初にシャットダウン フックを登録します。タスクが終了して JVM が終了すると、フック メソッドが呼び出され、完全なログがアップロードされます。 OSS。また、ログを完全に表示したい場合は、Spark のジョブ履歴関連のコードを変更する必要があり、履歴ページに stdout と stderr を表示し、ログをクリックするとドライバーに対応するログ ファイルを取得する必要があります。または OSS の Executor、最後にレンダリングされ、ブラウザーで表示されます。さらに、タスクを実行するために、Spark 実行 Web UI をユーザーに提供します。タスクが正常に送信された後、spark-operator はユーザーが実行中の詳細を表示できるようにサービスと Ingress を自動的に生成します。このとき、ログは次のとおりです。 K8s にアクセスすることで取得でき、API は対応する Pod の実行ログを取得できます。

5. 柔軟性とコスト削減

ACK クラスターによって提供される柔軟なスケーリング機能と ECI のフル活用に基づいて、K8 上で同じ規模の Spark タスクを実行する総コストは、固定 Yarn クラスターよりも大幅に低くなり、リソース使用率も大幅に向上します。改善されました。評価してください。

Elastic Container Instance ECI はサーバーレス コンテナ実行サービスです。ECI と ECS の最大の違いは、ECI は秒単位で課金され、アプリケーションとリリースの速度も第 2 レベルであるため、ECI は負荷に非常に適していることです。 Spark などの山と谷、明らかなコンピューティング シナリオ。

上の図は、Spark タスクが ACK クラスター上で ECI にどのように適用され、使用されるかを示しています。使用の前提条件は、クラスターに ack-virtual-node コンポーネントをインストールし、Vswitch およびその他の情報を構成することです。タスクの実行中、Executor は仮想ノードにスケジュールされ、仮想ノードは ECI の作成と管理に適用されます。

ECI は、通常のインスタンスとプリエンプティブル インスタンスに分かれています。プリエンプティブル インスタンスは、デフォルトの保護期間が 1 時間の低コスト入札インスタンスです。ほとんどの Spark バッチ処理シナリオに適しています。保護期間を超えると、プリエンプティブル インスタンスは強制的にリサイクルされる場合があります。コスト削減効果をさらに向上させ、プリエンプティブル インスタンスの価格メリットを最大限に活用するために、ECI インスタンス タイプの自動変換を実装するように Spark を修正しました。Spark タスクの Executor Pod は、プリエンプティブル ECI インスタンス上で実行されるように優先されます。インベントリ不足またはその他の理由でプリエンプティブル インスタンスを作成できない場合、タスクの通常の動作を確保するために、自動的に通常の ECI インスタンスに切り替わります。具体的な実装原理と変換ロジックを以下の図に示します。

6. セレボルン

K8s ノードのディスク容量は非常に小さく、ノードの申請と使用後に解放されるため、大量の Spark Shuffle データを保存することはできません。クラウド ディスクを Executor Pod にマウントする場合、マウントされるディスクのサイズを決定するのは難しく、データ スキューなどの要因を考慮すると、ディスク使用量が比較的少なくなり、使用がより複雑になります。また、Spark コミュニティでは 3.2 で Reuse PVC などの機能を提供していましたが、調査の結果、機能が完全ではなく、安定性が不十分であることが判明しました。

K8s 上の Spark データ シャッフルの問題を解決するために、複数のオープンソース製品を徹底的に調査および比較した後、最終的に Alibaba のオープンソース Celeborn ソリューションを採用しました。Celeborn は、Spark の中間 Shuffle データを保存するために特別に使用される独立したサービスで、Executor がローカル ディスクに依存しなくなります。このサービスは、K8s と Yarn の両方で使用できます。Celeborn はプッシュ シャッフル モードを採用しており、シャッフル処理は追加書き込みと順次読み取りを行うことで、データの読み取りと書き込みのパフォーマンスと効率を向上させます。

オープンソースの Celeborn プロジェクトに基づいて、データ ネットワーク送信の機能強化、メトリクスの強化、監視とアラームの改善、バグ修正などの内部作業も行い、現在、内部安定版が形成されています。

7. K8sの九尾

Kyubi は、Spark、Flink、または Trino に SQL およびその他のクエリ サービスを提供できる分散マルチテナント ゲートウェイです。初期の頃、Spark Adhoc クエリは実行のために Kyubi に送信されました。Yarn キューのリソース不足によりユーザーのクエリ SQL が送信および実行できない問題を解決するために、K8s 上での Kuubi Server のデプロイと運用もサポートしており、Yarn リソースが不足している場合、Spark クエリは自動的に K8s に切り替えて実行されます。 。Yarn クラスターのサイズが段階的に縮小することを考慮すると、クエリ リソースは保証できません。同じユーザー クエリ エクスペリエンスを保証するために、現在、すべての SparkSQL アドホック クエリを実行のために K8s に送信しています。

ユーザーのアドホック クエリが K8 上でスムーズに実行できるようにするために、Kyubi プロジェクトの docker-image-tool.sh、Deployment.yaml、および Dockfile ファイルの書き換えやリダイレクトなど、ソース コードの変更もいくつか行いました。 On OSS へのログオン、Spark オペレーター管理サポート、権限制御、タスク実行 UI の簡単な表示など。

8. K8sマネージャー

K8s 上の Spark シナリオでは、K8s にはクラスターレベルの監視とアラームがありますが、ニーズを完全に満たすことはできません。実稼働環境では、クラスター上の Spark タスクの実行ステータス、ポッドのステータス、リソース消費、および ECI にさらに注意を払います。K8sのWatch機構を利用して、独自の監視・警報サービス「K8s Manager」を実装しました(下図にサービスの概要図を示します)。

K8sManager は内部的に実装された比較的軽量な Spring Boot サービスであり、その機能は、各 K8s クラスター上の Pod、Quota、Service、ConfigMap、Ingress、Role などのさまざまなリソース情報を監視および要約することで、カスタマイズされたメトリクス インジケーターを生成し、インジケーターを表示します。異常アラーム(クラスターの CPU とメモリの合計使用量、現在実行中の Spark タスクの数、Spark タスクのメモリ リソース消費量と実行時間の上位統計、1 日の Spark タスクのボリュームの概要、クラスター ポッドの合計数、ポッド ステータスなど)統計、ECI マシン モデルとアベイラビリティ ゾーンの分布統計、期限切れリソースの監視など、ここではすべてをリストすることはしません。

9. その他の業務

9.1 スケジュールされたタスクの自動切り替え

私たちのスケジューリング システムでは、Spark タスクは、Yarn、K8s、および Auto の 3 つの実行戦略の構成をサポートしています。ユーザー タスクで実行する必要があるリソース マネージャーが指定されている場合、タスクは Yarn または K8s でのみ実行されます。ユーザーが [自動] を選択した場合、タスクが実行される場所は、図に示すように、Yarn キューの現在のリソース使用状況によって決まります。以下の図に表示します。タスクの総量が大きいことと、Hive タスクの Spark への継続的な移行により、一部のタスクはまだ Yarn クラスター上で実行されていますが、最終的な形式ではすべてのタスクが K8 によってホストされます。

9.2 複数のアベイラビリティ ゾーンと複数のスイッチのサポート

ECI は、Spark タスクの実行中に広範囲に使用されます。ECI を正常に作成するには、2 つの前提条件があります: 1. IP アドレスを申請できること、2. 現在のアベイラビリティ ゾーンにインベントリがあること。実際、単一のスイッチで提供される利用可能な IP の数は限られており、単一のアベイラビリティ ゾーン内のプリエンプティブル インスタンスの総数も限られているため、実際の運用環境では、通常の ECI またはスポットを使用することをお勧めします。タイプ ECI. この方法は、複数のアベイラビリティ ゾーンと複数のスイッチをサポートするように構成することです。

9.3 コスト計算

Spark タスクの送信時に各 Executor の CPU、メモリ、その他のモデル情報が明確に指定されているため、タスクの終了時に SparkContxt が閉じられる前に、各 Executor の実際の実行時間をタスクから取得できます。単価を使用すると、Spark タスクのおおよそのコストを計算できます。ECI スポット インスタンスは市場や在庫に応じて常に変化するため、この方法で計算されるシングル タスク コストは上限であり、主に傾向を反映するために使用されます。

9.4 Spark オペレーターの最適化

起動当初のタスクの数が少なかったときは、Spark Operator サービスはうまく動作しましたが、タスクの数が増加し続けるにつれて、さまざまな Event イベントを処理する Operator の速度がますます遅くなり、さらにはタスクの数が多くなりました。 ConfigMap、Ingress、Service、およびその他のタスクが実行プロセス中にクラスターに表示され、生成されたリソースが時間内にクリーンアップできずに蓄積され、新しく送信された Spark タスクの Web UI を開いてアクセスできなくなります。問題発見後、Operatorのコルーチン数を調整し、Pod Eventのバッチ処理や無関係なイベントのフィルタリング、TTL削除などの機能を実装することで、Spark Operatorの性能不足の問題を解決しました。

9.5 Spark K8s クライアントのアップグレード

Spark3.2.2 は、fabric8 (Kubernetes Java クライアント) を使用して K8s クラスター内のリソースにアクセスし、操作します。デフォルトのクライアント バージョンは 5.4.1 です。このバージョンでは、タスクが終了し、Executor が中央で解放されると、ドライバーは大きな削除ポッド API の数。K8s Apiserver へのリクエストにより、クラスター Apiserver と ETCD に大きな負荷がかかり、Apiserver の CPU が即座に増加します。

現在、社内の Spark バージョンは kubernetes-client を 6.2.0 にアップグレードしています。これにより、Spark タスクが集中的にリリースされるときに大量の削除 API リクエストによって引き起こされるクラスターのジッターを解決するために、ポッドのバッチ削除がサポートされます。

04 問題と解決策

Spark on K8s ソリューションの設計と実装のプロセス全体を通じて、さまざまな問題、ボトルネック、課題にも遭遇しました。ここでは、簡単な紹介とソリューションを紹介します。

1. Elastic Network Card のリリースが遅い

エラスティック ネットワーク カードの遅いリリース速度は、大規模な ECI アプリケーション シナリオにおけるパフォーマンスのボトルネックです。この問題は、スイッチ上の IP の大量消費につながり、最終的には Spark タスクが停止したり、送信に失敗したりすることにつながります。以下の図に示されています。現在、Alibaba Cloud チームは技術的なアップグレードを通じて問題を解決し、リリース速度と全体的なパフォーマンスを大幅に向上させました。

2. ウォッチャーの失敗

Spark タスクがドライバーを開始すると、Executor のイベント リスナーが作成され、すべての Executor の実行ステータスをリアルタイムで取得します。長時間実行される一部の Spark タスクでは、リソースの期限切れやネットワークの異常などが原因でこのリスナーが失敗することがよくあります。したがって、この場合、ウォッチャーをリセットする必要があります。そうしないと、タスクが暴走する可能性があります。この問題は Spark のバグであり、現在、内部バージョンは修正され、PR が Spark コミュニティに提供されています。

3. タスクが行き詰まっている

上図に示すように、Driver は List と Watch を通じて Executor の実行ステータスを取得します。Watch はパッシブ リスニング メカニズムを使用していますが、ネットワークやその他の問題により、イベントが見逃されたり見逃したりする可能性がありますが、その可能性は比較的低いです。List はアクティブなリクエスト メソッドを採用しており、たとえば、ドライバーは 3 分ごとに、そのタスクの現在のすべてのエグゼキューターの情報を Apiserver にリクエストできます。

List はタスクのすべての Pod 情報を要求するため、タスクが多い場合、頻繁に List を行うと K8s の Apiserver や ETCD に大きな負担がかかるため、初期の頃はスケジュールされた List をオフにして Watch のみを使用していました。Spark タスクが異常に実行される場合 (たとえば、多数の Executor OOM がある場合)、一定の確率で Driver Watch 情報が正しくなくなります。タスクの実行が完了していないにもかかわらず、ドライバーはタスクの実行を Executor に申請しなくなります。そしてタスクは行き詰まっています。これに対する私たちの解決策は次のとおりです。

  • 監視メカニズムをオンにしている間、リストメカニズムもオンにし、リストの時間間隔を延長して、5 分ごとのリクエストを設定します。
  • ExecutorPodsPollingSnapshotSource に関連するコードを変更して、Apiserver サーバーがキャッシュできるようにし、キャッシュから全量の Pod 情報を取得し、クラスター上の List の負荷を軽減します。

4. Celeborn の読み取りおよび書き込みタイムアウト、失敗

ApacheCeleborn は Alibaba のオープンソース製品で、以前は RSS (Remote Shuffle Service) として知られていました。初期段階ではまだ成熟度がわずかに不足しており、ネットワーク遅延やパケット損失例外などの処理が十分に完璧ではないため、大量の Shuffle データを含む一部のオンライン Spark タスクで時間がかかることがあります。この問題に対する解決策は次の 3 点です。

  • Celeborn を最適化し、内部バージョンを形成し、ネットワーク パケット送信用のコードを改善します。
  • Celeborn のマスターおよびワーカー関連パラメータを調整して、シャッフル データの読み取りおよび書き込みパフォーマンスを向上させます。
  • ECI の基礎となるイメージのバージョンをアップグレードし、ECI Linux カーネルのバグを修正します

5. タスクをバッチで送信するとクォータ ロックの競合が発生する

リソースが無制限に使用されるのを防ぐために、K8s クラスターごとにクォータ制限を設定します。K8s では、Quota もリソースの 1 つであり、各 Pod の適用とリリースによって Quota の内容 (Cpu/Memory 値) が変更されます。多くのタスクが同時に送信されると、Quota ロックの競合が発生し、タスク ドライバーの作成に影響を与える可能性があります。タスクの起動に失敗しました。

この状況によるタスク起動の失敗に対処するには、Spark Driver Pod の作成ロジックを変更し、構成可能な再試行パラメーターを追加します。ドライバー Pod の作成がクォータ ロックの競合によって引き起こされたことが検出された場合、作成は再試行される。エグゼキュータ ポッドの作成は、クォータ ロックの競合により失敗する場合もあります。この状況に対処する必要はありません。エグゼキュータの作成が失敗した場合、ドライバーは自動的に適用されて新しいエグゼキュータを作成します。これは自動的に再試行することと同じです。

6.タスクをバッチで送信すると、UnknownHost がエラーを報告する

大量のタスクを瞬時にクラスターに一括送信すると、複数のSubmit Podが同時に起動し、TerwayコンポーネントからのIPの申請とElastic Network Cardのバインドを同時に行うことになり、一定の確率で実行されます。ポッドが起動され、エラスティック ネットワーク カードが正常にバインドされたという状況が発生しますが、実際には完全に準備ができていないため、この時点ではポッドのネットワーク通信機能は正常に使用できません。タスクが Core DNS にアクセスすると、リクエストを送信できず、Spark タスクは UnknownHost エラーを報告し、実行に失敗します。この問題は、次の 2 つの対策によって回避および解決されます。

  • ECS ノードごとに Terway Pod が割り当てられます
  • Terway のキャッシュ機能をオンにし、IP カードとエラスティック ネットワーク カードを事前に割り当てておくと、新しい Pod はキャッシュ プールから直接取得され、使用後はキャッシュ プールに戻されます。

7. アベイラビリティゾーン間のネットワークパケット損失

十分なインベントリを確保するために、各 K8s クラスターは複数のアベイラビリティ ゾーンで構成されていますが、アベイラビリティ ゾーン間のネットワーク通信は、同じアベイラビリティ ゾーン間の通信よりも若干不安定であり、アベイラビリティ ゾーン間で一定の確率でパケット損失が発生します。 . タスクの実行時間が不安定な性能です。アベイラビリティーゾーンをまたがるネットワークパケット損失の現象については、ECI スケジューリングポリシーを VSwitchOrdered に設定することで、タスクのすべての実行者が基本的に同じアベイラビリティーゾーンに存在し、異なるアベイラビリティーゾーンにある実行者間での通信異常を回避できます。タスクの実行時間が不安定になる問題。

05 概要と展望

最後に、技術ソリューション全体の実装と実際の移行中に、多くの貴重な提案と専門的な技術サポートを提供してくれた Alibaba Cloud Container、ECI、EMR、およびその他の関連チームの学生に非常に感謝しています。

現在、新しいクラウド ネイティブ アーキテクチャは本番環境で 1 年近く安定して稼働していますが、今後は主に以下の点に焦点を当ててアーキテクチャ全体の最適化と改善を継続していきます。

1. クラウドネイティブ ソリューション全体の最適化を継続し、システムの耐荷重性と災害復旧機能をさらに強化します。

2. クラウド ネイティブ アーキテクチャがアップグレードされ、より多くのビッグ データ コンポーネントがコンテナ化され、アーキテクチャ全体がより完全にクラウド ネイティブになりました。

3. よりきめ細かいリソース管理と正確なコスト管理

著者:MiHoYoビッグデータ開発

元のリンク

この記事は Alibaba Cloud のオリジナル コンテンツであり、許可なく複製することはできません。

Microsoft、新しい「Windowsアプリ」を発表 Xiaomi、Xiaomi Velaが完全オープンソース、基盤となるカーネルはNuttX Vite 5 であることを正式発表 Alibaba Cloud 11.12が正式リリース 障害の原因が判明:アクセスキーサービス(アクセスキー)の異常 GitHub レポート: TypeScript が Java に代わって 3 番目に人気になる 言語オペレータの奇跡的な操作 : バックグラウンドでネットワークを切断し、ブロードバンド アカウントを無効にし、ユーザーに光モデムの変更を強制する ByteDance: AI を使用して Linux カーネル パラメータを自動的に調整する Microsoft オープン ソースTerminal Chat Spring Framework 6.1 が正式に GA OpenAI の元 CEO 兼社長の Sam Altman 氏と Greg Brockman 氏が Microsoft に入社
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/yunqi/blog/10150099