予測: クラウド

SQL Azure によるブランチ ノードの同期

Joseph Fultz

私は、マイクロソフトへの入社前と入社後の数年間、小売り業界に大きくかかわっていました。その間、テクノロジの進歩によってブランチ ノードの同期に関する問題が解決されるのを目にすることが非常に多く、ほとんどユーモラスに感じるほどでした。

現在の職務では、石油/ガス業界にかなりかかわっていますが、この業界にもノード間でのデータ同期という同じような問題があることがわかりました。石油/ガス企業では、小売りチェーンと同様、さまざまなデバイスが使用され、接続に関するさまざまな課題があります。海上石油プラットフォームで使われる可能性のある衛星通信から、油田の技術者に至るまで、タイムリーで正確なデータを必要としていることに変わりはありません。

そこで、小売りと石油/ガスの両方を念頭に置いて、再びこの課題について見ていきます。ただし、今回は少し SQL Azure と Sync Framework の助けを借りて、データセンター (本社) からブランチ (たとえば、店舗、掘削装置、ハブなど) へ、そして個々のデバイス (ハンドヘルド、共用端末、特定の機器など) へのデータの移動に関する問題を解決するのにクラウドがどのように役立つかについて説明します。

今月は、アーキテクチャ全般についての説明を少し多めに、実装についての説明を少なめにします。ですが、ノードと SQL Azure の間で同期を設定し、同期に必要なトラフィックと時間を削減する方法としてコンテンツをフィルター処理するためのコード例はいくつか紹介します。来月のコラムでは、サービス ベースの同期のアプローチを使用して、コンテンツの分散や地理的分散に基づいて複数の SQL Azure データベースにデータを分配するだけにとどまらないスケーラブルな同期ソリューションを提供することについて考察します。

中核となる問題は変わっていませんが、テクノロジが進歩するにつれてソリューションに要求されることが増えています。ノード間でのデータ移動という単純な問題を解決すればよいのではなく、より多くの詳細を得るためのデータ量増加、データの収集と表示のためのさまざまなデバイスの利用、よりリアルタイムに近いフィードなど、要求として望まれることが追加されるようになっています。

この現実に向き合いましょう。人は、持てば持つほど欲張りになってしまうものなのです。ほとんどの場合、10 年前から存在するデータ フローの問題を解決するのは簡単ですが、今日の環境でのそのソリューションは、より堅牢なソリューションの土台にすぎません。小売りの場合、データ フローは (カタログ形式のデータ (メニュー、倉庫など) のプッシュおよびトランザクション ログのバックアップという形をとり) とても簡単な場合もあれば、(在庫水準の頻繁な更新、リアルタイムの損失防止分析、ブランチから本社へ、およびブランチ間での手動の商品登録を伴い) 非常に複雑な場合もあります。大部分においては石油/ガス企業もパターンは同じですが、石油/ガス企業の場合、使用される機器の操作、評価、および調整に関する複雑さが少し増します。複雑さのレベルについて大まかに理解するため、次の方法での同期について考えます (この 4 つの中では、後の方法ほど、実装とサポートがより複雑です)。

  1. 本社からブランチへ、そしてその先への、読み取り専用データのプッシュ。
  2. 異なるデータに対する 2 つの一方向プッシュ (本社からブランチへのプッシュ (カタログなど) およびブランチから本社へのプッシュ (トランザクション ログ、在庫など))。これには、ブランチからブランチへのプッシュも含まれます。ポイントは、基本的に 2 つ以上の一方向同期であることです。
  3. 本社とノードの間の双方向のデータ同期 (手動での商品登録や従業員情報など)。
  4. ブランチ間およびブランチと本社の間のピア同期。

タイプ 4 は他と比べてはるかに複雑な問題で、通常、多くの競合をもたらします。そのため、このパターンを避けるよう努めます。このパターンの使用を余儀なくされる条件は、ノード間でリアルタイム更新を行う必要がある、または本社のデータ ストアにアクセスできない場合にブランチを同期できる必要があるという 2 つのみです。あまりにも多くのノード間でのほぼリアルタイムまたはリアルタイムの更新は、一般に過剰な量のトラフィックをもたらし、通常は理にかなった解決策ではないため、本当に注意を払うべき唯一の条件は、マスターなしで同期できることです。ノード間でリアルタイムの情報が必要となる場合もありますが、一般に、データ同期では必要となりません。これが必要となるのはイベント通知のシナリオであり、このニーズに対処するには別の方法が使用されます。

ソリューション アーキテクチャを定義する

