re:Invent 2024: AWSが解説 Amazon EKSによるデータ分析基盤の構築と最適化
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Amazon EKS as data platform for analytics (KUB405)
この動画では、Amazon EKSを活用したデータ処理プラットフォームの構築と最適化について、AWSのDirector Specialist Solution ArchitectsのRoland Barciaらが解説しています。Platform Engineeringの進化とデータワークロードの特性を踏まえた上で、Apache SparkやApache Flinkなどのデータ処理ツールをKubernetes上で効率的に運用する方法を詳しく説明しています。特に注目すべきは、AppsFlyerの事例で、Amazon EKSとKarpenterの活用により、コストを60%削減しSLAを35%改善した具体的な成果が示されています。また、AWS Controllers for Kubernetes(ACK)を活用したAPIの提供や、Data Engineerの自律性を高めるための実践的なアプローチなど、大規模データ処理の実装に関する具体的な知見が共有されています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
データ時代におけるAWSのアプローチ:自己紹介と課題設定
こんにちは。私はAWSのワールドワイドDirector Specialist Solution ArchitectsのRoland Barciaです。本日は、Christina AndonovとVictor Gershkovichと一緒に発表させていただく光栄な機会を得ました。お二人には後ほど自己紹介をしていただきます。カバーする内容が多いので、時間を有効に使うため、すぐに本題に入らせていただきます。これは400レベルのセッションですので、早い段階から深い内容に入っていきます。まずは私から文脈を設定し、その後Christinaにバトンタッチします。
今回は、データについてお話しします。これは、Generative AIやAmazon Bedrock、関連テクノロジーについて議論するこのカンファレンスにおいて、特に重要なトピックです。データは私たちの重要な資産の一つとなっています。データフォーマットは多様で、データを利用するユーザーやペルソナも様々です。もはやアナリストだけではなく、開発者もユーザーも、社内チームもデータを使用し、皆が素早く意思決定を行う必要があります。
データについて語る際、私たちはペルソナについて考える必要があります。なぜなら、AWSはカスタマーオブセッションであり、データを使用する人々の視点から考える必要があるからです。Apache Sparkを例にとったデータ処理などについて、より深く掘り下げていきます。ビジネスの一環としてデータにアクセスする外部ユーザーについても考える必要があります。多くの場合、履歴データやバッチデータなど、月次や週次で確認する既知のパターンを持つデータがあります。最近では、リアルタイムでデータに基づいて意思決定を行う必要性が高まっています。これは、プロンプトエンジニアリングを使用してアドホッククエリを実行し、質問に対する回答を得るGenerative AIの活用場面でよく見られます。社内では、システムの効率性、スケーリング、セキュリティ監査に関する意思決定を行いたいペルソナがおり、Observabilityツールがそれを支援します。膨大な量のデータを処理する必要があるため、Sparkとそのクラスターテクノロジー、バッチ処理用のHadoop、そして意思決定のためのストリーミングとバッチデータ処理を組み合わせた Apache Flinkのような新興テクノロジーについて議論します。
Platform Engineeringの進化:データワークロードへの対応
Platform Engineeringについて話しましょう。多くのお客様がAmazon EKSを使用してKubernetesを標準化しており、今週のトラックの他のセッションでは、Auto modeなど素晴らしい発表がありました。スタートアップの段階では、Platform Engineeringを担当する開発チームだけかもしれません。しかし、成長とともにPlatform Engineeringの重要性が高まり、Kubernetesとともに進化してきました。当初、これらの課題の多くはWebアプリケーションやマイクロサービスに焦点を当てていました。
この進化は、私が「ペルソナとゴールの衝突」と呼ぶものを表しています。開発者は自由を求めています - お気に入りのオープンソースツールやテクノロジーを使用し、新しいアプリケーションを自律的に構築し、迅速にデプロイしたいと考えています。一方で、プラットフォームチームはシステムのセキュリティ、スケーラビリティ、コスト、パフォーマンスを懸念しています。これらプラットフォームチームの第一世代は、主にWebアプリケーション、マイクロサービス、トランザクションシステムについて考えていました。
Platform Engineeringは、開発者に優しい方法で自律性と標準化の自動化のバランスを取る手段として台頭してきました。Platform Engineering全般に関する講演は数多くありますが、私も木曜日のServerlessトラックで開発者の視点からの講演を行います。Platform Engineeringについて語る際、お客様がよく苦心されるのは、プラットフォームを利用する開発者とプラットフォームチームの境界線をどこに引くかという点です。クラスターを提供すべきか、Code as a Serviceを提供すべきか、あるいは開発者がコードをチェックインするだけで済むようにすべきかといった疑問が生じます。
これらの第一世代の課題は完全には解決されていません。境界線をどこに引くべきかについては、まだ多くの議論が続いていますが、それはワークロードの性質によるものです。データの時代に入り、データサイエンティストやエンジニアはNotebookを使ってアプリケーションを構築し、データ処理にSQLを使用するようになりました。彼らはステートフルなアプリケーション、ストリーミングやイベントを扱うアプリケーション、ワークフローを構築し、PythonやRを使用したNotebookで、Generative AI、Machine Learning、さまざまなタイプのデータ処理のためのアプリケーションを開発しています。
データサイエンティストやエンジニアはまた、Data LakeやData Meshを構築し、データを統合するアプリケーションも開発しています。プラットフォームチームは今や、最適なストレージソリューション、新しく発表されたInferential TwoやGraviton Twoを含むGPUについても考慮する必要があります。また、新しいタイプのDevOps、MLOps、データパイプラインも登場し、LLMのライフサイクルやデータ管理についても考慮しなければなりません。
データワークロードに関するPlatform Engineeringには、数多くの目標があります。開発者に適切なリソースを提供する必要があります。これには、ワークロード、Notebook、データ処理に適切なマシンタイプ、GPU、ストレージタイプが含まれます。セキュリティと分離は非常に重要で、データジョブがトランザクションシステムに干渉しないようにする必要があります。そしてこれらすべてをコスト効率よく維持しなければなりません。データサイエンティストやデータエンジニアは、PyTorch、TensorFlow、その他のデータアプリケーションフレームワークについて強い好みを持っているため、この新世代のデータ集約型アプリケーションにおいて、そうした自律性をサポートする必要があります。
ステートフルなワークロードでは、さまざまな課題に直面しています。数千のノードを必要とするシナリオや、逆に、起動してデータのウォームアップに時間がかかる大規模なイメージを管理するケースもあります。Kubernetesは元々、高速なコンピュートのスピンアップとPodの置き換えに最適化されていましたが、これらのデータワークロードでは、データ処理中のチェックポイントのような機能が必要になることがあります。ステートフルなアプリケーションでは新しい懸念事項があり、スケーラーが速すぎる場合もあります。ネットワーク構成ではデータの重力を考慮する必要があり、コンピュートにデータを近づける方がコスト効率が良いと判断するケースもあります。これらのパターンが変動するにつれて、プラットフォームチームも適応していく必要があります。
Amazon EKSとApache Sparkの統合:実装オプションとデータライフサイクル
実装には様々なオプションがあります。AWS サービスをネイティブに使用している場合は、Apache Spark EMR をサーバーレスで利用でき、デフォルトで多くの利点があります。多くのお客様は標準化のために Kubernetes を選択しており、私たちは Amazon EKS という最高の Kubernetes サービスの1つを提供しています。エコシステム内で Apache Spark を実行する方法は複数あり、Operator を使用して Spark を独立して実行することも、Amazon EMR on Amazon EKS を利用して管理性と柔軟性のバランスを取りながら、最高のオープンソースフレームワークにアクセスすることもできます。
Kubernetes とデータの関係を見ると、様々なパターンの進化が見られます。最初はストレージと Custom Resource Definition から始まり、その後 Kafka を使用したイベントストリーミングやメッセージングによるイベントベースのアプリケーションへと進化しました。次に Apache Spark が登場し、Hadoop ワークロードからインメモリ集中型の並列処理へとアーキテクチャを変革しました。その後、Apache Flink が登場し、リアルタイムとバッチの両方のデータ処理が可能になりました。現在では、モデルトレーニングなどの集中的なタスクのために GPU や特殊なハードウェアを組み込み、専用のスケジューラーや Notebook-as-a-Service のサポートも提供しています。
私たちには Data on Amazon EKS というプロジェクトがあります。後ほど私たちにご連絡いただければ、Apache Spark や Apache Flink、その他のサービスを Amazon EKS 上で実行するための様々なブループリントやベストプラクティスをご共有できます。 最後に、データについて話す際は、完全なライフサイクルを考慮する必要があります。データプラットフォームは、まずデータの取り込みから始まる様々な側面をサポートする必要があります。これには、Amazon MSK のようなマネージドサービスを通じた Apache Kafka ベースのソリューションや、Kubernetes 上での Kafka の実行など、さまざまなツールのサポートが必要です。また、Amazon Kinesis のようなネイティブオプションや、より状態を持つパターンのためのデータステージングを支援する AWS Step Functions、Apache Airflow、Argo Workflows などのワークフローツールもあります。
データ処理についてはすでにお話ししました。 そして、データ処理層では夜間に必要な処理を行うバッチスケジューリングを実装し、 その後、データを取り出して利用できるようにします。変換を実行し、SQL クエリを実行し、データをカタログ化して API として利用可能にします。これがデータのライフサイクルです。
Kubernetes上の分析プラットフォーム最適化:Christina Andonovの視点
ここからさらに詳しく見ていきましょう。Christina に引き継ぎたいと思います。ありがとう、Roland。皆さん、こんにちは。次に、 Kubernetes 上の分析プラットフォームを成長に向けて最適化するための3つのポイントについてお話しします。これにより、分析ワークロードを AWS に迅速に取り込み、さらに異なるリージョンへと拡大できるようになります。私は Christina Andonov です。Solutions Architect として、お客様の Kubernetes 上での分析プラットフォームの構築をサポートしています。
Rolandが言及したように、皆さんがここにいる理由の1つとして、すでにビジネスアプリケーションをKubernetesで運用していて、その使用や拡張に慣れており、今度はアナリティクス・ワークロードが入ってくるというケースが考えられます。このような顧客と関わる際、通常、同じコンピュートを中心に2つの別々のチームが2つの別々のプラットフォームを構築しているのを目にします。その理由は、コンピュート自体というよりも、ワークロードのトラフィックパターンにあります。ビジネスアプリケーションのトラフィックパターンは、カリフォルニアの天気のようなものです - ほとんどの場合、最高気温は80度台、最低気温は60度台で、例外を除けばとても予測可能です。一方、アナリティクス・ワークロードのトラフィックパターンは、ハリケーンシーズン中のカリブ海の天気のようなものです。
ジョブの洪水がクラスターに到達すると、データプラットフォームチームの責任は、これらのクラスターが極めて短時間でスケールできることを確実にすることです。彼らはジョブを取り込み、高速処理のために最適化し、そのすべてをコスト効率よく行う必要があります。次に、これらのクラスターを最適化するためにできることのベストプラクティスをいくつか見ていきましょう。ベストプラクティスについて話す際、すでにビジネスアプリケーションをKubernetesで運用していることを前提としているので、ビジネスプラットフォームとデータプラットフォームの間のベストプラクティスの違いについてのみ説明します。
ベストプラクティスに基づいてクラスターを一から構築していきます。構築を3つの論理層に分けます:第1層はアナリティクス向けに最適化された、バニラではあるものの本番環境対応のクラスターの構築、第2層は様々なオープンソースツールをインストールしてそのクラスターを目的特化型にすること、第3層はそのクラスター上にテナントをオンボーディングすることです。クラスターを作成する前に、ネットワークがスケールすることを確認し、十分なIPを確保するためにネットワークをセットアップする必要があります。なぜなら、IPv4では、IPアドレスの枯渇が現実の問題であり、自然な発想としてオーバーレイネットワークを使用したくなるかもしれません。しかし、オーバーレイネットワークは必然的にレイテンシーを追加することになり、これは私たちがここで達成したいことの妨げとなります。
オーバーレイネットワークの代わりに、特別な範囲の非ルーティング可能なIPを使用することができます。この例では、2つのCIDRブロックで、ノードとポッド用に130のIPを使用できます。ここで通常よく質問されるのが、「IPv6はどうですか?」ということです。はい、IPv6は最終的にすべての枯渇問題を解決してくれます。KubernetesはIPv6を2年前からサポートしており、Apache Sparkはバージョン3.4以降でIPv6をサポートしています。しかし、スタックのどこかやクラスターが通信する何かがまだIPv6をサポートしていない可能性があります。これは確かに選択肢の1つですが、使用を選択する場合は、徹底的にテストしてください。いずれにせよ、十分なIPを確保できれば、クラスターの作成に進み、クラスターにアドオンを追加し始めることができます。クラスターのセットアップは、必須コンポーネントの追加から始まります。
VPC CNIから始めると、VPC CNIにはWARM_ENI_TARGET=1というデフォルト設定があります。これは、インスタンスが起動する際に、事前に温められたIPのセットを保持するENIを持つことを意味します。これらのIPの1つがワーカーノードに割り当てられ、Spotインスタンスが起動すると、それらの事前に温められたIPから割り当てられます。
例えば、c5.2xlargeインスタンスを使用する場合、ENIは15個のIPを保持します。 しかし、アナリティクス用途では通常、c5.18xlargeのようなより大きなインスタンスを使用します。これには2つのENIがあり、それぞれ50個のIPを保持し、合計で100個のIPとなります。アナリティクスでは、Podは比較的大きくなる傾向があるため、このインスタンスに100個ものPodをスケジュールすることはありません。これらのIPの多くは未使用のまま残り、その100個のIPプールでも十分ではない可能性があります。
この問題に対処するため、VPC CNIのMAX_ENIを1に設定できます。2つ目のオプションであるmaxPods=30は、CNIで30のような静的な数値に設定できます。私たちのデータを確認するか、Blueprintsを使用してください。異なるLinuxフレーバーに対して、インスタンスサイズに基づいてこのオプションを自動的に設定する様々なパターンがあります。VPC CNIは、EC2 APIと頻繁にやり取りを行い、IP毎に1回のAPIコールを行います。1つのインスタンスでは問題ありませんが、100個のインスタンスを同時に立ち上げるとAPIがスロットリングされる可能性があります。解決策は、Prefix Delegationを有効にすることです。これにより、16個の IPを1つのクエリにまとめることができ、EC2 APIクエリを16分の1に削減できます。
VPC CNIの設定が完了したら、次はCoreDNSについて話しましょう。 CoreDNSがすべてのパーティーに招待される理由をご存知ですか?それは、すべての問題を解決するからです! アナリティクス用途では、多くのインスタンスが立ち上がるため、CoreDNSを事前にスケールアップする必要があります。以前は、Cluster-Proportional-Autoscalerというオープンソースプロジェクトを使用してCoreDNSをスケールする必要がありました。朗報として、5月にCoreDNSのマネージドスケーリングを発表しました。EKSバージョン1.25とCoreDNS 1.9以降を使用している場合、 5月以降、この機能はすでに利用可能で、有効化するだけです。
また、NodeLocal DNSというオープンソースプロジェクトもインストールする必要があります。 NodeLocal DNSは、各ノードで実行されるDaemonSetで、クエリをキャッシュしてCoreDNSの負荷を軽減します。CoreDNSが外部ドメインをどのように解決するか見てみましょう。s3.amazonaws.comのようなドメインが与えられると、ndots:5という設定を確認します。これは、CoreDNSがそのドメインを見て、ドットが2つしかないため(5未満)、クラスタードメイン内部のものと判断することを意味します。searchラインのすべてのオプションを付加して、5回の不要なクエリを実行してから、外部をチェックします。 CoreDNSのndots:5設定は変更すべきではありませんが、Pod専用にndotsを2に設定することはできます。これにより、ドメインを見てドットが2つあることを認識します。
すぐに解決されるため、1回のクエリで済み、CoreDNSポッドへの負荷が軽減されます。これがCoreDNSがパーティーのセレブリティステータスを維持できる理由です。
ビジネスアプリケーションのためのコンピューティングリソースのスケーリングについてお話しします。 ビジネスアプリケーションでは、多くのお客様がCluster Autoscalerというオープンソースプロジェクトを利用する傾向にあります。Cluster AutoscalerはCPUとメモリに基づいてインスタンスをスケールアップし、通常インスタンスを起動するのに2〜3分かかります。データプラットフォームチームが最初に別のオープンソースプロジェクトであるKarpenterに移行しているのを目にします。KarpenterはAWSから生まれ、昨年私たちがオープンソース化してCluster Autoscalerに寄贈し、今年GAに昇格しました。現在はV1として安定版となり、すぐにでも使用できる状態です。
AppsFlyerの事例:Victor GershkovichによるEKS移行の成功談
Karpenterの特徴は、AWSの価格設定を完全に把握していることです。ポッドのメモリとCPUの要件に合うインスタンスを選ぶだけでなく、最もコスト効率の良いインスタンスを選択します。また、Karpenterはインスタンスのスケールアップが非常に速く、通常1分以内で完了します。Karpenterの設定の詳細に入る前に、Sparkジョブの仕組みについて説明しましょう。データエンジニアがSparkジョブを投入すると、ドライバーポッドが起動し、そのドライバーポッドがジョブの管理を担当します。ドライバーポッドはExecutorのスケジューリングを担当し、Executorが中断された場合でもドライバーポッドがそれを把握します。ドライバーポッドは新しいExecutorをスケジュールしてジョブを完了させます。ドライバーポッドが中断された場合は、ジョブ全体をやり直す必要があります。
これはKarpenterにとって、ドライバーポッドをオンデマンドインスタンスにインストールできることを意味します。Executorは大幅に割引されたSpotキャパシティに最適です。Karpenterでは、1つのノードプールを設定し、そのノードプール内で両方のキャパシティタイプを提供し、アノテーションやラベル、あるいはTaintsとTolerationを使用して、それぞれのワークロードを適切に配置することができます。
コンピューティングのスケーリングを設定したところで、次はストレージについて説明します。ストレージと言うとき、私はSparkのシャッフルストレージのことを指しています。インスタンスタイプの名前に'd'が付いているものがありますが、この'd'はそのインスタンスにSSDドライブが組み込まれていることを意味し、これが最速のストレージとなります。そのため、これらのインスタンスとそのストレージの活用をお勧めします。インスタンスによってSSDドライブが1つのものと複数のものがあり、全容量を最大限活用するにはこれらのドライブをRAID0に設定する必要があります。Karpenterを使用すれば、instance store policy RAID0と設定するだけで簡単です。
これまでは計算を行うユーザーデータスクリプトが必要でしたが、今では素晴らしく簡単になりました。Executorがそのストレージに直接アクセスできるため、Executorのホストパスを設定する必要もなくなりました。ただし、Sparkの設定でストレージの使用量を制限したい場合があるかもしれませんが、それだけです。短時間のジョブには最適ですが、長時間実行されるジョブの場合、そのインスタンスが中断されると、ドライバーポッドは認識して他のExecutorを起動しますが、チェックポイントは失われてしまいます。Executorは最初からやり直す必要があるため、より長時間実行されるジョブの場合は、EBSボリュームを使用するのがより良い選択となります。Spark設定では、この設定でドライバーポッドがEBSボリュームを認識できるようになります。これにより、インスタンスが中断された場合、新しいインスタンスが起動し、ドライバーポッドがEBSボリュームの場所を把握して新しいExecutorにアタッチし、新しいExecutorは中断された時点から処理を再開できます。新しいExecutorは、Amazon EBSにチェックポイントデータがあるため、中断された時点から処理を再開できるのです。
これら2つのストレージオプションは、相互に排他的なものではありません。エンドユーザーに両方のオプションを提供し、実行するジョブに応じて選択してもらうことができます。
先ほど申し上げたように、Karpenterはインスタンスを非常に素早く起動します。次のステップでは、Podを実行するためのイメージをインスタンスにダウンロードする必要があります。ここでの目安として、インスタンスが必要になってからPodが起動するまでを1分以内に収めることを目指します。最適化のために、まず第一に、それらのイメージをインスタンスにできるだけ近い場所に配置してください。Amazon ECRに保存している場合は、クロスリージョンレプリケーションを使用して、必ずそのリージョンに配置してください。別のリポジトリに保存している場合は、ECRのプルスルーキャッシュをサポートしているので、それを利用してリージョン内に配置し、VPCエンドポイントを設定することで、ネットワークを外部に出ることなくイメージをダウンロードできます。
特に5~10ギガバイトのような大きなイメージの場合、これだけでは1分以内に収まらないかもしれません。その場合は、JARファイルやその他のライブラリなどの大きなファイルをイメージから切り離すことができます。これらのファイルをS3 Express One Zoneに保存し、イメージをスリム化します。ダウンロード時には、S3-Mountpointを使用してこのS3バケットをドライブとしてExecutorにマウントします。
これで1分以内に収まるようになりましたが、この第一層での最後の考慮事項はモニタリングです。本番環境に投入する前に、必ずモニタリングを設定してください。多くの方がApache Sparkやその他のオープンソースソフトウェアのメトリクスを監視されていると思いますが、さらに3つの追加項目の監視をお勧めします。まず、Kubernetesコントロールプレーンを監視してください。Kubernetesのコントロールメトリクスを公開しているので、EKSのベストプラクティスガイドを参照してください。次に、AWS APIのモニタリングを確実に行ってください。CloudWatchメトリクスを提供しており、先ほど述べたようにVPC CNIを使用している場合、EC2 APIがスロットリングされる可能性があります。GrafanaやモニタリングベンダーのデータソースとしてCloudWatchを通じて、これらのスロットリングメトリクスにアクセスできるようにしてください。EBS APIについても同様です。
最後に、必ずネットワークを監視してください。例えば、CoreDNSはUDPプロトコルを使用しているため、LinuxのConnection Tracking Tableが満杯になると、CoreDNSパケットがドロップされてしまいます。CoreDNSメトリクスからこれを把握できるようにする必要があるため、ネットワークの監視が重要です。ネットワークのモニタリングについては、EKSのベストプラクティスガイドを参照してください。これで第一層は完了です。これにより、スケーラブルで、十分なパフォーマンスを持ち、コスト効率の良いクラスターが実現できました。
次に、このクラスターに様々なオープンソースソフトウェアを追加して、目的に特化したクラスターを構築していきます。 お客様が最もよく使用されるオープンソースプロジェクトは、Apache FlinkとApache Sparkです。 よくある質問は、これらを同じクラスターで実行するか、別々のクラスターに分けるかということです。答えはクラスターの規模によって変わってきます。200〜300ノードまでの比較的小規模なクラスターであれば、同じクラスター上で実行できます。ただし、それ以上の規模になる場合は、分離を検討し始めるのが良いでしょう。
この後の話は主にApache Sparkに焦点を当てていきます。オープンソース版のApache Sparkを使用する場合は、Spark Operatorの使用をお勧めします。今年の初めに、Data EKSのメンテナーがコミュニティと協力して、Spark OperatorをKubeFlowコミュニティに寄贈しました。それ以降、数多くのバグ修正が行われ、メンテナーも活発に活動しています。もうひとつのオプションコンポーネントはスケジューラーです。ジョブは先入れ先出し方式でスケジュールできますが、HadoopやYARNの世界から来られた方は、優先キューやギャングスケジューリングをご希望かもしれません。その場合は、Sparkとの相性が非常に良い、Yunikornというもう一つのオープンソースプロジェクトをお勧めします。
ジョブには、ワークフローエンジンが必要になります。最も一般的なのはApache Airflowで、これは自分でインストールして管理することもできますし、マネージドサービスを利用することもできます。最近では、Argo WorkflowsやAWS Step Functionsを使用してワークフローを処理するケースも増えてきており、これで第2層の説明は終わりです。
テナントのオンボーディングに進む前に、テナント分離戦略について話しましょう。チームごとに1つのクラスターを使用するお客様もいますが、大多数のお客様は実際にはマルチテナントクラスターを採用し、Namespace as a Serviceを利用しています。第3層でNamespace as a Serviceを使用する場合、Namespaceやspark API、その他いくつかのコンポーネントを作成する必要があります。
これを別の視点から見てみましょう。具体的には、各層の自動化を誰が作成し、誰がその自動化を利用するのかということです。第1層については、通常データプラットフォームチームが担当し、主にTerraformを使用します。彼らがTerraformの設定を作成し、それを利用します。第2層も同様で、Terraformやその他のツールを使用して、このオープンソースソフトウェアのインストールと管理を行います。しかし、第3層では状況が少し異なります。
レイヤー3では、Data Engineerは通常チケットシステムを通じて作業を依頼するか、あるいはTerraformプラットフォームへのアクセス権を持っていても、使い方に不慣れなため、サポートを求めてチケットを発行する必要があります。これらのチケットの主な理由はAWSリソースに関するものです。なぜなら、Helm Chartなど他のコンポーネントについてはツールが用意されているものの、AWSロール、ポリシー、S3バケット、RDSインスタンス、その他の権限が必要なAWSリソースを作成する際には、Data Engineerがチケットを発行する必要があるからです。このような構成を作成するには、セキュリティチームの承認を得て、Data Platformチームの誰かがチケットを受け取り、Terraformのコードをコピー&ペーストし、そしてComplianceチームがそれを監査する必要があります。
このプロセスを使用する代わりに、ユーザーに適切なインターフェースを提供することで最適化できます。私たちは、それはAPIであるべきだと考えています。Kubernetes APIを使用して、IAMポリシーやS3バケットなどを作成するために、このオープンソースプロジェクトをインストールできます。AWS Controllers for Kubernetes(ACK)は、AWSが最近リリースしたオープンソースプロジェクトです。今年、Amazon EKSサービスチームがACKのすべてのコントローラーの所有権を引き継ぎ、現在50のGAコントローラーがあり、つまり50のAWSサービスをカバーしています。GAステータスとは、エンタープライズサポートの対象となることを意味します。
ACKを使用することで、Kubernetes APIを拡張し、テナントのオンボーディングと完全なNamespaceベンディングを実行するためのAPIを作成できます。1チーム1クラスターを使用している場合、これら3つのレイヤーすべてに拡張しようとしているお客様を見かけます。しかし一般的に、大多数のお客様はここにいて、このアプローチに非常に満足しています。先ほど私が言及したように、同じコンピュートリソースに対して2つの別々のプラットフォームセンターをサポートする2つの別々のチームを持つお客様がいます。もしあなたが会場にいる経営者であれば、これが良いことなのか悪いことなのか、そしてそれについて何をすべきか - チームを統合すべきか、別々のままにすべきか - を考えているかもしれません。
私からアドバイスをさせていただきます。組織の成長を制限したくはありませんよね。プラットフォームチームの数自体はそれほど重要ではありません。重要なのは、ツールとプラクティスを標準化して、組織の成長に応じてコラボレーションを促進できるようにすることです。
Terraformを使用する場合、このシナリオを考えてみてください:もし10のプラットフォームチームがあり、Terraformを標準化したとしても、間違いなく10の異なるコードベースが生まれることになります。そのため、ツールだけでなく、ツールの使用方法も標準化する必要があります。先ほど述べたように、エンジニアにAPIを提供できるように、AWS Controllers for Kubernetes(ACK)APIをそのようなツールの1つとして活用したいと考えています。
Analyticsプラットフォームをスケールさせるために実施すべき3つのポイントは次の通りです:先ほど説明したベストプラクティスを活用してクラスターのスケーラビリティ、パフォーマンス、コストを最適化すること、 プラットフォームチームの数を制限するのではなく、組織内でツール、ベストプラクティス、プロセスを標準化することで組織の成長を促進すること、そして エンドユーザーがプラットフォームにオンボーディングできるインターフェースを提供して満足度を高めることです。これらは理論としては素晴らしいものですが、実践していただいているお客様がいらっしゃるからこそ、単なる理論で終わらないのです。
Karpenterを活用したスケーリングとコスト最適化
私たちのお客様であるAppsFlyerをお迎えできることを大変嬉しく思います。Victorが、これらすべてをどのように実践し、さらにそれ以上のことを大規模に実現したかについてお話しくださいます。ありがとうございます。Christina、ありがとうございます。ここにいられることをとても嬉しく思います。皆さん、こんにちは。Rolandは、Sparkワークロードを実行するための様々なオプションについてお話ししました。 たった1つの決断でデータ組織を変革できるとしたらどうでしょうか?パフォーマンスを向上させ、可観測性を強化し、コストを削減し、開発者に力を与えることができるのです。フィクションのように聞こえますよね?
実は、1年前に私たちが下した決断についてお話ししたいと思います。 私の名前はVictor Gershkovichです。AppsFlyerで6年間働いており、リアルタイムおよびAnalyticsデータプラットフォームを担当するData Platform Groupのリーダーを務めています。AWS エコシステムとデータ処理について豊富な経験を持っており、AppsFlyerの大きな利点の1つは、大規模にこれらを実践できることです。
世界には70億台以上のスマートフォンがあることをご存知でしょうか?各スマートフォンには平均して60以上のアプリがインストールされています。皆さんのスマートフォンとアプリを見せていただければ、必ずAppsFlyer SDKが組み込まれているアプリを見つけることができます。AppsFlyerは、 アプリ所有者が広告キャンペーンを最適化し、アプリに適切なオーディエンスを見つけるお手伝いをしています。これを実現するために、詳細な分析を提供し、日々膨大な量のデータを処理しています。
それでは、Analyticsワークロードについて、そしてデータオペレーションをどのように実行しているかについて見ていきましょう。 まず、Apache Sparkについてお話ししましょう。Sparkは大規模データ処理のためのオープンソースAnalyticsエンジンです。大規模なデータを扱うほぼすべての組織でSparkを見つけることができます。主な特徴を見ていきましょう。Sparkは通常、 ダウンストリームデータの消費と生成のためのバッチ処理として使用されます。ジョブに応じて、異なるCPU、メモリ、I/Oパフォーマンスが必要となります。 処理時間は非常に重要で、適切なコンピューティングとスケーリング戦略が重要な要素となります。
Sparkジョブは通常ステートレスな性質を持っています。しかし、中断された場合はデータの再処理が必要となり、SLAに影響を及ぼす可能性があります。それでは、AppsFlyerがSparkジョブで直面している課題についてお話ししましょう。 私たちは毎日100テラバイト以上のデータを処理しています。 常時数千もの異なるジョブを実行しており、 IntelからGravitonまで、CPU、メモリ、ストレージに最適化されたインスタンスなど、あらゆる種類のコンピューティングリソースを活用しています。
私たちのシステムは、データのトレンドに応じて非常にダイナミックに変化します。 毎秒数百万のイベントを処理し、トラフィックは急激に増減する可能性があります。そのため、スケーリング戦略において非常に効率的である必要があります。また、SLAについても非常に厳格です。 データカンパニーとして、ビジネスに影響を与えないよう、確実にデータを時間通りに処理しなければなりません。
これらの課題に対処するため、Configuration Managementと社内ツールで管理されていた2つのインスタンスから、Amazon EKSへワークロードを移行することが最善の策だと判断しました。詳しく見ていきましょう。アナリティクス処理に関して、EKSエコシステムが特に優れている分野がいくつかあります。その中から3つを取り上げ、それぞれの価値についてご説明します。 スケーリングとコンピューティングの最適化のためのKarpenter、データに関する貴重な洞察を提供できる観測可能性、そして データエンジニアの権限付与について説明していきます。
このスライドを覚えておいてください。 これは、インプット、処理、アウトプットを完璧に示しています。データレイク領域に焦点を当てて、主要なデータ処理のCompactionジョブがどのように実行されているかを例として説明させていただきます。 AWSでは、Compactionとは、小さく断片化されたデータファイルをより大きな整理されたファイルにマージして、ストレージの効率性とパフォーマンスを最適化することです。これは通常、データレイクへの最初のエントリーポイントとなります。私たちは1時間ごとに実行し、実行時間の異なる約150のジョブがあり、各イテレーションで約60テラバイトのデータを処理しています。
まず、Karpenterについてお話しします。これは、コンピューティングのスケーリングとコストパフォーマンスに関する課題を解決し、目標を達成するのに役立ちました。 EKSとKarpenterに移行する前の、EC2ベースのSparkクラスターがどのような状態だったかをご覧ください。これはConfiguration Managementツールで管理されており、黄色の線が使用率を、紫の線がクラスターサイズを表しています。 ご覧の通り、スケーリングメカニズムが効果的に機能していませんでした。使用率が低下した際に、ノードのスケールダウンが追いついていなかったのです。
Karpenterはこの問題を解決します - 毎時の計算要件に応じて最適なコンピュートを選択し、各イテレーションでの使用率に応じて効率的にスケールアップとダウンを行います。私たちは約60ノードまでスケールアップし、処理が終わるとスケールダウンします。ノードの使用率を見てみると、 私たちの理想的なポイントである80%付近でピークを迎え、フル稼働時は安定しています。 使用率が低下した時のみスケールダウンを開始します。データ処理は計算能力の面で非常にコストがかかります。このアプローチにより、24時間サイクルにおけるアイドル時間を最小限に抑え、リソースの無駄や不要なコストを排除しています。
1,600回以上のノードの作成と終了を行っています。これは私たちのCompactionワークロードだけの数字であることを覚えておいてください - 他にも何百もの異なる処理ワークロードがあるので、日々のノードの終了と作成の数がどれほどになるか想像できるでしょう。 インスタンスの分布を見てみましょう。Karpenterの戦略は、その時点で最も安定してコスト効率の良いノードを選択することです。私たちはGraviton第3世代を使用し、キャパシティがない場合は第2世代にフォールバックします。 Spotインスタンスのみを使用していますが、ベアメタルノードを見てください - マシンリソースの完全なコントロール、ハードウェアへの直接アクセス、ハイパーバイザーのオーバーヘッドなし、非常に高いパフォーマンスを実現しています。これは私たちのノードプールの15%を占めています。Sparkのようなステートレスまたはダイナミックなアプリケーションに対して、最後に手動でベアメタルノードを選択したのはいつでしょうか?また、新世代のインスタンスを使用するオプションもあり、利用可能になり次第プロビジョニングできます。
また、複数のAvailability Zoneにノードを分散させています。Karpenterは 最もコスト効率の良いゾーンでプロビジョニングを行うことを確実にします。その日はZone Aが優勢で、Zone Bと比べて20%多くのノードがありました。また、ジョブのPodが同じAvailability Zone内で実行されるようにすることで、クロスAZデータ転送とそれに関連するコストを排除しています。
しかし、その日はすべてが順調というわけではありませんでした。24時間の間に多くのSpot中断があり、時には1時間に数十回も発生し、これは本来ならSLAに壊滅的な影響を与えるはずでした。しかし、 KarpenterによるSpot終了の効果的な処理のおかげで、Spotの終了シグナルをSparkにフックすることができ、これにより2分以内に中間段階のデータを移行するオプションが得られます。このアプローチにより、ノード障害時の再処理の必要性がなくなります。これによってSpot終了がワークロードにほとんど影響を与えなくなり、 SLA内に十分収まっています。そして、その24時間の中で最も長いジョブでもわずか33分でした。
いくつかの良好な結果をお見せしました。では、 いくつかのシンプルな設定変更で、ほぼ同じパフォーマンスを達成する方法を見てみましょう。スケーリングには、高速な起動時間とカーネルパフォーマンスに最適化されたAmazon Linux 2023を使用しています。 これにより、10秒未満でノードをプロビジョニングできます。デコミッションについては、 処理のトレンドに応じてノード分散予算を調整します。アイドル時間を減らすために積極的にデコミッションできる時間帯と、通常ピーク使用率時に高パフォーマンスを維持するために控えめにデコミッションする時間帯を設定します。
この設定は、Sparkがノードの終了を認識し、 Sparkのシャッフリングを有効にして、2分以内での移行を確実にするために使用されています。最適なパフォーマンスを得るために、ローカルストレージを活用しています。 レジリエンシーとコスト効率を高めるため、各Sparkジョブを同一のAvailability Zone内で実行するように設定し、AZ間トラフィックとそれに関連するコストを排除しています。このセクションでは、最適なパフォーマンスを得るために、ローカルストレージを備えたGravitonインスタンスの使用について定義しています。特定のノードの配置を試みましたが、どれだけ多くのバリエーションを試しても、Karpenterの自動選択が常にコスト効率の面で優れていたことを申し上げておく必要があります。
データ処理の可観測性向上:メトリクスの統合と洞察
チューニングについては以上です。次は、観測可能性についてできることを見ていきましょう。Karpenterがどのように私たちのコンピュートを管理・スケーリングするのかを見てきました。では、Karpenter、Kubernetes、そしてSparkからのメトリクスを組み合わせることで、プラットフォームからどのような有益な洞察が得られるのかを見ていきましょう。皆さんの中で、コンパクション処理における各データ処理フローの割合を把握している方はどれくらいいらっしゃいますか?私たちは、各処理サイクルにおいて、それぞれの処理の正確な比率と、開始・終了のタイミングを把握しています。ここでご覧いただけるように、クリックデータは全体の約28%を占めており、各サイクルの中盤から開始されます。
これにより、任意の時点での各データセットの分布と重みを確認することができます。さらに、日次、週次、月次のトレンドを見ることで、システムとビジネスへの影響を理解することができます。このメトリクスを見てください:先週と比べてクリック処理が8%減少し、別のデータセットが35%増加していることがわかります。これは懸念事項かもしれません。データドッククエリを確認すると、サービスとSparkからのメトリクスを組み合わせることで、この情報が簡単に取得できることがわかります。
では、コスト見積もりのためにKarpenterのメトリクスを追加するとどうなるでしょうか?KarpenterはインスタンスとAZごとのコストを送信し、Sparkとサービスのデータと組み合わせることで、各データ処理のコストを計算することができます。これにより、データ処理のコストをほぼリアルタイムで1分ごとに把握できます。
このほぼリアルタイムの処理コストデータは、エンジニアリングとビジネスの両面で重要です。コードのデプロイがコストにどのように影響するかを監視し、トレンドに基づいて意思決定を行うことができます。顧客に提供するサービスの価格設定をより適切に行うことができます。さらに一歩進んで、これをデータリネージに統合することで、データ処理パイプライン全体の総コストを把握することができます。何を最適化できるか、何が冗長かを判断できます。観測可能なメトリクスを組み合わせることで、データフローの包括的な視点が得られ、データに基づいた意思決定を行うことができます。
Data Engineerの自律性とプラットフォーム最適化:まとめと展望
私がお見せしたそれらのメトリクスやパフォーマンスは、Platform Engineerだけが使い方やチューニング方法を知っているのでは意味がありません。先ほどは、ほんの一部のオプションをお見せしただけです。私たちは、Data Engineerに対して、彼らのアプリケーションとプラットフォームに関する完全な自律性とコントロールを与え、それを推奨しています。ベストプラクティスに基づくデフォルト設定とポリシーを提供していますが、必要に応じてそれらを変更したり上書きしたりすることができます。すべてはソースコードを通じて行われます。
インフラストラクチャ、アプリケーション、サードパーティ統合のためのリポジトリデプロイメントユニットのアクションを定義する、詳細なGit構造を作成しました。また、開発、ステージング、本番環境を分離し、それぞれが独自のGitフローを持つ環境も構築しました。このアプローチにより、単一のインターフェースからインフラストラクチャ、証明書、アプリケーションコンポーネントを管理でき、実行とデプロイメントの自動化されたワークフローとバリデーションを実現できます。これにより構成のドリフトを防ぎ、現在の状態を維持し、数分以内にアプリケーションとインフラストラクチャを立ち上げたり変更したりすることができます。これによってPlatform Engineerへの依存性が解消されます。
これによりData Engineerの開発速度と自律性が向上し、双方の知識向上にも貢献します。冒頭で、ある1つの決断が私たちの組織を変えたとお話ししました。お気づきの通り、その決断とはSparkワークロードをEMRからAmazon EKSに移行することでした。では、その価値をお見せしましょう。これは若かりし頃の私ですが、以前使用していたEMRのウィンドウ化されたSparkクラスターと比較すると、Amazon EKS、Karpenter、Gravitonを使用することで、コストを60%削減しました。SLAを35%改善し、可観測性も大幅に向上させました。そして最後の仕上げとして、Platform Engineerの運用負荷を削減し、彼らの全体的な満足度も向上させることができました。
ありがとうございます。素晴らしいプレゼンテーションでした。ここで覚えておいていただきたいのは、分析のためのAmazon EKSの最適化と監視、そしてベストプラクティスです。組織の成長を促進するためのツールとプラクティスを整合させてください。Christinaが話していたレイヤーを見てきましたので、Victorのように幸せになれます。そしてAPIを提供することを忘れないでください。開発者、Data Engineer、Data Scientistは、あなたのプラットフォームのお客様です。もし彼らが構築できなければ、APIを提供できなければ、結局使われないプラットフォームになってしまいます。そのため、制御のための自動化を提供しながら、Data Engineerが自律的に作業できるようにAPIを提供することが重要です。私たちは幸せな統合を実現できています。
皆様、ご参加ありがとうございました。Amazon EKSでのデータ処理など、セッションリソースについては、こちらのQRコードをクリックまたはスキャンしてください。ご来場ありがとうございました。カンファレンスの残りもお楽しみください。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion