Skip to content

MS_ElasticScaleAndPool

nishi_74322014 edited this page Aug 18, 2026 · 1 revision

Elastic Scale, Elastic Database Pool

概要

RDBMS でのステートフルなデータ処理では難しかった、
拡張性+弾力性をアプリケーションに提供する。

  • スケールアウト(水平分散)が可能
  • アプリケーションをマルチテナント化する。
  • インスタンス横断なトランザクション処理(ACID)
  • その際に、アプリケーションの変更は不要。
    (ただし、Elastic Database Client Library で作成し直す必要がある)

補足(シャーディングという解法): SQL Server パーティション分割
1 インスタンス内でデータを分割するのに対し、
Elastic Scale は複数のデータベース インスタンスに跨って分割する
(= シャーディング)。

パーティション分割 シャーディング(Elastic Scale)
分割の範囲 1 データベース内 複数データベース(シャード)
主目的 保守性・アーカイブ スケールアウト(性能・容量)
上限 インスタンスの性能に律速 インスタンスを増やせる
横断クエリ 通常の SQL Multi-Shard Query が必要

SQL Server のレプリケーション
「RAID1 的(ミラーリング)」に対して
RAID0 的」と表現されるのがシャーディングである。

機能

Elastic Database tools

  • DB シャーディングの構築と管理。
  • 2 種類のツールが存在する。

Elastic Database Client Library

DB シャーディングのクライアント・アプリケーションの開発。

  • Shard Map Management

    • シャードのコレクションを管理する "shard map manager" と呼ばれる
      特殊なデータベースを管理する。
    • "shard map manager" は、スケールアウトされたデータベースを横断して、
      メタデータを管理する。
  • Data Dependent Routing
    1 回の呼び出しでテナントに対応するデータベースと接続する。

  • Multi-Shard Queries
    1 回の呼び出しでシャードに跨ったデータを 1 つの結果セットに集約する。

補足(シャード マップ マネージャは単一障害点): どのシャードに
どのキー範囲が入っているかを保持するメタデータ DB であるため、
ここが落ちると全体が機能しない。
クライアント ライブラリはローカル キャッシュを持つが、
可用性の設計(SQL Server のクラスタリング)は
別途必要になる。

Elastic Database Split-merge tool

  • DB シャーディングのスケールアウト(スケールイン)
  • シャード マップの再構築などを行う。

Pools, Jobs, query

Elastic Database Pool

  • 一定量の DTU (Database Throughput Unit) の管理をする。
  • 大量の Elastic Database Pool の性能・コスト管理を容易にする。
  • ポータル、PowerShell、.NET ライブラリを使用して、
    Elastic Database Pool を管理することができる。

補足(Pool と Scale は別物): 名前が並んでいるため混同しやすいが、
Elastic Pool と Elastic Scale は目的が異なる

Elastic Database Pool Elastic Scale(Database tools)
何をするか 複数 DB でリソース(DTU/vCore)を共有する データを複数 DB に分割する
主目的 コスト最適化 スケールアウト
アプリの変更 不要 クライアント ライブラリが必要

Elastic Pool は、「ピークの時間帯がバラバラな多数の小さな DB」を
束ねて 1 つのリソース枠を共有させる仕組みで、
SaaS のマルチテナントで各テナントに DB を割り当てる構成と相性がよい。
データを分割するわけではない点に注意。

補足(最新化:DTU から vCore へ): DTU(Database Throughput Unit)は
CPU・メモリ・I/O を 1 つの指標にまとめた抽象的な単位だったが、
現在は vCore 購入モデルが主流である(DTU モデルも継続提供)。
vCore モデルでは CPU 世代とメモリを個別に選べ、
ライセンス持ち込み(Azure Hybrid Benefit)も利用できる。

Elastic Database Jobs

Elastic Database Client Library を使用し、

  • Elastic Database Pool と shard set の全データベース横断の
    Transact-SQL (T-SQL) を実行できる。
  • なお、このクエリは、DML だけではなく、DDL、運用・保守タスクも実行できる。
    • スキーマ変更
    • 資格情報管理
    • 参照データの更新
    • パフォーマンス データの収集
    • テナント(顧客)遠隔操作