一般に最も普及していると思われるパターンは、本社のマスター データベースから (なんらかのディストリビューターを通じて) ブランチのサーバーやモバイル ユーザーへデータを直接プッシュするというものです。ワークステーション、販売時点管理 (POS) 端末などのデバイスへのデータ配布は、通常、ブランチにあるサーバー (通称 "back-of-house サーバー"。"back-of-house" は "裏手" を指します) から行われ、一方、モバイル ユーザー (ノート PC など) への同期は、クライアントによって開始された同期プロセスを通じて、本社からコンピューターへ直接行われます (図 1 参照)。

image: Typical Architecture for Data Distribution

図 1 データ配布の標準アーキテクチャ

リレーショナル データベース管理システム (RDBMS) 組み込みのレプリケーション機能を通じてこれを行う組織もあれば、データの配布と収集を処理するプロセスを構築する組織もあります。今回は、パターンを維持しつつ、ディストリビューターの代わりに SQL Azure のインスタンスを使用し、レプリケーションの代わりに、SQL Azure をサポートする Sync Framework を使用します。したがって、単に、ディストリビューターとブランチの間に層を 1 つ追加することになります (図 2 参照)。

image: Base Architecture Using SQL Azure and the Sync Framework

図 2 SQL Azure と Sync Framework を使用した基本アーキテクチャ

SQL Azure を挟むとどうなるのでしょう。ブランチ ノードのシナリオにおけるメリットのいくつかを以下に示します。

  1. データセンターのフットプリントを増大させることなく、データ サービスをスケール変更できます。
  2. 追加のコストや労力を費やすことなく、データの可用性を高めることができます。
  3. SQL Azure はマスター データ ストアではないため、挟まない場合と比べてセキュリティを気にしなくて済む可能性があります。

最初のシナリオで、本社の接続またはデータ ストアがダウンした場合、すべてのクライアントがトランザクションを維持する必要があるとします。その場合、接続の回復を待つ間にデバイスがなくなったり、前述のとおり、トランザクションを保存するためのデバイス上の領域が使い果たされたりすることで、容易にデータの損失が発生します。さらに、ブランチが共通のデータを持つ場合 (倉庫の在庫データなど)、ブランチは本社が正常な状態に戻るまで古いデータを利用することになります。完ぺきな解決策はありませんが、SQL Azure では、自動的にデータのコピーを作成し自動フェールオーバーを提供することでこのシナリオに対処します。また、複数の SQL Azure データベースを通じてデータのフローを分割することで、ダウンのリスクを減らすことができ、別々のインスタンスだけでなく別々のデータセンターも使用することで、負荷の影響をさらに減らすことができます。

設計のポイントとして、同期をブランチとサーバーのどちらから開始するかによる影響を考慮する必要があります。マスターまたはディストリビューターからノードへ同期するようにアプリケーションを設計すると、管理とサポートを行うポイントがより少なくて済むというメリットがありますが、実装にいくつかの技術的負担がもたらされ、次のようなことが必要となるというデメリットがあります。

  1. エンドポイントを認識する。
  2. ターゲットごとに適したスコープを認識する。
  3. 複数ノードの同期を並列に行うため、同期プロセスが複雑になる。実際、API セマンティクスは一度に 1 組のエンドポイントと 1 つのスコープです。

同期をターゲット (ノードやブランチなど) から開始すると、次のような理由で同期コードの複雑さは軽減されます。

  • アプリケーション/デバイスのスコープに的を絞ることができる。
  • より容易に随時接続に対処できる。
  • 同期コードでは、配布データを同期するいくつかのエンドポイントのみを認識および管理すればよい。

ただし、同期をターゲットから開始すると、ターゲット デバイス上のアプリケーションの複雑さが少し増します。また、各デバイスで同期プロセスまたはエージェントをデバッグしなければならない可能性があるため、サポートと保守が複雑になる場合があります。複数のアプリケーションのデータを同期する必要がある場合、理想的なのは、同期エージェントを実行するためのスコープ、頻度、および接続文字列が定義されている構成ファイルに基づいて同期を管理する、独立したプロセスを作成することです。この同期エージェントは、デバイス上のデータ コンシューマーであるアプリケーションの外部に存在しますが、各アプリケーションがデータの同期を開始する手段は各プロセスによって提供されます。これにより、ノードから同期を開始するメリットが得られるだけでなく、サポートと保守が 1 つのプロセスにまとめられるため、サポートと保守が楽になるというメリットもあります。

