-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ElasticScaleAndPool
- 戻る(冗長化アーキテクチャ、SQL Server)(分散・冗長化)
- Elastic Scale, Elastic Database Pool
- SQL Server のクラスタリング / SQL Server のレプリケーション / SQL Server リンクサーバ機能
RDBMS でのステートフルなデータ処理では難しかった、
拡張性+弾力性をアプリケーションに提供する。
- スケールアウト(水平分散)が可能
- アプリケーションをマルチテナント化する。
- インスタンス横断なトランザクション処理(ACID)
- その際に、アプリケーションの変更は不要。
(ただし、Elastic Database Client Library で作成し直す必要がある)
補足(シャーディングという解法): SQL Server パーティション分割が
1 インスタンス内でデータを分割するのに対し、
Elastic Scale は複数のデータベース インスタンスに跨って分割する
(= シャーディング)。
パーティション分割 シャーディング(Elastic Scale) 分割の範囲 1 データベース内 複数データベース(シャード) 主目的 保守性・アーカイブ スケールアウト(性能・容量) 上限 インスタンスの性能に律速 インスタンスを増やせる 横断クエリ 通常の SQL Multi-Shard Query が必要 SQL Server のレプリケーションの
「RAID1 的(ミラーリング)」に対して
「RAID0 的」と表現されるのがシャーディングである。
- DB シャーディングの構築と管理。
- 2 種類のツールが存在する。
DB シャーディングのクライアント・アプリケーションの開発。
-
Shard Map Management
- シャードのコレクションを管理する "shard map manager" と呼ばれる
特殊なデータベースを管理する。 - "shard map manager" は、スケールアウトされたデータベースを横断して、
メタデータを管理する。
- シャードのコレクションを管理する "shard map manager" と呼ばれる
-
Data Dependent Routing
1 回の呼び出しでテナントに対応するデータベースと接続する。 -
Multi-Shard Queries
1 回の呼び出しでシャードに跨ったデータを 1 つの結果セットに集約する。
補足(シャード マップ マネージャは単一障害点): どのシャードに
どのキー範囲が入っているかを保持するメタデータ DB であるため、
ここが落ちると全体が機能しない。
クライアント ライブラリはローカル キャッシュを持つが、
可用性の設計(SQL Server のクラスタリング)は
別途必要になる。
- DB シャーディングのスケールアウト(スケールイン)
- シャード マップの再構築などを行う。
- 一定量の 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 Client Library を使用し、
- Elastic Database Pool と shard set の全データベース横断の
Transact-SQL (T-SQL) を実行できる。 - なお、このクエリは、DML だけではなく、DDL、運用・保守タスクも実行できる。
- スキーマ変更
- 資格情報管理
- 参照データの更新
- パフォーマンス データの収集
- テナント(顧客)遠隔操作
補足: シャーディング構成で最も面倒なのが
**全シャードへのスキーマ変更(マイグレーション)**である。
Elastic Jobs はこれを一括実行するための仕組みで、
シャード数が増えるほど価値が上がる。
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
-
Connectionオブジェクトの取得方法が変わるだけ。 - SQL の実行自体は、従来の SqlClient を使用する。
-
参照クエリ専用。
-
DataReaderのみサポートする。 - Adapter 系はサポートしない。
-
-
従って、
Transactionもサポートしない。
補足(この差が設計を決める): 更新は Data Dependent Routing、
参照のうち横断が必要なものだけ Multi-Shard Query、という使い分けになる。
つまり、更新は必ず単一シャードに閉じる設計が前提であり、
シャード キー(テナント ID など)の選定が
アーキテクチャの成否を決める。
- TransactionScopeをサポートする。
- 複数 Instance を跨いだクエリを実行する場合、TransactionScopeを使用する。
- Data Dependent Routing のシナリオのみで有効。
Windows Azure AppFabric Customer Advisory チーム (CAT) と
patterns & practices チームが開発したライブラリ。
- クエリによって成功する可能性の高い処理のリトライを行う。
- Data Dependent Routing のシナリオのみで有効。
- 双方とも、Data Dependent Routing のシナリオのみで有効。
-
TransactionScopeと Retry policy の範囲は、
TransactionScope < Retry policy となる。
補足(入れ子の順序が重要): 「TransactionScope < Retry policy」とは、
リトライがトランザクションの外側にある、という意味である。Retry policy { TransactionScope { ← 失敗したらロールバックし、 ... 丸ごとやり直す } }逆にすると、ロールバック済みの状態から部分的に再実行してしまい
整合性が壊れる。
SQL Server でのデッドロックのリトライ設計と同じ原則である。
補足(最新化:一時的エラーへの対処): クラウドの DB は
フェールオーバーやスロットリングによる**一時的エラー(transient fault)**が
前提であり、リトライは必須である。
現在は専用ライブラリを持ち込まなくても、
Microsoft.Data.SqlClientのConnectRetryCount/ConnectRetryInterval- EF Core の
EnableRetryOnFailure()(SqlServerRetryingExecutionStrategy)- Polly(汎用のリトライ/サーキット ブレーカー ライブラリ)
で対応するのが標準である。
なお、EF Core の再試行戦略とユーザー定義トランザクションは
併用に注意が要る(ExecuteAsyncでラップする必要がある)。
補足: 見出しのみだが、前述のとおり
マルチテナント パターンの要となる機能である。
テナント 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_contextでTenantIdを設定する。
WHERE TenantId = @idの付け忘れによる情報漏えいを構造的に防げるのが利点。
- 参考
- Get started with elastic database tools
https://learn.microsoft.com/en-us/azure/azure-sql/database/elastic-scale-get-started - Elastic Database ツールの概要
https://learn.microsoft.com/ja-jp/azure/azure-sql/database/elastic-scale-get-started
- Get started with elastic database tools
以下の処理を実行する。

