データ依存ルーティングを使用して、クエリを適切なデータベースにルーティングするUse Data-dependent routing to route a query to appropriate database

データ依存ルーティングは、クエリ内のデータを使用して、要求を適切なデータベースにルーティングできる機能です。Data-dependent routing is the ability to use the data in a query to route the request to an appropriate database. データ依存ルーティングは、シャード化されたデータベースを操作するときの基本的なパターンです。Data-dependant routing is a fundamental pattern when working with sharded databases. 特にシャーディング キーがクエリの一部でない場合は、要求コンテキストを使用して要求をルーティングすることもできます。The request context may also be used to route the request, especially if the sharding key is not part of the query. データ依存ルーティングを使用したアプリケーションで、特定のクエリまたはトランザクションがそれぞれアクセスするデータベースは、要求ごとに 1 つに制限されています。Each specific query or transaction in an application using data-dependent routing is restricted to accessing one database per request. Azure SQL Database Elastic ツールでは、このルーティングは ShardMapManager (Java.NET) クラスで実行します。For the Azure SQL Database Elastic tools, this routing is accomplished with the ShardMapManager (Java, .NET) class.

アプリケーションは、シャード化された環境の各種データ スライスに関連付けられた、さまざまな接続文字列または DB の場所を追跡する必要はありません。The application does not need to track various connection strings or DB locations associated with different slices of data in the sharded environment. 代わりに Shard Map Manager が正しいデータベースへの接続処理を必要に応じて管理します。Instead, the Shard Map Manager opens connections to the correct databases when needed, based on the data in the shard map and the value of the sharding key that is the target of the application’s request. 通常、このキーは、データベース要求の基本的なパラメーターである、customer_idtenant_iddate_key、または他の特定の識別子です。The key is typically the customer_id, tenant_id, date_key, or some other specific identifier that is a fundamental parameter of the database request.

詳細については、「データ依存型ルーティングを使用した SQL Server のスケールアウト」を参照してください。For more information, see Scaling Out SQL Server with Data-Dependent Routing.

クライアント ライブラリのダウンロードDownload the client library

ダウンロードの対象:To download:

データ依存ルーティング アプリケーションでの ShardMapManager の使用Using a ShardMapManager in a data-dependent routing application

アプリケーションは、ファクトリ呼び出し GetSQLShardMapManager (Java.NET) を使用して、初期化中に ShardMapManager をインスタンス化する必要があります。Applications should instantiate the ShardMapManager during initialization, using the factory call GetSQLShardMapManager (Java, .NET). この例では、ShardMapManager と、これが含んでいる特定の ShardMap の両方が初期化されます。In this example, both a ShardMapManager and a specific ShardMap that it contains are initialized. また、GetSqlShardMapManager メソッドと GetRangeShardMap (Java.NET) メソッドを使用しています。This example shows the GetSqlShardMapManager and GetRangeShardMap (Java, .NET) methods.

ShardMapManager smm = ShardMapManagerFactory.getSqlShardMapManager(connectionString, ShardMapManagerLoadPolicy.Lazy);
RangeShardMap<int> rangeShardMap = smm.getRangeShardMap(Configuration.getRangeShardMapName(), ShardKeyType.Int32);
ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(smmConnectionString, ShardMapManagerLoadPolicy.Lazy);
RangeShardMap<int> customerShardMap = smm.GetRangeShardMap<int>("customerMap"); 

シャード マップの取得には最小限のアクセス許可を持つ資格情報を使用するUse lowest privilege credentials possible for getting the shard map

アプリケーションでシャード マップ自体を操作しない場合は、ファクトリ メソッドで使用される資格情報には、グローバル シャード マップ データベースに対する読み取り専用アクセス許可を付与します。If an application is not manipulating the shard map itself, the credentials used in the factory method should have read-only permissions on the Global Shard Map database. これらの資格情報は、通常、シャード マップ マネージャーへの接続で使用される資格情報とは異なります。These credentials are typically different from credentials used to open connections to the shard map manager. Elastic Database クライアント ライブラリへのアクセスに使用する資格情報」も参照してください。See also Credentials used to access the Elastic Database client library.

OpenConnectionForKey メソッドを呼び出すCall the OpenConnectionForKey method

ShardMap.OpenConnectionForKey メソッド (Java.NET) は、key パラメーターの値に基づいて、適切なデータベースへのコマンド発行の準備が整った接続を返します。The ShardMap.OpenConnectionForKey method (Java, .NET) returns a connection ready for issuing commands to the appropriate database based on the value of the key parameter. シャード情報は、ShardMapManager によってアプリケーションにキャッシュされるため、これらの要求では通常は、グローバル シャード マップ データベースに対するルックアップは行われません。Shard information is cached in the application by the ShardMapManager, so these requests do not typically involve a database lookup against the Global Shard Map database.