Sync Framework を使用する場合、マスター データ ストアから SQL Azure へ同期を開始し、その後、ノードから同期を開始してノードと SQL Azure の間で同期するという混合の同期モデルを出発点とします。SQL Azure がマスターとブランチの間の可用性の高い中央のハブとなり、データがマスターからプッシュされブランチからプルされると言い換えることもできます。検討しているソリューションのニーズと制約に基づいて、同期プロセスの制御をチェーン内のある場所から別の場所へ (たとえば、デバイスからクラウドへ、または本社からクラウドへ) 移すことのコストとメリットについて考えます。こうした考慮事項のほんのいくつかを挙げると、次のような疑問が生じます。

  • マスターのプロセスをホストする場所はあるか。
  • SQL Azure で同期プロセスをホストすることと競合するセキュリティ ポリシーはあるか。
  • 各レベルでいくつのノードが同期されるか。
  • ターゲット デバイスは現実に同期プロセスをサポートできるか。
  • データ同期のタイムリーさに関する要件は何か。

さらに、こうした疑問のそれぞれに対して、考慮すべき複数の層が存在し、考えられるソリューション設計をこうした複数の層に対して綿密に調査する必要があります。万能の設計は存在しませんが、前述のモデルを出発点として、複数の一方向同期により双方向データ同期に似たものを実現するか、デバイス/本社データベースと SQL Azure の間で双方向同期を使用することをお勧めします。その後、設計を無効にし、設計の修正を余儀なくするシナリオを探します。通常、避けるよう努める同期スタイルはピアツーピアのみです。

同期を設定する

Sync Framework 2.1 を使用して同期を設定する方法は、クラウドでクライアントを同期するか、ローカル コンピューター上でクライアントを同期するかの 2 つです。差し当たり、後者に注目します。同期リレーションシップを設定するための手順を以下にごく簡単に示します。

  1. 同期するデータ、およびデータ フローの方向を特定します。これは、データの同期に使用されるスコープ (SqlSyncScopeProvisioning) の定義に使用します。
  2. Sync Framework 2.1 をダウンロードしてインストールします (microsoft.com/downloads/details.aspx?FamilyID=ee6af141-79d0-4351-a4a0-ea89bb29dcf5&displayLang=ja)。注: x64 がターゲット プラットフォームの場合は、x64 用のビルド ターゲットを追加する必要があります。そうしなければ、SyncOrchestrator で依存関係を解決することができません。
  3. データベースとテーブルを同期用に準備します。データベース全体を準備することも、特定のテーブルのみを準備することも、特定の列のみを準備することもできます。
  4. 必要なフィルターを追加します。データを水平方向にパーティション分割したり、フィルター処理したりする場合は、フィルターを使用できます。
  5. 同期するプロセスを作成および実行します。

趣旨が伝わりやすいように、ここではかなり具体的な例を示します。また、両側にデータベースが用意された状態からスタートします。ローカル データベースへの接続を作成し、同期するテーブルの定義 (DbSyncTableDescription) を取得して、そのテーブルをスコープ (DbSyncScopeDescription) に追加します。さらに、特定の列を指定しますが、単にテーブル全体を同期する必要があるだけの場合はこれは必要ありません。同期リレーションシップを特定の列のみに限定するのは、帯域幅の使用を最適化しプロセスを迅速化するための優れた方法です (図 3 参照)。

図 3 同期スコープの作成

SqlConnection azureConn = new SqlConnection(AzureConnectionString);
SqlConnection onPremiseConn = new SqlConnection(LocalConnectionString);

// List of columns to include
Collection<string> columnsToInclude = new Collection<string>();
columnsToInclude.Add("au_id");
columnsToInclude.Add("au_lname");
columnsToInclude.Add("au_fname");
columnsToInclude.Add("phone");
columnsToInclude.Add("address");
columnsToInclude.Add("city");
columnsToInclude.Add("state");
columnsToInclude.Add("zip");
columnsToInclude.Add("contact");

// Definition for authors from local DB
DbSyncTableDescription authorsDescription =
  SqlSyncDescriptionBuilder.GetDescriptionForTable("authors", 
  columnsToInclude, onPremiseConn);

// Create a scope and add tables to it
DbSyncScopeDescription authorScopeDesc = new DbSyncScopeDescription(ScopeName);

// Add the authors table to the sync scope
authorsScopeDesc.Tables.Add(authorsDescription);

同期する必要がある構造ごとに、説明を取得するコードを少し追加する必要があります。続いて、それをスコープに追加する必要があります。次のステップは、スコープ準備オブジェクトを取得し、スコープがまだそのデータベース内に存在しない場合はそのオブジェクトを使用して各データベースを準備することです (図 4 参照)。

図 4 スコープの準備

// Create a provisioning object for "customers" and 
// apply it to the on-premises database
SqlSyncScopeProvisioning onPremScopeConfig = 
  new SqlSyncScopeProvisioning(onPremiseConn, authorsScopeDesc);