Azure SQL database (V12 servers)
Visual Studio 2012 or higher with C# is required.
.NET Framework 4.5 or a later version
- Nuget 2.7 or higher.
- Elastic Database Client Library.
- Azure portal から SQL databases(named ElasticDatabase) を作成する。

移行メモ(誤字): 元ページの「naned ElasticDatabase」は
「named ElasticDatabase」の誤記。
-
接続文字列は、
Configuration.GetCredentialsConnectionString()method が作成する。
https://github.com/OpenTouryoProject/SampleProgram/blob/master/Azure/ElasticDatabase/ElasticDB_Sample/ElasticScaleStarterKit/Configuration.cs -
ElasticDatabase をクリックする。
-
ダッシュボードから接続文字列を取得する。

- 接続文字列を config に設定する。
https://github.com/OpenTouryoProject/SampleProgram/blob/master/Azure/ElasticDatabase/ElasticDB_Sample/ElasticScaleStarterKit/App.config

- このサンプルで SQL Server + Windows 認証を使用する場合、
以下の設定が必要(テスト用?)。
<add key="IntegratedSecurity" value="true" />注:この設定はサンプル独自の設定。
補足: 接続文字列に資格情報を直書きするのは検証目的の便宜である。
実運用では Microsoft Entra ID 認証やマネージド IDを使い、
パスワードを持たない構成にする
(ADO.NETデータプロバイダの接続文字列)。
- 以下のコードは、ShardMap と Shard を作成するためのもの。
https://github.com/OpenTouryoProject/SampleProgram/blob/master/Azure/ElasticDatabase/ElasticDB_Sample/ElasticScaleStarterKit/Program.cs

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

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

追加された ShardMap と Shard(SQL Serverの Instance)を確認。
- ポータルから ShardMap と Shard を確認。

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

- 以下のコードは、Data Dependent Routing で行挿入するためのもの。
https://github.com/OpenTouryoProject/SampleProgram/blob/master/Azure/ElasticDatabase/ElasticDB_Sample/ElasticScaleStarterKit/DataDependentRoutingSample.cs

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

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

- 以下のコードは、MultiShardQuery で行を
SELECTするためのもの。
https://github.com/OpenTouryoProject/SampleProgram/blob/master/Azure/ElasticDatabase/ElasticDB_Sample/ElasticScaleStarterKit/MultiShardQuerySample.cs

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

- 以下のコードは、ShardMap と Shard を削除するためのもの。
https://github.com/OpenTouryoProject/SampleProgram/blob/master/Azure/ElasticDatabase/ElasticDB_Sample/ElasticScaleStarterKit/Program.cs

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

以下の差分のように、コードを修正して
DamSqlDbWithMultiShardを取り込むことができる。
https://github.com/OpenTouryoProject/OpenTouryoTemplates/compare/01-72...azuretmplt-chngs
前述の「サンプルを実行する方法」と同じ方法で実行できる。
- Elastic Database ツール機能の概要
https://learn.microsoft.com/ja-jp/azure/azure-sql/database/elastic-scale-introduction-
Azure SQL Database エラスティック データベース クエリの概要
https://learn.microsoft.com/ja-jp/azure/azure-sql/database/elastic-query-overview -
Azure SQL Database - クライアント ライブラリ
https://learn.microsoft.com/ja-jp/azure/azure-sql/database/elastic-database-client-library- シャード マップ管理
- データ依存ルーティング
- マルチシャード クエリ実行
-
エラスティック データベース分割/マージ ツールを使用したスケーリング
-
Elastic Scale のセキュリティの構成(分割/マージ サービスの利用に必要)
-
その他
- Elastic Database ジョブの概要
- 弾力性データベース ツールと行レベルのセキュリティを使用したマルチテナント アプリケーション
- Azure SQL Database エラスティック データベース プールの価格および
パフォーマンスに関する考慮事項
-
補足(最新化:現在の 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
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。