Delen via


Gegevensafhankelijke routering gebruiken om een query naar een geschikte database te routeren

Van toepassing op:Azure SQL Database

Gegevensafhankelijke routering is de mogelijkheid om de gegevens in een query te gebruiken om de aanvraag naar een geschikte database te routeren. Gegevensafhankelijke routering is een fundamenteel patroon bij het werken met shard-databases. De aanvraagcontext kan ook worden gebruikt om de aanvraag te routeren, met name als de shardingsleutel geen deel uitmaakt van de query. Elke specifieke query of transactie in een toepassing die gegevensafhankelijke routering gebruikt, is beperkt tot toegang tot één database per aanvraag. Voor de elastische hulpprogramma's van Azure SQL Database wordt deze routering uitgevoerd met de ShardMapManager klasse (Java, .NET).

De toepassing hoeft geen verschillende verbindingsreeksen of DB-locaties bij te houden die zijn gekoppeld aan verschillende segmenten gegevens in de shard-omgeving. In plaats daarvan opent de scale-outdatabases met het shard-toewijzingsbeheer verbindingen met de juiste databases wanneer dat nodig is, op basis van de gegevens in de shard-toewijzing en de waarde van de shardingsleutel die het doel is van de aanvraag van de toepassing. De sleutel is doorgaans de customer_id, tenant_id, date_key of een andere specifieke id die een fundamentele parameter van de databaseaanvraag is.

Zie SQL Server uitschalen met Data-Dependent Routering voor meer informatie.

De clientbibliotheek downloaden

Downloaden:

Een ShardMapManager gebruiken in een gegevensafhankelijke routeringstoepassing

Toepassingen moeten tijdens het initialisatieproces de ShardMapManager instantiëren met behulp van de factory-aanroep GetSQLShardMapManager (Java, .NET). In dit voorbeeld worden zowel een ShardMapManager als een specifieke ShardMap dat het bevat geïnitialiseerd. In dit voorbeeld ziet u de methoden GetSqlShardMapManager en GetRangeShardMap (Java, .NET).

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

Gebruik inloggegevens met de laagste mogelijke bevoegdheden voor het verkrijgen van de shard map

Als een toepassing de shardmap zelf niet bewerkt, moeten de referenties die in de factory method worden gebruikt, alleen-lezenmachtigingen hebben voor de Globale Shardmap database. Deze referenties verschillen doorgaans van de referenties die worden gebruikt om verbindingen met de beheerder van de shard-kaart te openen. Zie ook referenties die worden gebruikt voor toegang tot de elastic database-clientbibliotheek.

De methode OpenConnectionForKey aanroepen

De ShardMap.OpenConnectionForKey methode (Java, .NET) retourneert een verbinding die gereed is voor het uitgeven van opdrachten naar de juiste database op basis van de waarde van de key parameter. Shard-gegevens worden in de toepassing door de ShardMapManager in de cache opgeslagen, zodat deze aanvragen meestal geen databasezoekactie tegen de Global Shard Map-database vereisen.

// Syntax:
public Connection openConnectionForKey(Object key, String connectionString, ConnectionOptions options)
// Syntax:
public SqlConnection OpenConnectionForKey<TKey>(TKey key, string connectionString, ConnectionOptions options)
  • De key-parameter wordt gebruikt als zoeksleutel in de shardkaart om de juiste database voor het verzoek te bepalen.
  • De connectionString wordt gebruikt om alleen de gebruikersreferenties voor de gewenste verbinding door te geven. Er is geen databasenaam of servernaam opgenomen in deze connectionString omdat de methode de database en server bepaalt met behulp van de ShardMapmethode.
  • De connectionOptions (Java, .NET) moet worden ingesteld op ConnectionOptions.Validate als een omgeving waarin shard-kaarten kunnen wijzigen en rijen als gevolg van split- of mergebewerkingen naar andere databases kunnen worden verplaatst. Deze validatie omvat een korte query naar de lokale shard-kaart op de database van de bestemming (niet naar de globale shard-kaart) voordat de connectie aan de applicatie wordt aangeboden.

Als de validatie voor de lokale shard map mislukt (wat aangeeft dat de cache onjuist is), voert de Shard Map Manager een query uit op de globale shard map om de nieuwe juiste waarde voor de zoekactie te verkrijgen, de cache bij te werken, en de juiste databaseverbinding te verkrijgen en terug te geven.

Gebruik ConnectionOptions.None alleen wanneer geen wijzigingen in de shardtoewijzing worden verwacht terwijl een applicatie online is. In dat geval kunnen de waarden in de cache worden verondersteld altijd correct te zijn en kan de extra retourvalidatieaanroep naar de doeldatabase veilig worden overgeslagen. Dit vermindert het databaseverkeer. De connectionOptions waarde kan ook worden ingesteld via een waarde in een configuratiebestand om aan te geven of er al dan niet shardingswijzigingen worden verwacht gedurende een bepaalde periode.

In dit voorbeeld wordt de waarde van een gehele getalsleutel CustomerIDgebruikt met behulp van een ShardMap object met de naam 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();
}  

De OpenConnectionForKey methode retourneert een nieuwe, al geopende verbinding met de juiste database. Verbindingen die op deze manier worden gebruikt, profiteren nog steeds optimaal van groepsgewijze verbindingen.

De OpenConnectionForKeyAsync methode (Java, .NET) is ook beschikbaar als uw toepassing asynchrone programmering gebruikt.

Integreren met tijdelijke foutafhandeling

Een best practice bij het ontwikkelen van toepassingen voor gegevenstoegang in de cloud is ervoor te zorgen dat tijdelijke fouten door de app worden onderschept en dat de bewerkingen meerdere keren opnieuw worden geprobeerd voordat er een fout wordt gegenereerd. Tijdelijke foutafhandeling voor cloudtoepassingen wordt besproken bij Transient Fault Handling (Java, .NET).

Tijdelijke foutafhandeling kan op een natuurlijke manier samen bestaan met het Data-Dependent-routeringspatroon. De belangrijkste vereiste is om de volledige aanvraag voor gegevenstoegang opnieuw uit te voeren, inclusief het gebruiksblok dat de gegevensafhankelijke routeringsverbinding heeft verkregen. Het voorgaande voorbeeld kan als volgt worden herschreven.

Voorbeeld: gegevensafhankelijke routering met tijdelijke foutafhandeling

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

Pakketten die nodig zijn om tijdelijke foutafhandeling te implementeren, worden automatisch gedownload wanneer u de voorbeeldtoepassing voor elastische databases bouwt.

Transactionele consistentie

Transactionele eigenschappen worden gegarandeerd voor alle bewerkingen lokaal voor een shard. Transacties die worden verzonden via gegevensafhankelijke routering, worden bijvoorbeeld uitgevoerd binnen het bereik van de doelshard voor de verbinding. Op dit moment zijn er geen mogelijkheden beschikbaar voor het inschakelen van meerdere verbindingen in een transactie en daarom zijn er geen transactionele garanties voor bewerkingen die worden uitgevoerd in shards.

Volgende stap

Gebruikt u nog geen hulpprogramma's voor elastische databases? Bekijk onze Aan de slag-handleiding. Neem voor vragen contact met ons op op de Microsoft Q&A-vragenpagina voor SQL Database en voor functieaanvragen, voeg nieuwe ideeën toe of stem op bestaande ideeën in het SQL Database-feedbackforum.