if (!(onPremScopeConfig.ScopeExists(authorsScopeDesc.ScopeName)))
{
  onPremScopeConfig.Apply():
}
// Provision the SQL Azure database from the on-premises SQL Server database
SqlSyncScopeProvisioning azureScopeConfig = 
  new SqlSyncScopeProvisioning(azureConn, authorsScopeDesc);
if (!(azureScopeConfig.ScopeExists(authorsScopeDesc.ScopeName)))
{
  azureScopeConfig.Apply();
}

データベース内でスコープが準備されるのはこれが初めてなので、スコープ情報を格納するためのいくつかの新しいテーブルが用意され、データベース内で準備された Authors スコープの追跡専用のテーブルも用意されます。ローカル データベースおよび SQL Azure データベースを準備または同期するコンソール アプリケーションの優れた例については、Sync Framework チームのブログ (bit.ly/dCt6T0、英語) を参照してください。

補足記事: SQL Azure Data Sync

SQL Azure Data Sync は Windows Azure でホストされるクラウド ベースのサービスで、SQL Server と SQL Azure の間でのデータベース全体または特定のテーブルの同期を可能にします。Microsoft Professional Developers Conference 2010 で、SQL Azure Data Sync Community Technology Preview (CTP) 2 と呼ばれる、このサービスへの更新が発表されました。この更新により、組織は内部設置型の SQL Server データベースを簡単にクラウドへ拡張できるようになり、アプリケーションを段階的にクラウドに移行することが可能になります。SQL Azure Data Sync を利用するソリューションを使用すると、ユーザーは、ローカル データにアクセスし続けることができ、変更発生時にシームレスに SQL Azure に同期させることができます。同様に、アプリケーションから SQL Azure に加えられた変更はすべて、内部設置型の SQL Server に同期されます。

データの同期を維持する

SQL Azure Data Sync は、すべての同期リレーションシップ向けに、中心となるクラウド ベースの管理システムを提供します。管理者は、任意のブラウザーから、パブリック サービスに接続し、さまざまなデータベース エンドポイントを管理および監視することができます。さらに、SQL Azure Data Sync ではスケジューリング サービスも提供され、同期を 5 分おきという高頻度で行うことも、また、同期をオフピーク時に実行したい場合はより低い頻度で行うこともできます。

最近の、SQL Azure Data Sync CTP 2 の更新では、SQL Azure Data Sync Agent という新しいコンポーネントも導入されました。このエージェントは組織内にインストールされる Windows サービスであり、セキュリティが確保された送信 HTTPS 接続を通じてローカルの SQL Server データベースを SQL Azure Data Sync にリンクします。つまり、ファイアウォールやセキュリティ構成の観点からの要求事項はないということなので、セットアップは簡単です。このエージェントの役割は、タスクの監視とログ記録を行うこと、および SQL Azure Data Sync から同期要求を開始することです。

新しいシナリオ

SQL Azure Data Sync を使用すると、SQL Server と SQL Azure データベースの間の同期で、従来は構築するのが非常に難しかったたくさんの新しいシナリオが実現されます。ブランチ オフィスや小売り店のデータベースとデータを共有するとします。SQL Azure Data Sync を使用する場合、管理者は、データベース間で共有するデータを定義する "同期グループ" を作成するので、これは簡単です。こうした同期グループには、データを中央の SQL Azure "データ ハブ" に同期する、企業の SQL Server を含めることができます。その後、遠隔地や地方にあるすべての SQL Server データベースは、このデータ ハブからデータの変更を同期することができ、データをよりユーザーの近くに持ってくることが可能になる一方で、帯域幅が大幅に減少し、仮想プライベート ネットワーク (VPN) の要件も大幅に軽減されます。

また、複数の SQL Azure データセンター間での同期が可能になることで、負荷を複数の地点にわたってスケールアウトするのが容易になります。3 か月ごとに報告書を提出する必要があり、これによって SQL Server データベースに非常に大きな周期的負荷がかかるとします。必要に応じてそのデータの一部を世界中の SQL Azure データベースに同期してはいかがでしょう。そうすれば、ユーザーは自分に最も近い場所にあるデータにアクセスすることができ、皆さんのローカルの SQL Server に対するスケーラビリティ要件は軽減されます。

詳細情報を確認し、CTP 2 を使用するための登録を行うには、microsoft.com/en-us/sqlazure/datasync.aspx (英語) を参照してください。

—Liam Cavanagh (SQL Azure Data Sync のシニア プログラム マネージャー)

データを同期する