補足: シャーディング構成で最も面倒なのが
**全シャードへのスキーマ変更(マイグレーション)**である。
Elastic Jobs はこれを一括実行するための仕組みで、
シャード数が増えるほど価値が上がる。

Elastic Database query

Elastic Database Client Library を使用し、

  • Elastic Database Pool と shard set の全データベース横断の
    Transact-SQL (T-SQL) を実行できる。
  • Microsoft とサードパーティ製の BI ツール(Excel, PowerBI, Tableau, etc.)
    から接続し、データベースを跨いだリモート テーブルへのアクセスが可能。

補足: こちらは外部テーブルCREATE EXTERNAL TABLE)として
他 DB のテーブルを見せる仕組みで、
通常の T-SQL / ODBC クライアントから利用できる点が
Multi-Shard Query(専用ライブラリが必要)との違いである。
SQL Server リンクサーバ機能の補足で触れた
PolyBase と同系統の技術と言える。

スケーリング

クラウド規模のデータベース アプリケーションでは、
容量または全体のパフォーマンスを調整するために、
2 つのスケーリング手法を組み合わせて使用する。

水平方向のスケーリング

Elastic Database Pool から、データベースを追加または削除する。

  • 追加:スケール・アウト
  • 削除:スケール・イン

これは、Elastic Database Client Library で管理する。

垂直方向のスケーリング

個々のデータベースのパフォーマンス レベルを増減する。

  • 増:スケールアップ
  • 減:スケールダウン

これには、以下の方法で対応する。

  • Azure PowerShell コマンドレットを使用する。
  • Elastic Database Pool のデータベースのパフォーマンス レベルを変更する。

テナント パターン

  • スケールアウトを目的とする。
  • マルチテナント化を目的とする。

※ SaaS のユーザや企業をテナントと呼ぶ。

シングルテナント パターン

  • 各データベース・インスタンスは
    特定のテナント ID 値 (または顧客キー値) に関連付けられる。

  • テナント ID 値 (または顧客キー値) がデータに存在する必要は無い。

  • 要求をデータベースにルーティングするのはアプリケーションの役目。
    Elastic Database Client Library はこの作業を簡素化できる。

マルチテナント パターン

  • 各データベース・インスタンスは
    複数のテナント ID 値 (または顧客キー値) に関連付けられる。

  • テナント ID 値 (または顧客キー値) がデータに存在する必要がある。

  • アプリケーションは多数の小さなテナントを管理する必要がある。

  • 要求をデータベースにルーティングするのはアプリケーションの役目。
    Elastic Database Client Library はこの作業を簡素化できる。

  • 複数のデータベース間でのデータ再分散(シャード マップの再構築)が必要になる。
    Elastic Database Split-merge tool はこの作業を簡素化できる。

補足(トレードオフ): 2 つのパターンの得失を整理する。

観点 シングルテナント(1 テナント 1 DB) マルチテナント(1 DB に複数テナント)
分離 強い(データ・性能とも完全分離) 弱い(Noisy Neighbor が起きうる)
コスト テナント数に比例。Elastic Pool で緩和 安い
復旧 テナント単位で復元できる 全体を復元することになる
スキーマ変更 全 DB に適用が必要(Elastic Jobs) 1 回で済む
誤って他テナントのデータを見せる事故 構造上起きにくい アプリのバグで起きうる

最後の点への対策が、本ページ後段の
行レベル セキュリティ(Row-Level Security)である。
テナント ID による絞り込みをアプリではなく DB 側で強制
できるため、
マルチテナント パターンでは事実上必須の機能と言える。

パターン変更のシナリオ

評価期間

見込顧客に試用版のソフトウェアを提供する場合、マルチテナント パターンを採用する。

理由:費用対効果を高めることができる。

本稼働

見込顧客との契約が完了した場合、シングルテナント データベースを採用する。

