Uso del enrutamiento dependiente de datos para enrutar una consulta a la base de datos adecuadaUse data-dependent routing to route a query to an appropriate database

SE APLICA A: Azure SQL Database

El enrutamiento dependiente de los datos es la posibilidad de utilizar los datos de una consulta para enrutar la solicitud a una base de datos adecuada.Data-dependent routing is the ability to use the data in a query to route the request to an appropriate database. El enrutamiento dependiente de los datos es un patrón fundamental cuando se trabaja con bases de datos con particiones.Data-dependent routing is a fundamental pattern when working with sharded databases. El contexto de solicitud también puede utilizarse para enrutar la solicitud, en especial si la clave de particionamiento no forma parte de la consulta.The request context may also be used to route the request, especially if the sharding key is not part of the query. Cada consulta o transacción específica en una aplicación que usa enrutamiento dependiente de los datos tiene restringido el acceso a una base de datos por solicitud.Each specific query or transaction in an application using data-dependent routing is restricted to accessing one database per request. En las herramientas elásticas de Azure SQL Database, este enrutamiento se efectúa con la clase ShardMapManager (Java, .NET).For the Azure SQL Database elastic tools, this routing is accomplished with the ShardMapManager (Java, .NET) class.

La aplicación no necesita realizar el seguimiento de las distintas cadenas de conexión o ubicaciones de base de datos asociadas con diferentes segmentos de datos en el entorno particionado.The application does not need to track various connection strings or DB locations associated with different slices of data in the sharded environment. Por el contrario, el Administrador de mapas de particiones abre las conexiones a las bases de datos correctas cuando es necesario, en función de los datos del mapa de particiones y del valor de la clave de particionamiento que es el destino de la solicitud de la aplicación.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. Esta clave normalmente es el valor de customer_id, tenant_id, date_key o algún otro identificador específico que sea un parámetro fundamental de la solicitud de la base de datos.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.

Para más información, consulte Scaling Out SQL Server with Data Dependent Routing (Escalado horizontal de SQL Server con enrutamiento dependiente de los datos).For more information, see Scaling Out SQL Server with Data-Dependent Routing.

Descarga de la biblioteca de clienteDownload the client library

Para descargar:To download:

Uso de ShardMapManager en una aplicación de enrutamiento dependiente de los datosUsing a ShardMapManager in a data-dependent routing application

Las aplicaciones deben crear una instancia de ShardMapManager durante la inicialización, mediante la llamada de fábrica GetSQLShardMapManager (Java, .NET).Applications should instantiate the ShardMapManager during initialization, using the factory call GetSQLShardMapManager (Java, .NET). En este ejemplo, se inicializan ShardMapManager y un elemento ShardMap específico que contiene.In this example, both a ShardMapManager and a specific ShardMap that it contains are initialized. En este ejemplo se muestran los métodos GetSqlShardMapManager y 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"); 

Uso de credenciales de menor privilegio posible para obtener el mapa de particionesUse lowest privilege credentials possible for getting the shard map

Si una aplicación no manipula el propio mapa de particiones, las credenciales utilizadas en el método de fábrica deben tener permisos de solo lectura en la base de datos del mapa de particiones global.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. Estas credenciales normalmente son distintas de las credenciales que se usan para abrir conexiones con el administrador de mapa de particiones.These credentials are typically different from credentials used to open connections to the shard map manager. Consulte también Credenciales usadas para acceder a la biblioteca de cliente de Elastic Database.See also Credentials used to access the Elastic Database client library.

Llamada al método OpenConnectionForKeyCall the OpenConnectionForKey method

El método ShardMap.OpenConnectionForKey (Java, .NET) devuelve una conexión lista para emitir comandos a la base de datos adecuada según el valor del parámetro 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. La información de particionamiento la almacena ShardMapManager en la caché de la aplicación, de modo que las solicitudes no implican normalmente una búsqueda de base de datos contra la base de datos Mapa de particiones global.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)
  • El parámetro key se usa como clave de búsqueda en el mapa de particiones para determinar la base de datos adecuada para la solicitud.The key parameter is used as a lookup key into the shard map to determine the appropriate database for the request.
  • El elemento connectionString se usa para pasar únicamente las credenciales de usuario para la conexión deseada.The connectionString is used to pass only the user credentials for the desired connection. Ningún nombre de base de datos o de servidor se incluye en esta connectionString, dado que el método determina la base de datos y el servidor a través de ShardMap.No database name or server name is included in this connectionString since the method determines the database and server using the ShardMap.
  • El valor de connectionOptions (Java, .NET) se debe establecer en ConnectionOptions.Validate si se trata de un entorno donde las asignaciones de las particiones pueden cambiar y las filas pueden moverse a otras bases de datos como resultado de operaciones de división o combinación.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. Esta validación implica una breve consulta al mapa de particiones local en la base de datos de destino (no al mapa de particiones global) antes de que se entregue la conexión a la aplicación.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.

