Amazon Web Services ブログ

マルチテナント SaaS 環境におけるデータ取り込みのための AWS サービスの利用

AWS SaaS Factory シニアパートナーソリューションアーキテクト Peter Yang 氏、AWS SaaS Factory プリンシパルパートナーソリューションアーキテクト Ranjith Raman 氏による投稿

Amazon Web Services (AWS) のサービスを使用してデータ取り込みアーキテクチャを設計および実装する方法はいくつかあります。 マルチテナントの Software as a Service (SaaS) 構成でデータを取り込む場合、ソリューションに組み込むべき追加の考慮事項、課題、トレードオフがあります。

SaaS の場合、テナントの詳細を取得し、取り込みプロセス全体で伝達されるようにする必要があります。これは、テナントのペルソナに基づいてデータを分離し、ワークロードとストレージを分割する方法に直接影響します。

マルチテナントデータ取り込みプロセスを実装する際に使用できる戦略は複数あります。専用 (サイロ型) メカニズムを使用するものと、共有 (プール型) 取り込みモデルを使用するものがあります。どちらも完全に有効で、両方を混在させることができますが、この投稿では、プール型モデルでのデータ取り込みの実装の細部に焦点を当て、テナントが取り込みリソースを共有する際に考慮すべきさまざまな点を取り上げます。

この投稿には、コードの実際に動作するサンプルソリューションが付属しています。このソリューションをデプロイするための手順は、GitHub から参照できます。

マルチテナントデータ取り込みの設計上の考慮事項

ソリューションの技術アーキテクチャについて詳しく見ていく前に、マルチテナントデータ取り込みプロセスを設計する際の主な考慮事項を見ていきましょう。以下は、このようなソリューションを構築する際に SaaS プロバイダーが検討する一般的な要素のリストです:

  • スケーリングとパフォーマンス: 大量のリクエストを処理し、シームレスに数千のテナントにスケールできる能力
  • セキュリティと隔離: テナントのイベントが認証されていることを保証するためのコントロールを実装し、そのコントロールを使用したデータのパーティショニングと隔離の判断
  • リソース管理: 突発的で予測が困難なトラフィックを処理するシームレスな容量管理
  • 運用効率: 運用と管理のオーバーヘッドを削減

ソリューションアーキテクチャ

この投稿では、データ (EC サイトや POS アプリケーションなどを想定) を収集および集計し、このデータをテナント / 顧客固有の属性で処理 (エンリッチおよび変換) してバックエンドデータストアに格納するサンプルソリューションをもとに説明を行います。

これらのアプリケーションは通常、「注文の合計」や「購入された商品のカテゴリー」などのクリックストリームデータやイベントを追跡し、データからトレンドを特定したり、重要な洞察を導き出すことを目的としています。
任意の瞬間にアクティブなユーザー数によっては、1 秒間に生成されるデータは大量になる可能性があります。

そのようなビジネスやユースケースをサポートするには、非常にスケーラブルでパフォーマンスが高く、イベントを非常に低いレイテンシーで処理できるアーキテクチャが必要です。 次の図は、ソリューションのアーキテクチャを示しています。

multi-tenant-data-ingestion-1

図 1 – ハイレベルアーキテクチャ

リクエストフロー

このアーキテクチャの詳細に入る前に、サンプルソリューションで採用されているハイレベルな要素を見て見ましょう。

以下が、このソリューションの一部であるいくつかのステップです:

  1. このソリューションのフローは、図 1 の左側から開始します。テナントは、Amazon API Gateway が提供する REST API を使用して、SaaS 環境にメッセージやイベントを送信します。これは、ストリーミングイベントのエントリポイントであり、各テナントからのイベントの認証を担当します。
  2. Amazon API Gateway は、Amazon Cognito を使用してJSON Web Token (JWT) を検証する Lambda オーソライザーを利用します。Lambda オーソライザーは、Amazon Kinesis Data Streams への入力として使用できるように、Amazon API Gateway のコンテキストに tenantId を追加します。
  3. Amazon API Gateway はプロキシとして機能し、Kinesis Data Streams にテナントイベントをプッシュします。Kinesis Data Streams は、あらゆる規模でデータストリームをキャプチャ、処理、保存するのに適した、サーバレスなストリーミングデータサービスです。この例では、Kinesis Data Streams が異なるテナントからのストリーミングデータを収集するデータインジェストストリームになります。
  4. Amazon Kinesis Data Streams はデータを Amazon Managed Service for Apache Flink にプッシュします。このソリューションでは Amazon Kinesis Data Analytics for Apache Flink がデータの処理を行い、tenantId とtimestamp の追加に利用されます。これらの値は Amazon Data Firehose がストレージとして利用される Amazon Simple Storage Service (Amazon S3) のプレフィックスの作成に使用します。
  5. Amazon Kinesis Data Analytics for Apache Flink はテナントイベントを Amazon Data Firehose にプッシュします。Amazon Data Firehose は、リアルタイムのストリーミングデータを直接 S3 に配信し、ストレージとさらなる処理のために使用されます。S3 には、マルチテナントデータを効率的に保存および整理するためのいくつかのメカニズムがあります。 より深い考察は、S3 を使用したマルチテナンシー実装のさまざまな戦略が議論されているこの AWS ブログ投稿をチェックしてください。

これでハイレベルなアーキテクチャを理解したので、ソリューションの各コンポーネントについてより詳しく見ていきましょう。

リクエストの認証と認可

Amazon API Gateway は、このソリューションのフロントドアとして機能し、テナントアプリケーションからのデータストリームをスケーラブルな方法で取り込むための、セキュアなエントリーポイントを提供します。API Gateway を使用することで、テナントコンテキストを抽出し、受信リクエストを認証する Lambda オーソライザー を導入することもできます。
このテナント情報は、テナントが Amazon Cognito によって認証されたときに生成されたエンコード済み JSON Web トークン (JWT) を介して渡されます。このコンテキストは、インジェストされたデータを個々のテナントに関連付けることをこのソリューションが可能にするために不可欠です。
API Gateway によって処理される各リクエストは、JWT からテナントコンテキストを抽出し、リクエストのアクセス範囲を設定する AWS Identity and Access Management (IAM) ポリシーを返す Lambda オーソライザーを呼び出します。
ポリシーとともに、リクエストのコンテキストにテナント ID (tenantId) も導入します。フローの後半で、このコンテキスト値の利用方法を見ていきます。以下のコード例は、コンテキストの一部として tenantId を設定する方法を示しています。

policy = AuthPolicy(principalId, awsAccountId)
policy.restApiId = apiGatewayArnTmp[0]
policy.region = tmp[3]
policy.stage = apiGatewayArnTmp[1]
policy.allowAllMethods()
authResponse = policy.build()
context = {
	'tenantId': tenantId,
}
authResponse['context'] = context
return authResponse

Kinesis Data Streams へのデータのルーティング

リクエストが正常に処理された後に、メッセージが Amazon API Gateway から Amazon Kinesis Data Streams に転送されるように設定します。これは、テナントデータのストリームを収集および処理します。以下の 図 2 は、設定手順を示しています。
ここでは、統合リクエストの統合タイプを AWS サービスに設定しています。つまり、リクエストを AWS サービス (この例では Kinesis Data Streams) に転送しているということです。

multi-tenant-data-ingestion-2

図 2 – Amazon API Gateway の統合リクエスト値

リクエストがストリームに転送される前に、API Gateway で変換を適用して、Kinesis Data Stream が期待している形式にリクエストを変換します。
Amazon API Gateway ではマッピングテンプレートを使用して、メソッドリクエストのペイロードを対応する統合リクエストにマップできます。
ソリューションでは、図 3 に示すように、テンプレートを使用して StreamName、Data、 および PartitionKey の値を設定しています。
Lambda オーソライザー によって設定された コンテキスト の一部として受信した tenantId フィールド を使用して、Kinesis Data Streams で必要な属性である PartitionKey の値を設定しています。
このテンプレートにより、ダウンストリームのサービスに渡されるすべてのリクエストが、そのリクエストを行うテナントとの関連付けがされていることを確認します。

Figure-3-v1

図 3 – Amazon API Gateway マッピングテンプレート

Amazon Managed Service for Apache Flink によるストリーミングデータの処理

前のセクションで説明したように、データストリームに送信するすべてのメッセージには、tenantId というパーティションキーがあります。このパーティションキーの値は、メッセージを処理するシャードに影響を与えます。

各 Kinesis ストリームには1つ以上のシャードがあり、シャード数は Kinesis が処理できるデータ量に直接影響します。
パーティションキーによってはホットシャードを引き起こし、ストリームのパフォーマンスに影響を与える可能性があることに気を付けてください。

データストリームによってメッセージが処理されると、Amazon Managed Service for Apache Flink を使用して、データのさらなる分析を行います。このサービスを使用すると、Java のようなプログラミング言語を使用して、ストリーミングデータを処理および分析できます。

サンプルソリューションでは、データが次のサービスに転送される前に、Flink ジョブを使用してメッセージを追加のフィールドで拡張しています。

図 4 の実装で見られるように、Flink ジョブには inputStreamName があり、これはデータの送信元を示しています。今回の場合は Kinesis Data Stream です。
上述のとおり、Flink ジョブはメッセージを Amazon Data Firehose 配信ストリームにプッシュする前に、tenantId の追加属性とタイムスタンプフィールドも追加します。

Figure-4

図 4 – Amazon Managed Service for Apache Flink – InputStream と FirehoseOutputStream の設定

また、下記の図 5 のコードに示すように、TenantId フィールドはメッセージが Amazon S3 のどのパスに配置されるかを示すために使用され、タイムスタンプは Flink ジョブがメッセージを処理した正確な時刻を反映します。

Figure-5-Data

図 5 – Flink ジョブでのtenantId の設定

Amazon Data Firehose を使用したデータ配信

サンプルソリューションでは、サービスごとのテナント分割モデルを使用してスケールを向上させるために、Amazon Data Firehose を利用してメッセージを S3 に配信しています。これは特に、SaaS システムに多数のテナントがある場合に効果的です。
Flink では、Flink ジョブから直接メッセージを S3 に配信できます。
しかし、データを Amazon Data Firehose に送信することで、このソリューションを将来的に拡張できる柔軟性が得られます。例えば、Amazon RedshiftAmazon OpenSearch Service などのその他の送信先や、その他のモニタリングソリューションをサポートできるようになります。

multi-tenant-data-ingestion-6

図 6 – Amazon Kinesis Data Firehose デリバリーストリーム

図 6 に示すように、配信ストリーム delivery-multi-tenant-firehose-stream は動的パーティショニング機能を利用しています。これにより、データ内のキーを使用して、Data Firehose のストリーミングデータをパーティション分割することができます。

Figure-7-Data-Ingestion

図 7 – tenantId と timestamp を使用した動的パーティショニング

キーは、対応するテナントの S3 プレフィックス位置に配信される前のデータのグループ化に用いられます。図 7 に示すように、動的パーティショニングを実装するために、入力メッセージの一部であったフィールド tenantId と timestamp を使用しました。S3 プレフィックスの一部として tenantId があることで、データの消費時に S3 のテナント分離戦略の一部として使用できる IAM ポリシーを作成できます。

最後に、S3 へのデータ配信のために、Amazon Data Firehose は、配信ストリームのバッファリング設定に基づいて、複数の入力レコードを連結します。
S3 へのデータ配信の頻度は、配信ストリームの S3 バッファサイズとバッファ間隔の値によって決まります。
こちらの詳細は、AWS ドキュメントで確認できます。

結論

この投稿では、AWS のサービスを使用してマルチテナントのデータ取り込みと処理エンジンを構築する方法を探りました。 このデータパイプラインの各コンポーネントと、SaaS のマルチテナントデータ取り込みプロセスの設計アプローチに影響を与える可能性のあるいくつかの主な考慮事項を検討しました。

また、AWS サービスを使用して、マルチテナントのストリーミングデータをどのようにインジェスト、変換、ストレージできるかを確認しました。その際、データの安全な処理を保証するために、パイプラインに構築物が組み込まれていることも確認しました。

ここで紹介したサンプルアプリケーションを掘り下げていくと、AWS 上に完全な実働ソリューションを構築する上でのエンドツーエンドの全体的な体験がよりよく理解できるようになるでしょう。
これにより、SaaS データ取り込みプロセスのニーズと整合性のあるポリシーの周りを形作ることができる一方で、良い出発点を提供するはずです。

このソリューションのより詳細な概要については、環境のすべての動的な要素を理解するのに役立つ段階的なデプロイ手順が記載されている GitHub リポジトリをご覧いただければと思います。

AWS SaaS ファクトリーについて

AWS SaaS Factory は、SaaSの旅路にあるどの段階の組織でも支援します。新しい製品の構築、既存アプリケーションの移行、AWS 上での SaaS ソリューションの最適化など、様々なニーズに対応できます。より多くの技術的、ビジネス的なコンテンツやベストプラクティスを知るには、AWS SaaS Factory Insights Hub をご覧ください。

SaaS ビルダーは、エンゲージメントモデルについて問い合わせたり、AWS SaaS Factory チームと連携するために、アカウント担当者に連絡することをお勧めします。

こちらに登録して、AWS 上の最新の SaaS のニュース、リソース、イベントについて通知を受け取ることができます。

翻訳はソリューションアーキテクトの福本が担当しました。原文はこちらです。

なお、翻訳版では Amazon Kinesis Data Analytics と Amazon Kinesis Data Firehose の名前変更に伴い、それぞれ Amazon Managed Service for Apache Flink、Amazon Data Firehose と表記しています。
https://aws.amazon.com/jp/about-aws/whats-new/2023/08/amazon-managed-service-apache-flink/
https://aws.amazon.com/jp/about-aws/whats-new/2024/02/amazon-data-firehose-formerly-kinesis-data-firehose/