Routing dipendente dei datiData dependent routing

Routing dipendente dei dati è la possibilità di usare i dati in una query per instradare la richiesta a un database appropriato.Data dependent routing is the ability to use the data in a query to route the request to an appropriate database. Questo costituisce un criterio fondamentale quando si usano database partizionati.This is a fundamental pattern when working with sharded databases. Per instradare la richiesta è anche possibile usare il contesto della richiesta stessa, soprattutto se la chiave di partizionamento orizzontale non fa parte della query.The request context may also be used to route the request, especially if the sharding key is not part of the query. Ogni query o transazione specifica in un'applicazione che usa il routing dipendente può accedere a un unico database per richiesta.Each specific query or transaction in an application using data dependent routing is restricted to accessing a single database per request. Per gli strumenti elastici del database SQL di Azure, il routing viene eseguito con la classe ShardMapManager (Java o .NET).For the Azure SQL Database Elastic tools, this routing is accomplished with the ShardMapManager (Java, .NET) class.

Per l'applicazione non è necessario rilevare le diverse stringhe di connessione o i percorsi dei database associati a diverse sezioni di dati nell'ambiente partizionato.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 che, quando necessario, apre le connessioni ai database corretti in base ai dati contenuti nella mappa partizioni e al valore della chiave di partizionamento orizzontale, che costituisce la destinazione della richiesta dell'applicazione.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. La chiave è in genere customer_id, tenant_id, date_key o un altro identificatore specifico che costituisce un parametro fondamentale della richiesta del database.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.

Per altre informazioni, vedere la pagina relativa all'aumento del numero di istanze di SQL Server con il routing dipendente dai dati.For more information, see Scaling Out SQL Server with Data Dependent Routing.

Scaricare la libreria clientDownload the client library

Per eseguire il download:To download:

Uso di ShardMapManager in un'applicazione di routing dipendente dai datiUsing a ShardMapManager in a data dependent routing application

Le applicazioni devono creare un'istanza di ShardMapManager durante l'inizializzazione, usando la chiamata alla factory GetSQLShardMapManager (Java o .NET).Applications should instantiate the ShardMapManager during initialization, using the factory call GetSQLShardMapManager (Java, .NET). In questo esempio, viene eseguita l'inizializzazione sia di ShardMapManager che una ShardMap specifica in essa contenuta.In this example, both a ShardMapManager and a specific ShardMap that it contains are initialized. Questo esempio illustra i metodi GetSqlShardMapManager e GetRangeShardMap (Java o .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(smmConnnectionString, ShardMapManagerLoadPolicy.Lazy);
RangeShardMap<int> customerShardMap = smm.GetRangeShardMap<int>("customerMap"); 

Usare credenziali con i privilegi più bassi possibile per ottenere la mappa partizioniUse lowest privilege credentials possible for getting the shard map

Se un'applicazione non gestisce direttamente la mappa partizioni, le credenziali usate nel metodo factory devono disporre solo di autorizzazioni di sola lettura per il database della mappa globale partizioni .If an application is not manipulating the shard map itself, the credentials used in the factory method should have just read-only permissions on the Global Shard Map database. Queste credenziali sono in genere diverse da quelle usate per aprire connessioni al gestore delle mappe partizioni.These credentials are typically different from credentials used to open connections to the shard map manager. Vedere anche Credenziali usate per accedere alla libreria client dei database elastici.See also Credentials used to access the Elastic Database client library.

Chiamare il metodo OpenConnectionForKeyCall the OpenConnectionForKey method

Il metodo ShardMap.OpenConnectionForKey (Java o .NET) restituisce una connessione pronta per l'invio di comandi al database appropriato in base al valore del parametro 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. Le informazioni sulla partizione vengono memorizzate nella cache dell'applicazione tramite ShardMapManager, in modo che in genere tali richieste non comportino una ricerca di database sul database Mappa globale partizioni.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)
  • Il parametro key viene usato come chiave di ricerca nella mappa partizioni per determinare il database appropriato per la richiesta.The key parameter is used as a lookup key into the shard map to determine the appropriate database for the request.
  • Il parametro connectionString viene usato per passare solo le credenziali utente per la connessione specifica.The connectionString is used to pass only the user credentials for the desired connection. In connectionString non viene incluso il nome del database o del server perché il metodo determina il database e il server usando ShardMap.No database name or server name is included in this connectionString since the method determines the database and server using the ShardMap.
  • Il parametro connectionOptions (Java o .NET) deve essere impostato su ConnectionOptions.Validate per un ambiente in cui le mappe partizioni possono essere modificate e le righe possono essere spostate in altri database in seguito a operazioni di divisione o unione.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. Ciò prevede una breve query sulla mappa locale partizioni nel database di destinazione (non sulla mappa globale partizioni) prima che la connessione venga fornita all'applicazione.This 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.