Si se produce un error de validación de la asignación de particiones local (lo que indica que el caché es incorrecto), Shard Map Manager consulta la asignación de particiones global para obtener el nuevo valor correcto de la consulta, actualizar el caché, y obtener y devolver la conexión de base de datos adecuada.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.

Utilice ConnectionOptions.None solo cuando no se esperen cambios de asignación de particiones mientras una aplicación está en línea.Use ConnectionOptions.None only when shard mapping changes are not expected while an application is online. En ese caso, los valores en caché se pueden asumir como correctos siempre y la llamada de validación de ida y vuelta adicional a la base de datos de destino se puede omitir sin problemas.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. Esto reduce el tráfico de la base de datos.That reduces database traffic. connectionOptions también se puede definir a través de un valor en un archivo de configuración para indicar si se esperan o no cambios en el particionamiento durante un período.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.

En este ejemplo se utiliza el valor de una clave de entero CustomerID, mediante un objeto ShardMap denominado customerShardMap.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();
}  

El método OpenConnectionForKey devuelve una nueva conexión ya abierta a la base de datos correcta.The OpenConnectionForKey method returns a new already-open connection to the correct database. Las conexiones utilizadas de esta manera seguirán aprovechando completamente las agrupaciones de conexiones.Connections utilized in this way still take full advantage of connection pooling.

El método OpenConnectionForKeyAsync (Java, .NET)también está disponible si la aplicación utiliza programación asincrónica.The OpenConnectionForKeyAsync method (Java, .NET) is also available if your application makes use asynchronous programming.

Integración con el control de errores transitoriosIntegrating with transient fault handling

Un procedimiento recomendado para el desarrollo de aplicaciones de acceso a datos en la nube es tener la seguridad de que la aplicación es capaz de capturar los errores transitorios y que las operaciones se reintentan varias veces antes de presentarse un error.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. El control de errores transitorios para aplicaciones en la nube se describe en el artículo sobre el control de errores transitorios (Java, .NET).Transient fault handling for cloud applications is discussed at Transient Fault Handling (Java, .NET).

El control de errores transitorios puede coexistir naturalmente con el patrón de Enrutamiento dependiente de los datos.Transient fault handling can coexist naturally with the Data-Dependent Routing pattern. El requisito clave es volver a intentar la solicitud de acceso a los datos completa, incluido el bloque using que obtuvo la conexión de enrutamiento dependiente de los datos.The key requirement is to retry the entire data access request including the using block that obtained the data-dependent routing connection. El ejemplo anterior se podría volver a escribir como se indica a continuación.The preceding example could be rewritten as follows.

Ejemplo: enrutamiento dependiente de los datos con control de errores transitoriosExample - 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(() -> {

    // 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");
    }
});

Los paquetes necesarios para implementar el control de errores transitorio se descargan automáticamente cuando crea la aplicación de ejemplo de base de datos elástica.Packages necessary to implement transient fault handling are downloaded automatically when you build the elastic database sample application.

Coherencia de las transaccionesTransactional consistency

Las propiedades de las transacciones están garantizadas para todas las operaciones locales respecto a una partición.Transactional properties are guaranteed for all operations local to a shard. Por ejemplo, las transacciones enviadas a través del enrutamiento dependiente de los datos se ejecutan dentro del ámbito de la partición de destino de la conexión.For example, transactions submitted through data-dependent routing execute within the scope of the target shard for the connection. En este momento, no se proporcionan funcionalidades para alistar conexiones múltiples en una transacción y, por lo tanto, no hay garantías de transacciones para las operaciones realizadas a través de las particiones.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.

Pasos siguientesNext steps

Para desasociar o volver a asociar una partición, vea Uso de la clase RecoveryManager para solucionar problemas de mapas de particiones.To detach a shard, or to reattach a shard, see Using the RecoveryManager class to fix shard map problems.

Recursos adicionalesAdditional resources

¿Aún no ha usado las herramientas de base de datos elástica?Not using elastic database tools yet? Consulte la Guía de introducción.Check out our Getting Started Guide. Si tiene alguna pregunta, póngase en contacto con nosotros en la Página de preguntas y respuestas de Microsoft sobre SQL Database. Para efectuar solicitudes de características, agréguelas en el foro de comentarios sobre SQL Database.For questions, please reach out to us on the Microsoft Q&A question page for SQL Database and for feature requests, please add them to the SQL Database feedback forum.