理由:パフォーマンスが向上する。

また、試用版を使用していた場合は、Elastic Database Split-merge tool を使用して、
マルチテナント データベースから新しいシングルテナント データベースにデータを移行する。

追加の調査

https://github.com/OpenTouryoProject/OpenTouryo/issues/144

SQLの実行方法

Data Dependent Routing

  • Connection オブジェクトの取得方法が変わるだけ。
  • SQL の実行自体は、従来の SqlClient を使用する。

Multi-Shard Queries

  • 参照クエリ専用。

    • DataReader のみサポートする。
    • Adapter 系はサポートしない。
  • 従って、Transaction もサポートしない。

補足(この差が設計を決める): 更新は Data Dependent Routing、
参照のうち横断が必要なものだけ Multi-Shard Query、という使い分けになる。
つまり、更新は必ず単一シャードに閉じる設計が前提であり、
シャード キー(テナント ID など)の選定が
アーキテクチャの成否を決める。

TransactionとRetry policy

Transaction (Elastic database transactions)

  • TransactionScopeをサポートする。
  • 複数 Instance を跨いだクエリを実行する場合、TransactionScopeを使用する。
  • Data Dependent Routing のシナリオのみで有効。

Retry policy (SqlDatabaseUtils.SqlRetryPolicy)

Windows Azure AppFabric Customer Advisory チーム (CAT) と
patterns & practices チームが開発したライブラリ。

  • クエリによって成功する可能性の高い処理のリトライを行う。
  • Data Dependent Routing のシナリオのみで有効。

TransactionScopeとRetry policyの関連

  • 双方とも、Data Dependent Routing のシナリオのみで有効。
  • TransactionScopeと Retry policy の範囲は、
    TransactionScope < Retry policy となる。

補足(入れ子の順序が重要): 「TransactionScope < Retry policy」とは、
リトライがトランザクションの外側にある、という意味である。

Retry policy {
    TransactionScope {  ← 失敗したらロールバックし、
        ...                丸ごとやり直す
    }
}

逆にすると、ロールバック済みの状態から部分的に再実行してしまい
整合性が壊れる。
SQL Server でのデッドロックのリトライ設計と同じ原則である。

補足(最新化:一時的エラーへの対処): クラウドの DB は
フェールオーバーやスロットリングによる**一時的エラー(transient fault)**が
前提であり、リトライは必須である。
現在は専用ライブラリを持ち込まなくても、

  • Microsoft.Data.SqlClientConnectRetryCount / ConnectRetryInterval
  • EF Core の EnableRetryOnFailure()SqlServerRetryingExecutionStrategy
  • Polly(汎用のリトライ/サーキット ブレーカー ライブラリ)

で対応するのが標準である。
なお、EF Core の再試行戦略とユーザー定義トランザクションは
併用に注意が要る(ExecuteAsync でラップする必要がある)。

Row-Level Security

補足: 見出しのみだが、前述のとおり
マルチテナント パターンの要となる機能である。
テナント ID による絞り込みを DB 側のポリシーとして強制できる。

CREATE FUNCTION dbo.fn_tenantAccessPredicate(@TenantId int)
RETURNS TABLE WITH SCHEMABINDING
AS RETURN SELECT 1 AS ok
   WHERE @TenantId = CAST(SESSION_CONTEXT(N'TenantId') AS int);

CREATE SECURITY POLICY dbo.tenantSecurityPolicy
ADD FILTER PREDICATE dbo.fn_tenantAccessPredicate(TenantId) ON dbo.Orders,
ADD BLOCK PREDICATE  dbo.fn_tenantAccessPredicate(TenantId) ON dbo.Orders
WITH (STATE = ON);

アプリ側は接続時に sp_set_session_contextTenantId を設定する。
WHERE TenantId = @id の付け忘れによる情報漏えいを構造的に防げるのが利点。

サンプルを実行する方法

https://github.com/OpenTouryoProject/SampleProgram/blob/master/Azure/ElasticDatabase/ElasticDB_Sample/