In caso di esito negativo della convalida in base alla mappa partizioni locale (che indica che la cache non è corretta), il gestore delle mappe partizioni esegue una query sulla mappa partizioni globale per ottenere il nuovo valore corretto per la ricerca, aggiornare la cache e ottenere e restituire la connessione al database appropriato.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.

Usare ConnectionOptions.None solo se non sono previste modifiche al mapping delle partizioni mentre l'applicazione è online.Use ConnectionOptions.None only when shard mapping changes are not expected while an application is online. In tal caso, i valori memorizzati nella cache possono essere considerati sempre corretti e la chiamata di convalida round trip aggiuntiva al database di destinazione può essere tranquillamente ignorata.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. Ciò riduce il traffico del database.That reduces database traffic. L'enumerazione connectionOptions può anche essere impostata tramite un valore in un file di configurazione per indicare se le modifiche di partizionamento sono o meno previste durante un intervallo di tempo.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.

Questo esempio usa il valore di una chiave Integer CustomerID, tramite un oggetto ShardMap denominato 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(); 
}  

Il metodo OpenConnectionForKey restituisce una nuova connessione già aperta al database corretto.The OpenConnectionForKey method returns a new already-open connection to the correct database. Le connessioni utilizzate in questo modo usufruiscono comunque del pool di connessioni.Connections utilized in this way still take full advantage of connection pooling.

Se l'applicazione usa la programmazione asincrona, è disponibile anche il metodo OpenConnectionForKeyAsync (Java o .NET).The OpenConnectionForKeyAsync method (Java, .NET) is also available if your application makes use asynchronous programming.

Integrazione con la gestione degli errori temporaneiIntegrating with transient fault handling

Una procedura consigliata nello sviluppo di applicazioni di accesso ai dati nel cloud consiste nel garantire che gli errori temporanei vengano rilevati dall'app e che le operazioni vengano ripetute più volte prima di generare un errore.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. La gestione degli errori temporanei per le applicazioni cloud è illustrata negli articoli in proposito relativi a Java e .NET.Transient fault handling for cloud applications is discussed at Transient Fault Handling (Java, .NET).

La gestione degli errori temporanei può coesistere naturalmente con il modello di routing dipendente dai dati.Transient fault handling can coexist naturally with the Data Dependent Routing pattern. Il requisito principale consiste nel ripetere l'intera richiesta di accesso ai dati, incluso il blocco using che ha ottenuto la connessione di routing dipendente dai dati.The key requirement is to retry the entire data access request including the using block that obtained the data-dependent routing connection. L'esempio precedente potrebbe essere riscritto come segue.The preceding example could be rewritten as follows.

Esempio: routing dipendente dai dati con gestione degli errori temporaneiExample - 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"); 
    } 
}); 

I pacchetti necessari per implementare la gestione degli errori temporanei vengono scaricati automaticamente quando si compila l'applicazione esempio dei database elastici.Packages necessary to implement transient fault handling are downloaded automatically when you build the elastic database sample application.

Coerenza delle transazioniTransactional consistency

Le proprietà transazionali sono garantite per tutte le operazioni locali rispetto a una partizione.Transactional properties are guaranteed for all operations local to a shard. Ad esempio, le transazioni inviate tramite il routing dipendente dai dati vengono eseguite nell'ambito della partizione di destinazione per la connessione.For example, transactions submitted through data-dependent routing execute within the scope of the target shard for the connection. Al momento, non sono disponibili funzionalità per l'inserimento di più connessioni in una transazione e pertanto non esistono garanzie transazionale per le operazioni eseguite tra partizioni.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.

Passaggi successiviNext steps

Per disconnettere o riconnettere una partizione, vedere Uso della classe RecoveryManager per correggere i problemi delle mappe partizioniTo detach a shard, or to reattach a shard, see Using the RecoveryManager class to fix shard map problems

Risorse aggiuntiveAdditional resources

Se non si usano gli strumenti di database elastici,Not using elastic database tools yet? vedere la Guida introduttiva.Check out our Getting Started Guide. Se ci sono domande, è possibile visitare il forum sul database SQL mentre è possibile inserire le richieste di nuove funzionalità nel forum relativo a commenti e suggerimenti sul database SQL.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.