// Syntax:
public Connection openConnectionForKey(Object key, String connectionString, ConnectionOptions options)
// Syntax:
public SqlConnection OpenConnectionForKey<TKey>(TKey key, string connectionString, ConnectionOptions options)
  • key パラメーターは、要求に対する適切なデータベースを特定するためのシャード マップへのルックアップ キーとして使用されます。The key parameter is used as a lookup key into the shard map to determine the appropriate database for the request.
  • connectionString は、必要な接続を行うためのユーザーの資格情報のみを渡すために使用されます。The connectionString is used to pass only the user credentials for the desired connection. この connectionString には、データベース名またはサーバー名は含まれません。メソッドがデータベースとサーバーを特定するために ShardMap を使用するためです。No database name or server name is included in this connectionString since the method determines the database and server using the ShardMap.
  • 分割やマージの操作の結果、シャード マップが変更されている可能性や、行が他のデータベースに移動している可能性のある環境では、connectionOptions (Java.NET) を ConnectionOptions.Validate に設定する必要があります。The connectionOptions (Java, .NET) should be set to ConnectionOptions.Validate if an environment where shard maps may change and rows may move to other databases as a result of split or merge operations. この検証では、接続要求がアプリケーションに配信される前に、ターゲット データベースにあるローカルのシャード マップ (グローバル シャード マップではない) に対する簡単なクエリが実行されます。This validation involves a brief query to the local shard map on the target database (not to the global shard map) before the connection is delivered to the application.

ローカルのシャード マップの検証が失敗した (キャッシュが正しくないことが示された) 場合は、シャード マップ マネージャーがグローバル シャード マップに対してクエリを実行し、ルックアップの正しい値を新しく取得します。その後、キャッシュを更新してから適切なデータベース接続を取得して戻します。If the validation against the local shard map fails (indicating that the cache is incorrect), the Shard Map Manager queries the global shard map to obtain the new correct value for the lookup, update the cache, and obtain and return the appropriate database connection.

ConnectionOptions.None を使用するのは、アプリケーションがオンラインの間にシャード マッピングの変更が想定されない場合のみです。Use ConnectionOptions.None only when shard mapping changes are not expected while an application is online. その場合、キャッシュされた値は常に正しいと見なすことができ、ターゲット データベースに対する今後のラウンドトリップ検証呼び出しを安全にスキップすることができます。In that case, the cached values can be assumed to always be correct, and the extra round-trip validation call to the target database can be safely skipped. これによりデータベース トラフィックを軽減できます。That reduces database traffic. また、 connectionOptions は、一定期間内にシャーディングの変更が想定されるかどうかを示すために構成ファイルの値で設定することもできます。The connectionOptions may also be set via a value in a configuration file to indicate whether sharding changes are expected or not during a period of time.

この例では、customerShardMap という名前のオブジェクト ShardMap を使用した、整数キー CustomerID の値を使用しています。This example uses the value of an integer key CustomerID, using a ShardMap object named customerShardMap.

int customerId = 12345;
int productId = 4321;
// Looks up the key in the shard map and opens a connection to the shard
try (Connection conn = shardMap.openConnectionForKey(customerId, Configuration.getCredentialsConnectionString())) {
    // Create a simple command that will insert or update the customer information
    PreparedStatement ps = conn.prepareStatement("UPDATE Sales.Customer SET PersonID = ? WHERE CustomerID = ?");

    ps.setInt(1, productId);
    ps.setInt(2, customerId);
    ps.executeUpdate();
} catch (SQLException e) {
    e.printStackTrace();
}
int customerId = 12345;
int newPersonId = 4321;

// Connect to the shard for that customer ID. No need to call a SqlConnection
// constructor followed by the Open method.
using (SqlConnection conn = customerShardMap.OpenConnectionForKey(customerId, Configuration.GetCredentialsConnectionString(), ConnectionOptions.Validate))
{
    // Execute a simple command.
    SqlCommand cmd = conn.CreateCommand();
    cmd.CommandText = @"UPDATE Sales.Customer
                        SET PersonID = @newPersonID WHERE CustomerID = @customerID";

    cmd.Parameters.AddWithValue("@customerID", customerId);cmd.Parameters.AddWithValue("@newPersonID", newPersonId);
    cmd.ExecuteNonQuery();
}  

OpenConnectionForKey メソッドは、正しいデータベースに対し、既に開いている接続を新たに返します。The OpenConnectionForKey method returns a new already-open connection to the correct database. この方法で接続した場合も引き続き接続プーリングの利点を最大限に活用できます。Connections utilized in this way still take full advantage of connection pooling.

アプリケーションが非同期プログラミングを使用する場合は、OpenConnectionForKeyAsync method (Java.NET) も使用できます。The OpenConnectionForKeyAsync method (Java, .NET) is also available if your application makes use asynchronous programming.

一時的な障害処理との統合Integrating with transient fault handling

クラウドでのデータ アクセス アプリケーション開発のベスト プラクティスは、一時的な障害をアプリケーションで確実に捕捉し、エラーがスローされる前に操作を確実にリトライすることです。A best practice in developing data access applications in the cloud is to ensure that transient faults are caught by the app, and that the operations are retried several times before throwing an error. クラウド アプリケーションにおける一時的な障害処理の詳細については、一時的な障害処理 (Java.NET) に関するページをご覧ください。Transient fault handling for cloud applications is discussed at Transient Fault Handling (Java, .NET).

一時的な障害処理は、データ依存ルーティングのパターンと自然に共存できます。Transient fault handling can coexist naturally with the Data-Dependent Routing pattern. そのための主な要件は、データ依存ルーティング接続を取得した using ブロックを含めたデータ アクセス要求全体をリトライすることです。The key requirement is to retry the entire data access request including the using block that obtained the data-dependent routing connection. 前の例は次のように書き換えることができます。The preceding example could be rewritten as follows.

例 - 一時的な障害処理機能を伴うデータ依存ルーティングExample - data-dependent routing with transient fault handling

int customerId = 12345;
int productId = 4321;
try {
    SqlDatabaseUtils.getSqlRetryPolicy().executeAction(() -> {
        // Looks up the key in the shard map and opens a connection to the shard
        try (Connection conn = shardMap.openConnectionForKey(customerId, Configuration.getCredentialsConnectionString())) {
            // Create a simple command that will insert or update the customer information
            PreparedStatement ps = conn.prepareStatement("UPDATE Sales.Customer SET PersonID = ? WHERE CustomerID = ?");

            ps.setInt(1, productId);
            ps.setInt(2, customerId);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    });
} catch (Exception e) {
    throw new StoreException(e.getMessage(), e);
}
int customerId = 12345;
int newPersonId = 4321;

Configuration.SqlRetryPolicy.ExecuteAction(() =&gt;
{
    // Connect to the shard for a customer ID.
    using (SqlConnection conn = customerShardMap.OpenConnectionForKey(customerId, Configuration.GetCredentialsConnectionString(), ConnectionOptions.Validate))
    {
        // Execute a simple command
        SqlCommand cmd = conn.CreateCommand();

        cmd.CommandText = @"UPDATE Sales.Customer
                            SET PersonID = @newPersonID
                            WHERE CustomerID = @customerID";

        cmd.Parameters.AddWithValue("@customerID", customerId);
        cmd.Parameters.AddWithValue("@newPersonID", newPersonId);
        cmd.ExecuteNonQuery();

        Console.WriteLine("Update completed");
    }
});

一時的な障害処理の実装に必要なパッケージは、エラスティック データベースのサンプル アプリケーションのビルド時に自動的にダウンロードされます。Packages necessary to implement transient fault handling are downloaded automatically when you build the elastic database sample application.

トランザクションの整合性Transactional consistency

トランザクションのプロパティは、シャードにとってローカルなすべての操作で保証されています。Transactional properties are guaranteed for all operations local to a shard. たとえば、データ依存ルーティングを通じて送信されるトランザクションは、接続するターゲット シャードの範囲内で実行されます。For example, transactions submitted through data-dependent routing execute within the scope of the target shard for the connection. 現時点では、複数の接続を 1 つのトランザクションに登録するために提供された機能はありません。したがって、複数のシャードにまたがる操作にもトランザクション上の保証はありません。At this time, there are no capabilities provided for enlisting multiple connections into a transaction, and therefore there are no transactional guarantees for operations performed across shards.

次の手順Next steps

シャードをデタッチまたは再アタッチする方法については、「 RecoveryManager クラスを使用したシャード マップに関する問題の解決To detach a shard, or to reattach a shard, see Using the RecoveryManager class to fix shard map problems

その他のリソースAdditional resources

まだ弾力性データベース ツールを使用していない場合は、Not using elastic database tools yet? ファースト ステップ ガイドを参照してください。Check out our Getting Started Guide. 質問がある場合は、SQL Database のフォーラムに投稿してください。機能に関するご要望は、SQL Database に関するフィードバック フォーラムにお寄せください。For questions, please reach out to us on the SQL Database forum and for feature requests, please add them to the SQL Database feedback forum.