re:Invent 2024: AWSによるApache KafkaとFlinkの大規模運用
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Operate and scale managed Apache Kafka and Apache Flink clusters (ANT342)
この動画では、AWSのマネージドサービスを使用してApache KafkaとApache Flinkを大規模に運用する方法について解説しています。Apache Kafkaの運用における課題として、クラスターの計画・プロビジョニング、高可用性の維持、インフラのスケーリングなどが挙げられ、これらの課題に対してAmazon MSKのExpress Brokerが提供する解決策を紹介しています。また、Apache Flinkの運用においても同様の課題があり、Amazon Managed Service for Apache Flinkを使用することで、サーバーレスかつ従量課金制で、スケーリングやセキュリティパッチなどの運用負荷を軽減できることを説明しています。両サービスを活用することで、ストリーミングデータの処理を効率的に行えることが示されています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
Apache KafkaとApache Flinkの紹介:データストリーミングの双子
セッション342へようこそ。ここでは、マネージドサービスを使用してKafkaとFlinkを大規模に運用する方法についてお話しします。私はSai Maddaliと申します。AWSでマネージドKafkaとFlinkサービスのプロダクトチームを率いています。双子の父親として家庭でも大変なのに、職場でもKafkaとFlinkという双子に出会ってしまいました。
私の双子には面白い話があります。見た目は全く同じで、同じ曜日、同じ日に生まれました。もちろん双子なのですが、面白いことに生まれた年が約6年離れているのです。この話は、Apache KafkaとApache Flinkにも似ています。何年も離れて誕生したKafkaとFlinkは、今やストリーミングデータの切っても切れない双子となっています。私の友人のAliも似たような経験をしています。皆さん、こんにちは。Ali Alemiです。AWSのシニアストリーミングアーキテクトをしています。私も双子の父親で、私の双子は全く同じ年齢です。双子の父親として既に手一杯だと思っていたのですが、Apache KafkaとApache Flinkに出会うまではね。私の双子のように、この2つは仲良く連携しますが、課題もあります。でも心配いりません。私たちの双子と同じように、Apache FlinkとApache Kafkaを大規模に管理するための戦略があるのです。そして、まさにそれについて今日お話しします。
今日のセッションで取り上げる内容を簡単にご紹介します。まず、データストリーミングとは何か、そして私たちのお客様がなぜデータストリーミングに興味を持っているのかについてお話しします。次に、なぜ人々がストリーミングアプリケーションを構築するためにKafkaとFlinkに注目しているのかについて説明します。自分で管理する場合のKafkaの大規模運用に必要なことと、マネージドサービスを使用した場合の簡便さについて比較します。Flinkについても同様の比較を行い、Aliがその部分を担当します。最後に質疑応答の時間を設けています。
ストリーミングデータの価値と活用事例
お客様からよく聞くのは、ストリーミングアプリケーションを構築するのに、今ほど良い時期はないということです。その理由をご説明しましょう:これらのお客様はリアルタイムインサイトの価値を理解しています。多くの方が銀行のサービスを利用していますが、不正利用のアラートは、イベントが発生した瞬間に欲しいでしょうか、それとも1時間後や数日後でも良いでしょうか?もちろん、その瞬間に欲しいですよね。小売業者であれば、リアルタイムの在庫状況にアクセスしたいですか?もちろんです。商品を顧客に確実にお届けし、コストを最適化したいからです。きっと多くの方がSRE(Site Reliability Engineer)の経験をお持ちでしょう。アラートはイベント発生時に欲しいですか、それとも1時間後でも良いですか?もちろん、イベント発生時です。
ご覧の通り、タイムリーなビジネス判断にはリアルタイムインサイトが非常に重要です。コストは私たち全員にとって最重要課題であり続けています。ストリーミングデータを使用すると、ノイズをフィルタリングして、シグナルにすばやくたどり着くことができます。例えば、Webサイトを管理していて、特定のユーザーの特定の購入インタラクションのみを捕捉したいとします。一つのアプローチは、全ユーザーの全インタラクションデータを収集して保存し、インサイトが必要なときにそれを毎回処理する方法です。これに対してストリーミングでは、データが生成される時点でキャプチャし、最も関心のあるインタラクションだけをフィルタリングできるため、コンピューティングとストレージのコストを節約できます。
お客様がストリーミングデータを選択する3つ目の理由は、システムを常時同期させておく必要があるからです。フードデリバリー企業を例に挙げると、常に数百万件のトランザクションに対応できるスケーラビリティが必要です。そのため、特定の機能に特化したマイクロサービスアプリケーションの構築に着手します。ここで最も重要なのは、これらのシステムが常に同期している状態を保つことであり、ストリーミングデータは企業全体でのデータ移動において重要な役割を果たします。お客様から注文に関する問い合わせがあった際、営業担当者やカスタマーサービス担当者がリアルタイムでその情報にアクセスできることで、全体的なカスタマーエクスペリエンスが向上します。まとめると、ストリーミングデータは、ストリーミングアプリケーションを通じてお客様に優れた結果をもたらし、エンドユーザーにより良いアウトカムを提供することができます。
KafkaとFlinkの特徴と課題:マネージドサービスへの注目
先ほど申し上げたように、お客様は2つの強力なテクノロジーに注目しています。それは、非常に低いレイテンシーで大量のデータを取り込むApache Kafkaと、リアルタイムインサイトを生成するためにデータを処理するApache Flinkです。興味深いことに、私の双子のように、Apache KafkaとFlinkは生まれた年は異なりますが、非常によく似た特徴を共有しています。それらの特徴を見ていきましょう。まず1つ目は、多様なユースケースをサポートしているということです。
Apache KafkaとApache Flinkを使用して、データの取り込み、変換、Data Lakehouseへのロード、Icebergテーブルへのデータロード、そして詳細な分析のための処理が可能です。また、KafkaとFlinkを使用してマイクロサービスアプリケーションやイベント駆動アーキテクチャを構築することもできます。不正検知や異常検知などのリアルタイム分析にもKafkaとFlinkを活用できます。exactly-once処理などの障害耐性や処理保証に関する特定の機能を備えており、開発者は迅速かつ容易にこれらのユースケースを実現できます。さらに、幅広い統合機能をサポートしており、企業内の様々なシステムとKafkaやFlinkを統合することができます。
AWSは多くのマネージドサービスとの統合機能を提供しており、その一部はオープンソースコミュニティにも還元しています。また、両者ともスケールアウトアーキテクチャを採用しているため、処理するデータが増えても、スケーリングの限界を心配する必要がありません。これらのテクノロジーは強力なコミュニティに支えられており、オープンソースエコシステムに複数の企業が構築した継続的なイノベーションにアクセスでき、最新機能に随時アップグレードできます。ご覧の通り、ストリーミングデータには大きな可能性があり、KafkaとFlinkはアプリケーション構築のための重要なテクノロジーとなっています。
私の頭に浮かぶ基本的な疑問は、お客様がストリーミングデータ上で10倍多くのユースケースを構築するために何が必要かということです。お客様に伺うと、 KafkaとFlinkに関する特定の課題があると言われます。皆さんの中で、実際にKafkaとFlinkを使用または運用している方はどれくらいいらっしゃいますか?もし経験がおありでしたら、スライドの内容に共感していただけるのではないでしょうか。セットアップは簡単ではなく、スケーリングが難しく、高可用性を最初から実現することも容易ではありません。このセッションでは、その理由を見ていきます。最後に重要なポイントとして、運用面とインフラコストの両面で維持が必要なため、大規模な運用には費用がかかる可能性があります。
これらの課題が依然として存在するため、お客様はAmazon Managed Streaming for Apache KafkaとAmazon Managed Service for Apache Flinkに注目しています。この2つのサービスの目的は、インフラストラクチャの管理や重労働をAWSチームに任せることでこれらの課題に対処し、お客様がKafkaやFlinkのアプリケーションの開発やクラスターの運用に専念できるようにすることです。なぜそうなのか、このプレゼンテーションで詳しく説明していきます。 様々な業界の、あらゆる規模のお客様がKafkaとFlinkのマネージドサービスを利用しています。The Orchardは、データベースの同期にかかる時間を数時間から数分に短縮するためにAmazon MSKを使用しています。Nexthinkのようなお客様は、MSKを使用して兆単位のイベントをストリーミングし、小規模なチームで大規模なスループットに対応できています。
そして私の好きなユースケースはNHLです。ホッケーファンの方はどれくらいいらっしゃいますか?NHLは、私たちのFlinkマネージドサービスを使用して、2人のプレイヤーが対峙したときのフェイスオフを計算し予測しています。パックが落ちたとき、誰が勝つかの予測確率を計算するのです。これは、NHLがFlinkやその他のサービスを使って観戦体験を変革している良い例です。 私の7歳の娘がよく聞く質問のように、「これができる」と言うと、次に必ず「なぜ?」と聞かれます。これらのお客様がなぜマネージドサービスに移行しているのか、説明していきましょう。まずはKafkaから始めて、スケールでKafkaを運用するために必要なことを見ていきます。
Kafkaクラスターの運用と課題:プロビジョニングからスケーリングまで
管理者がKafkaを管理する際に経験する過程について説明したいと思います。 通常、次の3つの活動のいずれかに時間を費やしています:クラスターの計画とプロビジョニング、高可用性を維持した運用(問題が発生したときは全員がページを受け取ります)、そしてインフラストラクチャのスケーリングとクラスターの変更です。これらの各フェーズにおける課題と、マネージドサービスがどのように役立つのかを順を追って見ていきましょう。 これらの活動に入る前に、Kafkaの2つの基本的な概念について説明したいと思います。一般的なKafkaクラスターには複数のBrokerがあり、各Brokerにはコンピュートレイヤーとストレージレイヤーという2つの側面があります。
コンピュートレイヤーは、リクエストの処理、認証、認可、そしてセマンティクスの維持を担当します。認証、認可、セマンティクスの維持は、Producerのべき等性において重要な側面です。ストレージコンポーネントは、データレイアウトと永続的なストレージの確保を担当します。Apache Kafkaは元々オンプレミス環境向けに開発されたため、コンピュートとストレージは密接に結合されており、通常ストレージはコンピュートノード上に配置されています。これは、両者の障害モードが相互に関連していることを意味し、コンピュートノードを失うと、すべてのストレージも再構築する必要があります。
クラウドに移行すると、 EBSのようなネットワークアタッチドストレージを使用するため、これらの障害ドメインの一部はより管理しやすくなります。コンピュートとストレージの障害モードはかなり分離されているため、Brokerを失ってEC2インスタンスが再起動しても、ストレージは intact な状態を保ちます。これにより、オンプレミス環境と比べて障害からの平均復旧時間が改善されます。また、停電などのインフラストラクチャ障害に対する保護も、クラウドの回復力により向上します。しかし、クラウド上で Kafkaソフトウェアを実行する場合でも、いくつかの考慮事項が残ります。コンピュートとストレージを一緒にスケールすることを考える必要があります - コンピュートを増やすためにノードを追加すると、ストレージも増え、ストレージ容量を増やすためにノードを追加すると、コンピュート容量も増加します。
このカップリングは、プロビジョニングとスケーリングにおいて興味深い挙動を引き起こします。あまり議論されていない別のカップリングについて、今日は詳しく説明したいと思います。まずは典型的なセットアップから見ていきましょう:3台のBrokerとPartitionを持つKafkaクラスターです。Kafkaでは、Partitionがストレージの単位となります。適切に設定されたクラスターでは、高可用性のために異なるBroker上にReplicaを持つLeader Partitionが存在します。書き込みはトピックのLeader Partitionに対して行われ、データのレプリケーションを考慮する必要があります。Leader Partitionへの書き込みは、異なるBroker上のReplicaにレプリケートされます。また、他のBroker上にもLeader Partitionを持つことができます。この例では、ProducerはBroker 1のPartition 1とBroker 2のPartition 2に書き込みを行い、データはそれぞれのReplicaにレプリケートされます。
クラスターのコンピュートとストレージをプロビジョニングする際は、書き込みと読み取りのスループットだけでなく、Broker間を流れるレプリケーショントラフィックも考慮する必要があります。障害はいつでも発生する可能性があるため、それに備えた計画が必要です。Brokerを1台失った場合に何が起こるか見てみましょう。自己管理環境でBroker 2が不健全になった場合、Kafkaを停止します。Kafkaは不健全なBrokerを検出し、Replicaを選出してフェイルオーバーを行います。この場合、Broker 1上のPartition 2のReplicaが新しいLeaderとなり、Producerアプリケーションからの全ての書き込みは、消費トラフィックと共にBroker 1上のPartition 2に向かうことになります。これにより、Broker 1は2倍のデータ負荷を処理することになるため、全てのBrokerの障害に対応できるバッファを計画する必要があります。
しばらくして、Broker 2が健全な状態に戻りオンラインに復帰した場合、そのBrokerは一定時間(例えば30分間)ダウンしていたため、Kafkaはキャッチアップを行う必要があります。Kafkaの興味深い特徴の1つは、アプリケーショントラフィックとリバランシングやリカバリーなどのシステムトラフィックを分離していないことです。分離がないため、クラスターが適切に設定されていない場合、キャッチアッププロセスがProduceやConsumeの主要な操作に影響を与える可能性があります。Brokerの復旧を高速化するように最適化すると、クラスター全体の可用性に影響を与える可能性があります。そのため、キャッチアップシナリオに備えたバッファを計画する必要があります。
考慮すべきもう1つの障害モードは、Slow Consumerシナリオです。これは、SparkジョブやFlinkジョブなどのConsumingアプリケーションがアプリケーションエラー、不適切なロジック、または問題のあるデプロイメントに遭遇した際によく発生します。処理が遅れ、例えば1時間ダウンした場合、見逃したデータ全てをキャッチアップする必要があります。
Consumerが利用できない場合のキャッチアップのためのバッファを確保することが重要です。ここで分かるように、プロビジョニングは多次元的な課題です。ワークロードに必要なインジェストトラフィックだけでなく、バックグラウンドトラフィックやシステムトラフィックについても考慮する必要があります。この場合、レプリケーショントラフィック、障害からの復旧に必要なキャッチアップ、そしてSlow Consumingアプリケーションからの復旧に必要なバッファが該当します。
Amazon MSKの進化:Express brokersとその利点
これらの考慮事項を踏まえた上で、インスタンスとボリュームの仕様について検討する必要があります。X largeインスタンスを選択するのか、2X largeインスタンスを選択するのか。これらすべての入力と仕様を考慮してクラスター仕様を決定します。複雑そうに聞こえますよね?ご安心ください。一緒にステップバイステップで見ていきましょう。 最初のステップは、EC2インスタンスを確認し、クォータ、CPUとRAMの要件のベンチマークを調べることです。Kafkaは基本的にスループットベースのシステムですが、CPUバウンドやメモリバウンドになるケースもあり、それらも考慮する必要があります。次に、平均スループットではなく、ピークスループットを確認します。これは、1日や1週間で発生する可能性のあるピークトラフィックに対応できる十分な容量を確保するためです。
そして、必要なメモリとCPUの量を計算し、ストレージの検討に移ります。 必要なEBSスループット、EBSストレージ容量、ネットワークスループットについて考えます。これらの値をインスタンスのクォータで割ることで、クラスター構成に到達します。これで最初の部分は完了です - クラスターが稼働しました。次の段階は、これを高可用性で運用することです。
まず最初に、適切なKafkaの設定が行われていることを確認する必要があります。 その中でも重要な3つについて説明しましょう。1つ目はレプリケーション係数です - Kafkaはリーダー・フォロワーベースのシステムなので、レプリケーション係数はリーダーパーティションに対するフォロワーの数を決定します。ベストプラクティスは、常に3つの異なるAvailability Zoneで RF(Replication Factor)を3に設定することです。先ほどの例でご覧いただいたように、これにより高可用性と高い耐久性を持つシステムを実現する最良の機会が得られます。次に注意すべきは耐久性の設定です。まず、minimum in-sync replicasがあります。これは、同期状態を維持したい最小レプリカ数を指定し、データの耐久性の問題に対する耐性を高めます。最後に、よく見落とされがちな設定として、unclean leader electionがあります。これはfalseに設定する必要があり、遅れているフォロワーが障害時にリーダーにならないようにします。
これらは3つのシンプルな設定ですが、これですべてというわけではありません。Kafkaには、ネットワーク、パフォーマンス、ストレージに関する8つのカテゴリーの設定があり、デフォルト値が常に最適というわけではありません。良い例としてIOスレッド数があります - 大きなインスタンスを使用してより多くのスループットを実現したい場合は、IOスレッド数を増やす必要があります。同時に、ネットワークスレッド数も増やす必要があります。そうしないと、特定のシナリオで飽和状態になってしまいます。また、非常に高い値を使用する際は注意が必要です。例を挙げて説明しましょう:60台のブローカーを持つある大規模な顧客が、レプリカスレッド数に非常に高い設定値を使用していました。レプリカスレッド数を増やすことで、障害からの迅速なキャッチアップと回復が可能になりますが、KafkaにはフォアグラウンドIOとバックグラウンドIOの適切な分離がありません。設定値が高すぎると、キャッチアップが優先されるため非常に早くキャッチアップできますが、その結果、プロデュースとコンシューム操作のためのリソースが不足してしまいます。
この高い設定値のために、顧客はクラスターの可用性よりもブローカーの可用性を優先することになり、キャッチアップ中に高い書き込みレイテンシーと読み取りレイテンシーが発生し、それが数時間続きました。これに対処する最善の方法の1つは、設定をテストして検証し、開発者が起こす可能性のある偶発的なミスから保護することです。私たちの多くは、レプリケーション係数が1のトピックを扱った経験があると思いますが、これは影響を十分に理解していない開発者がトピックを作成することで発生する可能性があります。効率的で高可用性のシステムを運用するための2つ目のポイントは、適切なメトリクスを持つことです。ここでいくつか例を挙げたいと思います。Kafkaでディスクフルによって呼び出されたことがある人はどのくらいいますか?かなりの数の方がいらっしゃいますね。そうですね、Kafkaはディスクが満杯になることを好みません - Kafkaでディスクが満杯になると。
Brokerは通常、クリーンではないシャットダウン状態になり、手動でのリカバリーが必要になります。ストレージの追加はリアルタイムで素早く行うことができないため、事前の計画が重要です。適切なモニタリングを行って使用率を追跡し、将来の成長に備えて十分な余裕を確保する必要があります。使用率が60%や80%に達した場合は、Kafkaの障害からの復旧に時間がかかるユースケースもあるため、事前にストレージを追加しておくべきです。
もう1つの課題となるパターンは、顧客がボリュームのスループットを使い果たす場合です。これは直接的には現れません。典型的な障害パターンは、ボリュームのスループットの問題から始まり、多数のリクエストがキューに入ります。その結果、CPU使用率が高くなり、不健全なBrokerによって他のBrokerからのリーダーパーティションの確認応答に時間がかかるようになります。クラスターは不安定になり、スループットが限界に達しているため、復旧にも時間がかかります。唯一の解決策は、そのクラスターを通過するトラフィックを減らすことです。これは、事前のモニタリングとアラートの欠如がクラスター全体の不安定性を引き起こす例といえます。
顧客が多くの時間を費やす3つ目の主要な側面はスケーリングです。変更は避けられないものだからです。高可用性を備えたクラスターをプロビジョニングして運用した後、変更が発生します。新しいワークロードのオンボーディング、ビジネスの成長に対応するためのスループット増加、セキュリティポスチャーの改善、あるいはBroker数を減らしてコストを最適化するなどです。これらの変更には通常、複雑なローリングリスタートが必要になります。
この例を使って、クラスターの垂直スケーリングのプロセスを見てみましょう。2XLインスタンスから4XLインスタンスに移行する場合です。まず、新しいインスタンスを起動し、同じバージョンのApache Kafkaをインストールします。次に、適切な設定を行い、正しいセキュリティ証明書をインストールし、Kafkaプロセスを開始して、クラスターへの参加を監視します。スライドには示されていない重要な点として、リスタートの順序があります。コントロールノードは必ず最後にリスタートする必要があります。そうしないと、コントローラーが頻繁に移動し、クラスターの不安定性、コンシューマーのタイムアウト、書き込みレイテンシーの増加を引き起こします。
Apache Kafkaで容量を追加するもう1つの方法は、より多くのBrokerを追加することです。これにはパーティションの再バランシングが必要で、Broker間でデータを移動することになります。スライドが示すように、このプロセスには何時間もかかる可能性があり、適切に実行しないとアプリケーションに影響を与える可能性があります。Kafkaにはリソースの分離が十分でないため、再バランシングには十分な帯域幅が必要です。Brokerに過負荷をかけないよう、同時に移動するパーティションを20以下に制限するなど、慎重に再バランシングを調整する必要があります。クラスターの状況は変化する可能性があり、計画の調整が必要になる場合があるため、この作業の継続的なモニタリングが重要です。Cruise Controlのようなツールは、アプリケーションに影響を与えることなく再バランシングを計画・実行するのに役立ちます。このプロセスは早めに開始することが重要です。
6年前、私たちはこれらの課題に対処し、Kafkaアプリケーションを実行するお客様にとって非常に使いやすいものにするためにAmazon MSKを立ち上げました。それ以来、私たちの最大のミッションは、AWSでKafkaを実行するお客様にとってさらに良いものにする方法を見つけることでした。EBSやS3のようなストレージシステムを運用してきた経験から、それらのシステムから得た弾力性とレジリエンシーの機能をAWS上のKafkaにも取り入れることができました。
より具体的には、お客様のストレージ管理をどのように簡素化できるか、Kafkaのリソースカップリングをどのように簡素化できるか、そしてお客様が数分で容量をスケールアップできるように、コンピュートの弾力性をどのように改善できるか、という課題に取り組みました。これらのベストプラクティスをどのようにして製品に組み込むことができるか。これらすべての改善を具現化したのが、高性能と高い弾力性を備えたAWS上のKafkaを再構築したAmazon MSKのExpress Brokerです。この新しいブローカータイプは3週間前に一般提供を開始し、現在お客様にご利用いただけるようになっています。
Express Brokerの最も重要な特徴の1つは、ストレージ管理が不要になったことです。AWSがこの責任を担うため、Express Brokerではストレージ容量のプロビジョニングやサイジングを心配する必要がありません。ブローカーごとに無制限のストレージ容量が提供されます。2つ目の重要な要素は、ストレージ設定の管理を気にする必要がないことです。AWSがセグメントサイズやレプリカ機能を管理します。さらに、保持しているデータ量に応じて料金を支払うだけです。保持期間を選択し、プロビジョニングされた容量や3つのアベイラビリティーゾーンの3つのコピーではなく、保持しているデータ量に対してのみ支払います。これにより、お客様はStandard Apache Kafkaと比較して、ストレージコストを最大80%削減できます。
Express Brokerでは、プロビジョニングが大幅に簡素化されました。複雑な計算は必要ありません。各インスタンスサイズで達成できる書き込みスループットと読み取りスループットが明確に示されています。45メガバイト/秒のクラスターが必要な場合は、3つのLargeブローカーをプロビジョニングするだけです。より多くの容量が必要な場合は、4つのExtra Largeブローカーを選択します。Express Brokerではサイジングが劇的に簡単になり、ブローカーあたりのスループットも最大3倍向上しています。
Standard Apache Kafkaブローカーと比較する方法として、持続的なスループットを見てみましょう。この例では、M7gブローカーを使用しており、持続的なスループットは、先ほど説明したすべてのバッファを考慮した後、アプリケーションが利用できる量を表しています。これに対して、Express Brokerでは、各ブローカータイプがStandardブローカーよりも多くのスループットを提供します。2XLインスタンスでは約25%増、4XLでは約33%増、16XLでは3倍以上になります。お客様からは、これは画期的な変更だと評価されています。なぜなら、より少ないブローカーで大規模なクラスターを運用できるようになったからです。例えば、3ギガバイト/秒のクラスターを実行するのに、Standardブローカーでは20のブローカーが必要でしたが、Express Brokerでは6つのブローカーで済むようになりました。
プロビジョニングが完了し、ベストプラクティスをすべて実装したら、次はスケーリングの段階です。Express brokerには2つのオプションがあります:垂直スケーリングと水平スケーリングです。垂直スケーリングでは、インスタンスタイプをXLから4XLに変更するなど、ワンクリックで変更が可能です。コンソールで変更を行うと、Amazon MSKがアプリケーションや耐久性に影響を与えることなく、基盤となる調整を処理します。必要に応じて安全にロールバックできるよう、ガードレールも用意されています。
Express brokerは、Standard brokerの20倍という画期的な弾力性も実現しています。Apache Kafkaでは、一般的な再バランシング作業に何時間もかかることがあります。まるで月曜の朝の高速道路のような状態で、綿密な計画が必要で、大きな混乱が生じる可能性があります。それに比べて、Express brokerでは再バランシングは数分で完了します。1秒あたり300メガバイトを処理する適切なサイズのクラスターで、6台のbrokerを使用した場合、3,000パーティションの移動にかかる時間は、Standard brokerでは数時間かかるところを、Express brokerでは5分以内で完了します。これにより、ピークイベントに備えて数分でスケールアップし、brokerの追加や削除が可能になります。
ピークイベントに備える必要がある場合、アプリケーションに影響を与えることなく、自信を持ってbrokerを追加できます。Express brokerでは、これまで必要だった計画や調整作業が不要になりました。
Express brokerは、3つの重要な理由により、ミッションクリティカルなアプリケーションを実行できるよう設計されています。第一に、すべてのベストプラクティスが製品にコード化されているため、開発者が誤った複製設定やミラー設定でトピックを構成する心配がありません。第二に、Express brokerにはリソースの分離機能があり、アプリケーショントラフィックとシステムトラフィックが互いに競合することはありません。brokerを通じて特定の量のスループットを確実に実現できることが保証されています。第三に、インフラストラクチャの障害が発生した場合、Express brokerはStandard brokerと比べて90%速く回復します。Express brokerでボリュームが失われた場合、回復には約5分しかかかりませんが、Standardの場合は数時間かかる可能性があります。これにより平均復旧時間が短縮され、大きなオーバーヘッドなしでクリティカルなアプリケーションを実行できます。
Express brokerでは、妥協を強いられることがないよう配慮しました。100% Kafkaであり、すべてのKafkaアプリケーションがExpress brokerで動作します。標準のApache Kafkaと同じ低レイテンシーを実現しており、お客様にそのようなトレードオフを強いることはありません。MSK Connect、Schema Registry、MSK Replicator、さらにmTLSやSCRAMなどの機能を含む、すべてのAmazon MSK機能をサポートしているため、インフラストラクチャの変更なしでアプリケーションを移行できます。非常に大規模な運用にも対応できるよう設計されており、どのような規模でも最高の価格性能比を実現します。
Amazon MSKでは、Express brokersの導入により、3つの選択肢が用意されています。Standard brokers、Express brokers、そしてMSK Serverlessです。どれを選ぶべきかと聞かれた時、私はこのように説明します:Standard brokersは、まるで手動車のようなもので、制御と柔軟性を求める人向けです。Kafkaに関する深い専門知識を持ち、最高のコストパフォーマンスを求め、AWSにKafkaインフラの管理を任せながらも、Kafkaの運用は自分たちで行いたいユーザーに適しています。
一方、MSK Serverlessは、ワンクリックでKafkaを実現できるように設計されています。クラスターを作成すれば、それだけで完了です。もし、その中間的な存在で、伸縮性があり、スケールアップとスケールダウンの機能、自動化、そして優れたコストパフォーマンスを持ち、どんな規模でもKafkaを運用できる能力が必要な場合、それがExpress brokersを選ぶタイミングです。特別な理由がない限り、私たちはすべてのKafkaワークロードにExpress brokersを使用することをお勧めしています。そのコストパフォーマンス、伸縮性、そして耐障害性の利点を考えると、AWSでKafkaワークロードを実行するのに最適な選択肢だと考えています。
単一のクラスター以上の耐障害性が必要な場合はどうでしょうか?災害復旧などのユースケースには、MSK Replicatorをご用意しています。MSK Replicatorは、Kafkaクラスターに追加の耐障害性を持たせるためのワンクリックソリューションです。特別なアプリケーションの計画や管理は必要ありません。クラスターでReplicatorを有効にするだけで、クラスター間のデータレプリケーションを自動的に処理します。
Aliにバトンタッチする前に、もう一つ紹介したい機能がMulti-VPC connectivityです。この機能は、異なるAWSアカウントで実行されている様々なアプリケーションを、中央のAmazon MSKクラスターに簡単に接続したい場合に役立ちます。この機能により、ワンクリックで接続が可能になります。MSKについてまとめると、私たちの目標は、最も重要なKafkaアプリケーションをAWS上で簡単に、コスト効率よく、そして極めて信頼性高く実行できるようにすることです。
Apache Flinkの構造と運用:開発者エクスペリエンスから高可用性まで
もう一つの双子、Apache Flinkについて話しましょう。まずはApache Flinkの開発者エクスペリエンスから始めましょう。Apache Flinkは、開発者がApache Flinkプログラムを構築するための複数のAPIを提供しています。最上位にあるのがFlink SQLで、これがApache Flinkアプリケーションを始めるのに最も簡単な方法です。開発者は従来のデータ操作と同じような感覚で、ストリーミングデータを実験したり操作したりすることができます。
プログラミングの知識がないデータアナリストでも、Apache Flinkをすぐに使い始めることができるようになっています。ストリーミングデータを扱う際、開発者は従来のデータベースと同じような感覚でデータを操作できます。また、開発者がより柔軟性を求める場合、他のAPIが重要になってきます。Table APIはより柔軟で、Python、Scala、Javaなどのプログラミング言語のプリミティブにアクセスできます。SQLと同じような抽象化と表現力を保ちながら、より多くのことができるようになります。実運用環境での複雑なアプリケーションにおいて、顧客が最も多く使用しているのはDataStream APIです。これは、リアルタイム処理、ウィンドウ処理、複雑な集計などをAPIを通じて最も柔軟にコントロールできるためです。
開発者が独自のオペレーターを作成したい場合もあり、そのためにProcess Function APIを使用します。ここでApache Flinkの開発はより複雑になりますが、Flinkのステートとタイマーにアクセスできることで最高の柔軟性が得られます。これを説明するのは、より大規模にApache Flinkを管理するプラットフォームを構築する計画がある場合に重要だからです。これらすべてのAPIをサポートするプラットフォームを構築することが重要です。そうしないと、開発者を単一のAPIに制限してしまい、すべての規模のワークロードや、ワークロード全体の複雑さに最適に対応できなくなってしまいます。
次に、Apache Flinkの構造について理解する必要があります。Apache Flinkには2種類のプロセスがあります。データストリーム内のイベントに対して計算を実行するTask Managerと呼ばれるプロセスと、Task Managerのオーケストレーションを担当するJob Managerと呼ばれる別のタイプのプロセスです。Flinkは複数のデプロイメントモードを提供していますが、Application Modeが最も推奨される方法です。これは、異なるジョブ間で分離と専用化が実現できるためです。各ジョブごとに専用のJob Managerと専用のクラスターが得られ、ハードウェアやその他の問題による障害から、そのジョブを分離することができます。
Apache Flinkクラスターをデプロイすると、1つのJob Managerと複数のTask Managerが得られます。デプロイメント後のJob Managerの役割は、Task Managerが提供するスロットにタスクをスケジューリングすることです。タスクスロットとタスク自体、そしてそれらの並列性との関連については、後ほど詳しく説明します。 この時点で理解しておく必要があるのは、Task Managerにストレージが必要だということです。なぜなら、Apache Flinkは分散型のステートフルなシステムであり、前回の操作結果を記憶し、処理を進めながら新しいイベントに反映させるためにデータを保存するストレージが必要だからです。
しかし、何か問題が発生した場合はどうなるでしょうか?Task Managerプロセスがクラッシュしたり、ハードウェア障害でTask Managerが失敗したりした場合はどうなるでしょうか?私たちには別のバックアップストレージ、つまりコスト効率が高く、高い耐久性と可用性を備えたストレージが必要です。これにより、ノードやハードウェアを失ったり、プロセスがクラッシュしたりしても、すべてのデータを失うことはありません。Apache Flinkは定期的なチェックポインティングと呼ばれるメカニズムを提供しており、ローカルストレージのスナップショットを耐久性のあるストレージに送信します。ジョブが失敗してTask Managerが再起動した場合、前回のスナップショットを取得して前回のチェックポイントから再開できます。Apache Flinkはまた、オペレーターが手動でこのステートのバックアップを取得するためのAPIを提供しており、そのバックアップを耐久性のあるストレージに保存することができます。
これらすべては、私たちの計画においてどのような意味を持つのでしょうか?まず、Apache Flinkクラスターのためのキャパシティプロバイダーが必要です。最も一般的な2つのオプションがあります:KubernetesとYARNです。
KubernetesとYARNは、Apache Flinkジョブを実行するApache Flinkクラスターをデプロイするために、コンピューティング、ローカルストレージ、メモリを提供するリソースプロバイダーです。先ほど申し上げたように、Apache Flinkジョブをデプロイする方法は他にもあります。セッションモードとも呼ばれる単一のApache Flinkクラスターを用意し、その上で複数のジョブを実行することができます。すべてのジョブに対して単一のJob Managerが割り当てられ、リソース使用の面でジョブ間の分離がありません。本番環境には適していませんが、開発環境やテスト環境でリソースコストを抑えたい場合には良い選択肢かもしれません。
Flinkジョブをアプリケーションモードでクラスターにデプロイする際は、Amazon S3のような高い耐久性と可用性を備えたストレージを用意する必要があります。そして、定期的なチェックポイントを有効にし、チェックポイントの設定を行う必要があります。例えば、チェックポイントの間隔は、どのくらいの頻度でチェックポイントを取るかを決定し、これは障害発生時にどれだけ早く復旧できるか、またどれだけのデータを再処理する準備があるかにも関係します。手動での定期的なセーブポイントの取得も必要です。新しいジョブをデプロイして、そのジョブを前のジョブの状態から再開させたい場合には、バックアップとしてのセーブポイントを提供する必要があるためです。
これらすべてを設定した後は、低コストストレージに対して保持ポリシーを設定する必要があります。Amazon S3は非常にコスト効率の良いストレージですが、数千のジョブがあり、各ジョブが30秒や60秒ごとに頻繁にチェックポイントを取得し、さらにバックアップも取る場合、コストを抑えるために適切な保持ポリシーを設定する必要があります。そして、モニタリングが必要です。モニタリングは、次にお話しするスケーリングにとって非常に重要です。モニタリングからの入力を使用して、自動スケーリング機能を構築することができます。ジョブの遅延が予想以上に長くなっている場合や、CPUの消費が予想以上に多い場合、それがジョブをスケールアップする必要がある時です。スケーリングについては次にお話しします。
Apache Flinkのスケーリングと高可用性:課題と解決策
Apache Flinkクラスターを運用されている方々の中で、Apache Flinkジョブのスケーリングに苦労されている方はどれくらいいらっしゃいますか?これは、このスライドで示している複雑さが原因です。Parallelismがなぜ重要なのかを少し簡単に説明させていただきます。開発者がFlinkアプリケーションを構築する際、それは連鎖的につながったタスクの形を取り、各タスクは並列に実行されるタスクインスタンスに分割されます。並列に実行されるタスクインスタンスの数がParallelismと呼ばれます。4つのタスクインスタンスが同時に実行される場合、そのParallelism数は4となります。
各Taskインスタンスはイベントのサブセットを処理することになります。これは、データストリーミングにはPartitionやShardの概念があり、データが個別に保存されているためです。つまり、これらのTaskはすべてのメッセージではなく、メッセージのグループを処理することになります。より多くのデータを処理したい場合、論理的な判断としては並列度を上げることになります。例えば、4つのTaskインスタンスの代わりに8つのTaskインスタンスを使えば、より高速に処理できるようになります。スループットが増えれば、並列度を上げる必要があります。しかし、本当にそれだけで済むのでしょうか?その理由についてお話ししていきましょう。
並列度を上げる方法を理解する前に、それがFlinkクラスターにどのような影響を与えるのかを理解する必要があります。並列度に合わせてFlinkクラスターをどのように再設定すべきかを理解しなければなりません。先ほど述べたように、各Task Managerはタスクの処理を担当し、ジョブに設定した構成に応じて特定のTask Slotを提供します。利用可能なTaskの数によって、Taskインスタンスの処理に必要な計算能力、メモリ、ディスク、その他すべてのリソースの容量が決まります。一方では、Amazonの様々な種類やサイズのコンピュートノードのようなハードウェアインスタンスがあり、もう一方では並列度があります。ここでは実際のベンチマークデータが必要で、これを考慮に入れる必要があります。
このテスト時のベンチマークデータは、必要な並列度に合わせてスケールアップするために、クラスター内の各インスタンスタイプとインスタンスサイズにどれだけのTask Slotを配置すべきかを把握するために重要です。まとめると、ジョブを監視し、スケーリング操作が必要かどうかを検出する必要があります。そして、例えば2倍などの新しい並列度を決定し、先ほど説明した設定を使用して、必要なノードの数とタイプを把握し、新しいクラスターを作成します。前のジョブのSavepointを取得し、ジョブを停止し、新しいクラスターに新しいジョブをデプロイし、前のジョブのSavepointを使用してジョブを再起動します。これがベストプラクティスに従ったスケーリング操作となります。
では、高可用性での運用について、高可用性の観点からどのように見えるかについて説明しましょう。Task Managerについて説明しましたが、これらは並列に実行され、いずれかが失敗した場合は再起動して前のCheckpointから開始できます。つまり、Task Managerを通じて冗長性による高可用性を得られます。では、Job Managerについてはどうでしょうか?Application Modeでデプロイしているため、Job Managerが失敗しても1つのジョブだけが失敗するという分離性は得られます。しかし、それでも失敗は避けたいものです。Job Managerは単一のプロセスであり、基本的に単一障害点となってしまいます。
このケースでは、Flinkは高可用性メカニズムを提供しています。まず、複数のJob Managerが必要ですが、同時にアクティブにはできません。任意の時点で1つのJob Managerのみがアクティブ(リーダーとして知られる)になれます。クラッシュした場合、別のJob Managerに引き継いでもらいたいわけです。しかし、プール内のどのJob Managerを次のリーダーとするかを判断し投票するのは誰でしょうか?投票システムが必要で、FlinkはこのZooKeeperクラスターまたはKubernetesクラスターを使用して投票を行うサービスを提供しています。このプロセスを通じて、次のJob Managerがリーダーとなり、他のJob Managerは回復してプールに戻ります。
Amazon Managed Service for Apache Flinkの特徴と利点
Apache Kafkaを利用しているお客様から、「AWSはなぜこれらの運用作業を簡素化するサービスを構築しないのか」という声が寄せられていました。お客様は差別化につながる業務に注力したいと考えており、より多くのストリーミングアプリケーションの構築や最新化に焦点を当てたいと望んでいます。組織内でApache Flinkジョブの計画やスケーリングのために必要な、自動化の構築やベンチマーク、テストといった差別化につながらない作業は避けたいと考えています。そこでAWSは、以前Amazon Kinesis Data Analyticsとして知られていたサービスを構築しました。これは、FlinkアプリケーションをAWS上のサーバーレスインフラストラクチャで実行するサービスでした。このサービスは昨年、Amazon Managed Service for Apache Flinkとして新たなブランド名に変更されました。
Amazon Managed Service for Apache Flinkを使用すると、Flinkジョブの展開を非常に迅速に開始でき、完全マネージド型でサーバーレス、さらに従量課金制という最高の特徴を備えています。ジョブの実行時間(分単位)に対してのみ料金が発生します。開発環境やテスト環境でジョブを停止すれば、料金の発生も停止します。また、スケーリング、計画、プロビジョニング、セキュリティパッチ、その他のパッチやアップグレードといった差別化につながらない作業から解放されます。
Amazon Managed Service for Apache Flinkでの計画プロセスは次のようになります。開発者は好みのIDEを使用してFlinkアプリケーションを構築し、 ローカルモードでアプリケーションをテストし、その後アプリケーションを正式なJARファイル(Pythonの場合はZIPファイル)にパッケージ化して、AWSアカウント内のAmazon S3バケットに配置します。次に、 SREチームメンバーまたは開発者が、Amazon Managed Service for Apache Flinkにアプリケーションの詳細を提供してアプリケーション作成のためのAPI呼び出しを行います。そして、 提供したJARファイルを指定してアプリケーションを開始するための後続のAPI呼び出しを行うと、Amazon Managed Service for Apache Flinkが処理を引き継ぎます。
アプリケーションが開始されると、Amazon Managed Service for Apache Flinkがプロビジョニング、計画、インフラストラクチャの提供を担当し、定義された並列処理に応じてタスク数を決定します。AWSでそのジョブを実行し、Amazon Kinesis Data Streamsなどのサービスとの統合を提供します。また、オープンソースのソースやシンクコネクタを提供して、データの取り込み、処理、AWSの様々な送信先への配信を行うことができます。さらに、サービスを通じて設定管理が提供され、設定のバージョニングとバージョン管理が可能です。
Apache Flinkでのスケーリングがどのように行われるか見てみましょう。 「並列度を4から12に増やしたい」と言うだけで、サービスが魔法のようにスケールできたら素晴らしいと思いませんか?これこそがAmazon Managed Service for Apache Flinkで実現できることです。並列度を指定すると、デフォルトでサービスは指定された並列度に応じて、KPU(Kinesis Processing Unit)と呼ばれるものを割り当てます。KPUは1つのCPU、4ギガバイトのメモリ、50ギガバイトのブロックストレージを提供します。
I/Oの負荷が高いジョブを実行するお客様で、同じジョブに対してより少ないKPUを使用しながら、I/Oワークロードに対して同じ並列性を確保したい場合は、KPUあたりの並列性を高めることをお勧めします。つまり、1つのKPUにより多くのスレッドを詰め込むということです。 先ほど、ハードウェア障害が発生した際にジョブを停止して新しいクラスターをデプロイする必要があり、それには最大15分かかる可能性があるとお話ししましたが、新規開発のデプロイメントの場合、このプロセスを手動で行うと最大25分もかかる可能性があります。しかし、Amazon Managed Service for Apache Flinkでは、バックグラウンドでWarmプーリングなどの仕組みが働いているため、オペレーターの実際の作業時間はほとんどの場合5分程度で済み、ストリーミングジョブのダウンタイムを大幅に削減できます。
設定管理に関しても追加の機能が提供されています。Apache Flinkを新しいバージョンにアップグレードする場合、通常は新しいFlinkバージョンでクラスターを構築し、アプリケーションを新しいFlinkでビルドして再度デプロイし、テストする必要があります。もし問題が発生した場合は、ロールバックも必要です。Amazon Managed Service for Apache Flinkでは、Apache Flinkバージョンのインプレースアップグレードが標準で自動化されています。また、新しい設定が原因でジョブが失敗して再起動できない場合は、自動的にロールバックが実行されます。さらに、互換性チェックを行い、新バージョンが以前のジョブのスナップショットと互換性がない場合は、変更を拒否します。以前の低いバージョンのFlinkのSavepointを使用して、新しいFlinkバージョンで新しいジョブを開始することも可能です。
結論として、最大規模でストリーミングワークロードを運用・実行するプラットフォームを構築する場合、スケールや並列性だけが重要なわけではありません。これらすべてのワークロードを同時にかつコスト効率よく大規模に管理できる必要があります。Active-ActiveまたはActive-Passiveのマルチリージョンアーキテクチャを通じて、すべてのジョブが自動的に復旧できる回復力を備えることが重要です。手動での運用はセキュリティとコンプライアンスにリスクをもたらす可能性があるため、エンタープライズグレードのセキュリティと接続性について考える必要があります。また、Flinkだけでなく、データの取り込みから配信まで(通常は同じAWSアカウントやAWS VPCではない)のエンドツーエンドの視点で考える必要があります。
以上で終わりですが、さらに詳しく読むためのリソースをご紹介します。ぜひ学び、好奇心を持ち続けてください - このQRコードをスキャンするか写真を撮って、ここで説明したベストプラクティスについてさらに学んでください。最後にお願いがあります - アンケートにぜひご協力ください。私たちは今後のセッションを改善するために皆様のご意見を本当に大切にしています。皆様とのつながりを楽しみにしています。ご清聴ありがとうございました。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion