Amazon Web Services ブログ

SaaS 向けリレーショナルデータベースのスケーリング(Part 2: シャーディングとルーティング)

この記事は、software as a service (SaaS) のためのリレーショナルデータベースのスケーリングに関するシリーズの続編です。SaaS プロバイダーは、Amazon Relational Database Service (Amazon RDS) や Amazon Aurora などのリレーショナルデータベースを一般的にソリューションで利用しています。Part 1 では、リレーショナルデータベースアーキテクチャをスケーリングまたは最適化する一般的な方法をいくつか紹介しました。これらの方法は、垂直スケーリングリードレプリカによる水平スケーリングなど、制限のある物理リソースのセットをスケーリングすることに焦点を当てていました。SaaS プロバイダーとしては、これらの限界を超えて成長する必要がある場合があり、そのような場合に データベースシャーディング がスケーリングメカニズムとして有効な選択肢となります。

データベースのシャーディングは複雑さを増し、一度実装すると後戻りできなくなることが多くあります。これは、シャーディングがデータモデルに明示的に組み込まれ、アプリケーションもそれに合わせて変更する必要があるためです。したがって、SaaS 運用に影響を与えるような判断をする前に、データベースをシャーディングすることの意味を理解しておく必要があります。さらに、データベースアーキテクチャが複雑になるにつれ、テナントのリクエストを正しいデータベースにルーティングする課題に直面する可能性があります。

この記事では、データベースのシャーディングと、アプリケーションがテナントのリクエストを正しいデータベースにルーティングする課題への対処方法について説明します。

更なるスケーリング

垂直スケーリングは読み取りと書き込みのパフォーマンスを向上させますが、データベースインスタンスを拡張または最適化できるサイズには上限があります。同様に、リードレプリカを使った水平スケーリングでは読み取り負荷に対してスケールアウトできますが、データベースソリューションでサポートされるリードレプリカの数に制限があります。これらの制限に近づいたり到達したりした場合、アプリケーションを拡大し続けるにはどうすればよいでしょうか。

プールやブリッジモデルでは、一部のテナントがリソースを他のテナントよりも多く消費している場合、サイロストレージにテナントを移行するという選択肢があります。選択されるテナントは通常、パフォーマンス要件が最も高いテナントです。その後、既存のテナントを新しい環境に移行するメカニズムを導入する必要があります。AWS Database Migration Service (AWS DMS) などのツールを使用すると、この移行を自動化できます。また、テナントとストレージを対応付ける必要があり、ソリューションとオペレーションにさらなる複雑さが加わります。

別の選択肢は、データベースのシャーディングを利用することです。これにより、パーティショニングモデルを維持しながら、顧客層の拡大に伴ってデータセットをスケールアップできます。

SaaS ソリューションにおけるデータベースのシャーディング

データベースのシャーディングについては、データベースのシャーディングとは?Amazon Relational Database Service でのシャーディングで詳しく説明されています。この概念に詳しくない場合は、これらの参考資料を確認することをお勧めします。この記事では、SaaS 固有の側面に焦点を当てています。

データベースのシャーディングアーキテクチャを設計する際、シャードキーの選択は重要です。SaaS プロバイダーは、テナントのデータを単一のデータシャードに紐付けできるため、tenant_id をシャードキーとして使用することが多くあります。次の図は、リレーショナルデータベースの Order テーブルを tenant_id をシャードキーとしてシャーディングする例です。

Tenant Sharding Diagram

テナントのすべてのトランザクションを単一のデータシャードに紐付けると、テナントごとのパフォーマンスを改善できます。例えば、テナントのデータベースクエリでは、すべてのデータベースのすべての行を検索する必要がある場合があります。テナントを単一のデータベースに限定すると、検索される行数が減り、パフォーマンスが向上します。また、テナントに対して外部キーと JOIN を使用できるようになります。次の図は、tenant_id をシャードキーとして使用し、複数のデータベーステーブルにわたってシャーディングされている様子を示しています。

Multi Table Sharding Diagram

データシャードは固有のデータベースであるため、単一のデータベース インスタンスまたはクラスターに複数のシャードを持つことができます。シャードのサイズとインスタンスあたりのシャード数は、使用事例によって異なります。たとえば、多数のシャードを管理する運用オーバーヘッドを減らすために、インスタンスごとに 1 つの大きなシャードを選択することができます。あるいは、データベースのサイズが原因で、レプリケーションやバックアップの遅延、vacuuming などのデータベースのメンテナンスタスクの実行に問題が発生している場合は、インスタンスあたり複数の小さなシャードを選択することができます。

シャーディングのメリット

シャーディングを使用すると、単一のデータベースのパフォーマンスを超えてアプリケーションをスケールアウトできます。既存のシャードのサイズ変更や、パフォーマンス問題への対応、または新規テナントのプロビジョニングに応じて、リアルタイムで新しいシャードを追加できるように、SaaS アプリケーションをアーキテクチャ設計できます。単一のテナントが単一のデータベースで提供できるパフォーマンスを超える必要がある場合、シャーディングは 1 つの解決策となります。

大規模なテナントを扱う場合、シャーディングを使ったプールモデルの方が、サイロモデルよりも運用効率が高くなります。データベースの管理数が少なくなり、新しいテナントを追加する際に新しいデータベースをプロビジョニングする必要がないため、テナントのオンボーディングが簡素化されます。

tenant_id をシャードキーとして使用することで、他の運用上の効率化も得られます。テナント分離アプローチと相性が良く、パフォーマンス問題に対処するためにテナントを新しいノードに簡単に再配置できます。これは、すべてのデータを単一のデータシャードに格納するためです。同様に、テナント単位のバックアップと復元では、複数のデータシャードにまたがる整合性を確保する必要がありません。

テナント ID をシャードキーとして使用する場合、シャーディングと他のデータベーススケーリングアプローチを組み合わせると、テナントのパフォーマンスがさらに向上しますが、複雑さが増します。たとえば、テーブルパーティショニングtenant_id に基づいて実装し、個々のテナントのパフォーマンスを対象にしたり、データベースキャッシングを導入してシャードのパフォーマンスを改善したりできます。

シャーディングは、cellular architecture パターンも提供します。これにより、インフラストラクチャの障害からの影響範囲が限定され、単一のテナントが他のパフォーマンスに与える影響が軽減されます。次の図は、各データベースインスタンスに最大 2 つのテナントを含む 3 つのシャードが含まれる (各シャードが個別のデータベース) アーキテクチャを示しています。この図には高可用性は示されていませんが、Aurora または Amazon RDS ではネイティブに実装されています。これらのオプションの詳細については、高可用性と耐久性およびAmazon RDS Multi-AZを参照してください。

Tenant Shuffle Sharding

シャッフルシャーディングを利用すれば、1 つの問題のあるテナントが他に与える影響をさらに軽減できます。ただし、シャードレプリケーションを管理するソリューションを導入する必要があるため、複雑さが増します。

シャーディングの課題

シャーディングは SaaS アプリケーションを非常に複雑にします。アプリケーションはすべてのシャードにわたるデータのマッピングとルーティングを処理する必要があります。ヘルパーサービスを導入することで、この複雑さを開発者から隠すことができます。この概念については、後ほど投稿内で説明します。

複数のシャードからデータを必要とするクエリでは、アプリケーションレベルでの追加エンジニアリングが必要になります。これは通常、単一のシャードを使用するクエリよりも高いレイテンシーを引き起こします。オンライン分析処理 (OLAP) のようなワークロードは、通常、全データセットに対してデータ分析を行うため、シャーディングには適していません。このような場合、両方の機能を持つために、データセットのコピーを OLAP データベースに作成することが一般的な方法です。

シャーディングを導入すると、いくつかの運用上の課題が生じます。データセットの領域が複雑になるため、サポートが難しくなる可能性があります。シャーディングされたデータセットは分散しているため監視が難しくなり、テナントを認識したコンテキスト、ログ記録、メータリングが必要になります。テナントの移行は簡単ではなく、データ保持に関する検討が必要になる可能性があります。

シャーディングされたデータセットは、時間の経過とともに偏りが生じ、データベースのホットスポットを引き起こす可能性があります。シャード間でのパフォーマンスの違いは、顧客のパフォーマンスにばらつきを生む原因となります。データを均等に分散せるためには、長期にわたってデータセット全体でテナントを継続的に再調整する必要があります。そのため、コアアーキテクチャの一部としてテナントを移行する機能が必要です。

シャード化されたアーキテクチャにオブザーバビリティを持たせる事は不可欠です。Amazon RDS Performance InsightsEnhanced MonitoringAmazon DevOps Guru for RDS などのツールを使用すると、データベースのパフォーマンスを可視化し、ソリューションに影響を与える可能性のある問題を特定できます。

最後に、シャード化されたアーキテクチャからシャード化されていないアーキテクチャに戻すことは難しく、相当な技術的専門知識、エンジニアリングリソース、プログラム管理が必要になります。シャード化の決定は一方通行だと考えるべきです。

これらの課題の多くは、Amazon Aurora Limitless Database (現在 Limited Preview 中) によって解決されます。Aurora Limitless Database は、単一インスタンスの制限を超えてスケーリングできる Aurora のサーバーレスデプロイです。アプリケーションレベルのシャーディングを自分で実装する必要はありません。Aurora Limitless Database は単一のインターフェースを提示するため、アプリケーションはシングルデータベースを使用する場合とほぼ同じ方法で使用できます。Aurora Limitless Database では、アプリケーションがテナントのルーティングを処理したり、クラスターのトポロジを認識する必要はありません。Aurora Limitless Database はスキーマとキーレンジの配置を認識しており、クエリを正しいデータアクセスシャードにルーティングし、アプリケーションに返す前に結果を集約します。

シャーディングのタイミングとシャーディングへのアプローチ

シャーディングの主な利点は、単一の物理データベースを超えてスケーリングできることです。現代のデータベースはリソースが増え続けているため、一般的にはその他のスケーリングアプローチが機能しなくなった場合にのみシャーディングを検討します。1 つのユースケースとして、データベースの物理的な限界に達したサイロモデルのテナントで、他の方法でスケーリングできない場合が考えられます。あるいは、データベースエンジンのパフォーマンスが限界に達しても、既存のパーティショニングモデルを維持したい場合もあるでしょう。SaaS アプリケーションのリレーショナルデータベースのパフォーマンスを改善する他の方法については、このシリーズのPart 1 をお読みください。

別のシャーディングのユースケースは、大規模環境での運用効率化です。多くのテナントが存在する場合、サイロモデルでこれらのテナントを管理することは、プールモデルほどのコスト効率性は得られませんが、シャーディングされたプールモデルと同じくらい運用が複雑になる可能性があります。たとえば、16 の データベースシャードにまたがる 400 のテナントを管理する方が、400 の個別のデータベースを管理するよりも簡単かもしれません。

レジリエンシーのためにシャーディングを検討することもできます。データベースアーキテクチャは多くのテナントをサポートできる可能性があります。しかし、データベース障害の影響が事業リスクとして大きすぎる場合があります。シャードの物理的な分離により、データベース障害の影響範囲が小さくなります。また、レプリケーションにより、障害発生時にセカンダリシャードからデータを利用できるようになります。

データセットをシャーディングすることを決めた場合は、どのようにシャーディングするか、何をシャーディングするかを評価する必要があります。データセットを複数のセットに分割し、シャーディングが必要な部分のみをシャーディングすることができるかもしれません。SaaS アプリケーションの機能とテナントの使用パターンを評価し、データセットのどの部分をシャーディングするのが適切かを判断してください。その上で、データセットの一部を分割し、シャーディングしてください。

複雑なデータセットにおけるデータベースリクエストのルーティング

独自のシャーディングソリューションを実装する場合、アプリケーションはデータベースへのリクエストをどこにルーティングするかを知る必要があります。データセットを複数のデータベースシャードやパーティショニングモデル (プレミアム層のサイロモデルと標準層のプールモデルなど) に分散させると、これが難しくなります。

アプリケーションには、テナントデータがどこにあるかを追跡するために、各テナントをデータベースインスタンスにマッピングするインデックスが必要です。新しいテナントをオンボーディングしたり、既存のテナントをシャードやパーティションモデル間で移行する際には、このインデックスを更新する必要があります。また、新しいテナントをどのシャードに配置するかを決定するメカニズムが必要になる可能性があります。

このインデックスの管理とクエリを行うヘルパーサービスとして、データアクセスマネージャーを実装できます。これにより、開発者からデータセットの複雑さを隠蔽し、アプリケーションを変更することなく将来的にデータセットのアーキテクチャを変更できます。リレーショナルデータベースの管理に限定されず、アプリケーション用のすべてのデータセットをインデックス化およびマッピングできます。

次の図は、データアクセスマネージャーのアーキテクチャ例を示しています。

Shard Manager Diagram

この例では:

  1. JSON Web トークン (JWT) が SaaS アプリケーションを通して渡され、テナントコンテキストが含まれています。
  2. JWT をデータアクセスマネージャーに渡し、JWT マネージャーを呼び出します。
  3. JWT マネージャーは JWT を検査し、tenant_id フィールドを返します。
  4. データアクセスマネージャーは、Amazon DynamoDB テーブルに格納されたマッピングを使用して、tenant_id を正しいデータベースインスタンスにマッピングします。
  5. データベースの詳細がアプリケーションに返却されます。
  6. アプリケーションは、正しいデータベースインスタンスに接続します。

マッピングテーブルには DynamoDB を使用しています。これは、マッピングデータを格納するための経済的でスケーラブルなソリューションを提供するためです。このマッピングデータはアプリケーション内のすべてのサービスやマイクロサービスで使用される可能性があるため、パフォーマンスのボトルネックにならないことが重要です。DynamoDB は、クエリごとに単一のアイテムのみが返されるこのようなキーバリュー型のアクセスパターンに適しています。複数のサービスが、バックエンドにある異なるデータベースを使用しながらこのシャーディングモデルを利用する場合は、service_id 属性を追加し、複合プライマリキーを作成することで、この例のアーキテクチャを拡張できます。さらに、このデータはかなり静的であると予想されるため、キャッシング層を導入して DynamoDB への呼び出し回数を減らすこともできます。

Aurora Limitless Database を使用すると、このようなルーティングの複雑さは解消されます。Aurora Limitless Database には、選択したシャードキー (例: tenant_id) に基づいて、クエリを正しいデータアクセスシャードにルーティングするルーターインスタンス群が含まれています。そのため、アプリケーションは、クエリの一部として tenant_id を指定し、単一のシャードグループエンドポイントにアクセスするだけで済みます。Aurora Limitless Database の詳細については、Join the preview of Amazon Aurora Limitless Database をご覧ください。次の図は、Aurora Limitless Database のアーキテクチャを示しています。

Aurora Limitless Database

結論

この投稿では、SaaS アプリケーション内のリレーショナルデータベースをスケーリングする選択肢としてのシャーディングと、データルーティングを処理するためのデータアクセスマネージャーの概念について説明しました。

リレーショナルデータベースをシャーディングすると、SaaS アプリケーションにアーキテクチャ上および運用上の複雑さが生じます。シャーディングされたアーキテクチャを実装することのトレードオフを検討し、それが自分のユースケースに最適なものであることを確認する必要があります。シャーディングが提供するパフォーマンス上の利点は、別のスケーリング戦略でも得られる可能性があります。

複数のスケーリング戦略を組み合わせ、シャーディングを選択することもできます。SaaS 導入における正しい判断は、チームの既存の知識を活かしてソリューションを運用し続けることかもしれません。既存のテクノロジースタックを維持することで、将来的によりスケーラブルなテクノロジーに移行する前に、他の成長分野に注力できます。

シャーディングを実装することにした場合は、アプリケーションのルーティングの複雑さを軽減し、スケーリングとメンテナンス作業を簡素化するために、Aurora Limitless Database などのマネージドなシャーディングソリューションを検討する必要があります。

スケーリング戦略を本番環境に導入する前に、十分にテストすることが重要です。スケーリングアプローチを設計する際は、スケーリングメカニズムのパフォーマンスを可視化し、期待したスケーリング目標に達しているかを検証するための運用メトリクスを実装する必要があります。


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

AWS SaaS Factory は、SaaS ジャーニーのあらゆる段階にある組織を支援します。新製品の構築、既存アプリケーションの移行、または AWS 上での SaaS ソリューションの最適化を検討している場合でも、お手伝いできます。AWS SaaS Factory Insights Hub にアクセスして、さらに多くの技術的およびビジネス的なコンテンツとベストプラクティスを見つけてください。

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


著者について

Dave Robertsaaaaaaaaa Dave Roberts は、シニアソリューションアーキテクトであり、AWS SaaS Factory チームのメンバーです。AWS 上で SaaS 製品を構築する AWS パートナーを支援しています。SaaS について話していないときは、ギターエフェクトペダルを作ったり、家族と森で時間を過ごすことを楽しんでいます。
Josh Hart Josh Hart は、Amazon Web Services のプリンシパルソリューションアーキテクトです。彼は英国の ISV 顧客と協力し、AWS 上で SaaS アプリケーションを構築およびモダナイズするのを支援しています。

翻訳はソリューションアーキテクトの「藤川 貞信」が担当しました。原文はこちらです。