データベースを適切に準備できたら、データベースを同期するのは非常に簡単です。これを行うには、アクティビティのそれぞれの側で、指定されたスコープを使用して SqlSyncProvider を作成する必要があります。これには、SyncOrchestrator オブジェクトを使用する必要があります。変更を特定しデータベース間で変更を移動するために背後で使用されるのがこのオブジェクトです。そのコードは次のようになります。

SqlConnection LocalConnection = new SqlConnection(LocalConnectionString);
SqlConnection AzureConnection = new SqlConnection(AzureConnectionString);

SqlSyncProvider LocalProvider = new SqlSyncProvider(ScopeName, LocalConnection);
SqlSyncProvider AzureProvider = new SqlSyncProvider(ScopeName, AzureConnection);

SyncOrchestrator orch= new SynOrchestrator();
orch.LocalProvider = new SqlSyncProvider(ScopeName, LocalConnection);
orch.RemoteProvider = new SqlSyncProvder(ScopeName, AzureConnection);
orch.Direction = SyncDirectionOrder.DownloadAndUpload;
orch.Synchronize();

データの分散と地理的分散

データの単純なレプリケーションには対処したので、今度は配置アーキテクチャとデータ フローの最適化に注目します。Sync Framework を使用して、フィルターを指定することができます。これを SQL Azure と組み合わせると、ブランチ ノード アーキテクチャにおいて非常に大きなメリットとなることがあります。この 2 つを組み合わせて使用すると、その地域またはデータ区分にとって重要なデータのみを同期することで、データをより最終消費者の近くに配置し、帯域幅の使用を (そして結果的に、料金も) 最適化することができます。さまざまな地域のデータ サーバーを使用するのではなく、データをその地域の SQL Azure のインスタンスのみに同期し、その地域のクライアントをそのインスタンスに同期することができます。

データを地理的に分散させ、特定のデータを特定の頻度で同期するのに適したスコープを実装すると、どのくらいの量のどのようなデータがいつ、どのようにネットワーク上を行き来するかをきめ細かく制御し、ユーザー エクスペリエンスを強化することができます (ユーザー エクスペリエンスはデータの可用性と鮮度に関係するため)。また、移動する可能性があり、位置が認識されるのが望ましいエンド ユーザー向けに、同期エージェントは現在位置を特定し、現在位置専用のデータ同期を試みることができます。この例をいくつか挙げると、製造環境や工場環境に入っていく労働者向けの現状通知や警告、小売りチェーンの地域担当マネージャー向けの当日の売上などがあります (図 5 参照)。

image: Synchronizing Data with Filters

図 5 フィルターを使用したデータ同期

フィルター処理を有効にするのは、同期スコープの準備と同じくらい簡単です。したがって、異なるフィルターを持つ (またはフィルターを持たない) 複数のスコープが存在する可能性があります。必要な変更は、単に、追加するフィルターごとに 2 行のコードを追加することです。この 2 行のコードとは、テーブルにフィルター列を追加するためのコード 1 行と、フィルター句を追加するためのコード 1 行 (つまり "where" 条件) です。今回のサンプルでは、次のように、州に基づくフィルターを追加し、ユタ (UT) 州に関する変更のみを同期しています。

onPremScopeConfig.Tables["authors"].AddFilterColumn("state");
onPremScopeConfig.Tables["authors"].FilterClause = "[authors].[state] = 'UT'";

フィルターに基づいて両方向に同期する場合は、それぞれの側でスコープを準備するときに両方のスコープにコードを追加する必要があります。

データを分散する

SQL Azure を (1 つのインスタンスであれ複数のインスタンスであれ) ソリューションに追加すると、この常に重要な間接化の層が追加されることで、ノードに同期する際のデータの可用性と全体的なパフォーマンスが本当に向上する場合があります。SQL Azure なら、インフラストラクチャの設計、準備、および管理に悩まされることなく、パフォーマンス、スケーラビリティ、および信頼性を高めることができます。来月のコラムでは、実装についてさらに詳しく述べ、10 月にリリースされた最新の Sync Framework 4.0 CTP (bit.ly/dpyMP8、英語) を使用して Windows Azure を同期用のソリューションに追加する方法について説明しますので、どうぞお楽しみに。

Joseph Fultz は、ダラスにある Microsoft Technology Center のアーキテクトで、企業ユーザーおよび ISV と連携して、ビジネスや市場の要求に応じてソフトウェア ソリューションを設計しプロトタイプを作成しています。Tech·Ed などのイベントや、同様の社内トレーニング イベントで講演を行っています。

この記事のレビューに協力してくれた技術スタッフの David Browne に心より感謝いたします。