以下の処理を実行する。

実行する処理

前提

Azure SQL database

Azure SQL database (V12 servers)

Visual Studio

Visual Studio 2012 or higher with C# is required.

.NET Framework

.NET Framework 4.5 or a later version

library

  • Nuget 2.7 or higher.
    • Elastic Database Client Library.

Azure SQL databasesの準備

Azure SQL databasesの作成

  • Azure portal から SQL databases(named ElasticDatabase) を作成する。

Elastic databaseの作成

移行メモ(誤字): 元ページの「naned ElasticDatabase」は
named ElasticDatabase」の誤記。

接続文字列を設定する。

接続文字列を取得

接続文字列をconfigに設定

  • このサンプルで SQL Server + Windows 認証を使用する場合、
    以下の設定が必要(テスト用?)。
<add key="IntegratedSecurity" value="true" />

注:この設定はサンプル独自の設定。

補足: 接続文字列に資格情報を直書きするのは検証目的の便宜である。
実運用では Microsoft Entra ID 認証やマネージド IDを使い、
パスワードを持たない構成にする
ADO.NETデータプロバイダの接続文字列)。

ShardMapの準備

ShardMapとShardの作成

ShardMapの作成

  • オプション 1 でコードを実行した時に ShardMap と Shard が作成される。

ShardMapの作成結果

  • オプション 2 で追加の Shard が作成される。

ShardMapの追加

ShardMapとShardの確認

追加された ShardMap と Shard(SQL Serverの Instance)を確認。

  • ポータルから ShardMap と Shard を確認。

追加されたShardMapとShardの確認

  • Visual Studio から ShardMap と Shard を確認。

追加されたShardMapとShardの確認2

DataDependentRoutingでShardに行挿入

Shardへの行挿入

Dependent Routingで行挿入

  • オプション 3 で上記コードを実行した時に Data Dependent Routing で行挿入される
    (この ID の場合、Shard2 に挿入される)。

Dependent Routingで行挿入

Shardへ挿入された行を確認

  • Management Studio から Shard2 に挿入された行を確認する。

Shardに挿入された行を確認

MultiShardQueryの実行

MultiShardQueryで行をSELECT

  • オプション 4 で上記コードを実行した時に MultiShardQuery で行が SELECT される
    (この ID の場合、Shard2 の行が SELECT される)。

MultiShardQueryで行をSELECT

ShardMapの削除

ShardMapの削除

  • オプション 5 でコードを実行した時に ShardMap と Shard が削除される。

ShardMapの削除結果

Open棟梁の Elastic Database 対応 Dam

DamSqlDbWithMultiShardの取り込み

以下の差分のように、コードを修正して
DamSqlDbWithMultiShardを取り込むことができる。

https://github.com/OpenTouryoProject/OpenTouryoTemplates/compare/01-72...azuretmplt-chngs

Elastic Database 対応 Damのサンプル

https://github.com/OpenTouryoProject/SampleProgram/tree/master/Azure/ElasticDatabase/ElasticDB_Sample2/

前述の「サンプルを実行する方法」と同じ方法で実行できる。

参考

補足(最新化:現在の SaaS マルチテナント設計): Microsoft は現在、
SaaS のマルチテナント設計について
**「Azure SQL Database の SaaS チュートリアル」**や
Architecture Center のマルチテナント ガイダンスという形で
より広い選択肢を提示している。

選択肢 概要
DB per tenant + Elastic Pool 分離が強く、コストはプールで最適化。最も一般的
Sharded multi-tenant(本ページの方式) テナント数が非常に多い場合
Hyperscale 単一 DB のまま最大 100TB までスケール。シャーディング不要にできる

特に Azure SQL Database Hyperscale の登場により、
「容量が足りないからシャーディングする」という動機は
かなり減っている。
現在シャーディングを選ぶのは、
テナント単位の完全な分離地理的分散が要件になる場合が中心である。


Tags: 移行, データアクセス, ADO.NET, Azure

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally