Kierowanie zapytania do odpowiedniej bazy danych przy użyciu routingu zależnego od danych

Dotyczy:Azure SQL Database

Routing zależny od danych to możliwość użycia danych w zapytaniu w celu kierowania żądania do odpowiedniej bazy danych. Routing zależny od danych jest podstawowym wzorcem podczas pracy z bazami danych podzielonymi na fragmenty. Kontekst żądania może być również używany do kierowania żądania, zwłaszcza jeśli klucz fragmentowania nie jest częścią zapytania. Każde konkretne zapytanie lub transakcja w aplikacji korzystające z routingu zależnego od danych jest ograniczone do uzyskiwania dostępu do jednej bazy danych na żądanie. W przypadku narzędzi elastycznych usługi Azure SQL Database ten routing odbywa się za pomocą klasy ShardMapManager (Java, .NET).

Aplikacja nie musi śledzić różnych parametry połączenia ani lokalizacji bazy danych skojarzonych z różnymi fragmentami danych w środowisku podzielonym na fragmenty. Zamiast tego Menedżer map fragmentów otwiera połączenia z odpowiednimi bazami danych w razie potrzeby na podstawie danych na mapie fragmentów i wartości klucza fragmentowania, który jest obiektem docelowym żądania aplikacji. Kluczem jest zazwyczaj customer_id, tenant_id, date_key lub inny konkretny identyfikator, który jest podstawowym parametrem żądania bazy danych.

Aby uzyskać więcej informacji, zobacz Skalowanie w poziomie programu SQL Server przy użyciu routingu zależnego od danych.

Pobieranie biblioteki klienta

Aby pobrać:

Używanie elementu ShardMapManager w aplikacji routingu zależnego od danych

Aplikacje powinny utworzyć wystąpienie elementu ShardMapManager podczas inicjowania przy użyciu wywołania fabrycznego GetSQLShardMapManager (Java, .NET). W tym przykładzie zainicjowano zarówno element ShardMapManager , jak i konkretną mapę fragmentów , którą zawiera. W tym przykładzie przedstawiono metody GetSqlShardMapManager i 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"); 

Uzyskiwanie mapy fragmentów przy użyciu poświadczeń o najniższych uprawnieniach

Jeśli aplikacja nie manipuluje samą mapą fragmentów, poświadczenia używane w metodzie fabryki powinny mieć uprawnienia tylko do odczytu w globalnej bazie danych map fragmentów. Te poświadczenia są zwykle inne niż poświadczenia używane do otwierania połączeń z menedżerem mapy fragmentów. Zobacz również Poświadczenia używane do uzyskiwania dostępu do biblioteki klienta elastycznej bazy danych.

Wywoływanie metody Open Połączenie ionForKey

Metoda ShardMap.Open Połączenie ionForKey (Java, .NET) zwraca połączenie gotowe do wydawania poleceń do odpowiedniej bazy danych na podstawie wartości parametru klucza. Informacje o fragmentach są buforowane w aplikacji przez narzędzie ShardMapManager, więc te żądania zwykle nie obejmują wyszukiwania bazy danych względem globalnej bazy danych map fragmentów.

// Syntax:
public Connection openConnectionForKey(Object key, String connectionString, ConnectionOptions options)
// Syntax:
public SqlConnection OpenConnectionForKey<TKey>(TKey key, string connectionString, ConnectionOptions options)
  • Parametr klucza jest używany jako klucz odnośnika do mapy fragmentów w celu określenia odpowiedniej bazy danych dla żądania.
  • Parametr connectionString służy do przekazywania tylko poświadczeń użytkownika dla żądanego połączenia. W tym parametrze connectionString nie ma nazwy bazy danych ani nazwy serwera, ponieważ metoda określa bazę danych i serwer przy użyciu elementu ShardMap.
  • Parametr connectionOptions (Java, .NET) powinien być ustawiony na Połączenie ionOptions.Validate, czy środowisko, w którym mapy fragmentów mogą ulec zmianie, a wiersze mogą zostać przeniesione do innych baz danych w wyniku operacji dzielenia lub scalania. Ta walidacja obejmuje krótkie zapytanie do lokalnej mapy fragmentów w docelowej bazie danych (nie do globalnej mapy fragmentów) przed dostarczeniem połączenia do aplikacji.

Jeśli walidacja względem lokalnej mapy fragmentów nie powiedzie się (wskazująca, że pamięć podręczna jest niepoprawna), Menedżer map fragmentów fragmentów wysyła zapytanie do globalnej mapy fragmentów, aby uzyskać nową poprawną wartość wyszukiwania, zaktualizować pamięć podręczną i uzyskać i zwrócić odpowiednie połączenie z bazą danych.

Użyj Połączenie ionOptions.None tylko wtedy, gdy zmiany mapowania fragmentów nie są oczekiwane, gdy aplikacja jest w trybie online. W takim przypadku można założyć, że buforowane wartości są zawsze poprawne, a dodatkowe wywołanie weryfikacji rundy do docelowej bazy danych można bezpiecznie pominąć. Zmniejsza to ruch bazy danych. Parametr connectionOptions można również ustawić za pośrednictwem wartości w pliku konfiguracji, aby wskazać, czy zmiany fragmentowania są oczekiwane, czy nie w danym okresie.

W tym przykładzie użyto wartości klucza całkowitego CustomerID przy użyciu obiektu ShardMap o nazwie 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();
}  

Metoda Open Połączenie ionForKey zwraca nowe już otwarte połączenie z poprawną bazą danych. Połączenie iony wykorzystywane w ten sposób nadal korzystają z pełnej puli połączeń.

Metoda Open Połączenie ionForKeyAsync (Java, .NET) jest również dostępna, jeśli aplikacja używa programowania asynchronicznego.

Integracja z obsługą błędów przejściowych

Najlepszym rozwiązaniem w tworzeniu aplikacji dostępu do danych w chmurze jest zapewnienie, że błędy przejściowe są przechwytywane przez aplikację i że operacje są ponawiane kilka razy przed zgłoszeniem błędu. Obsługa błędów przejściowych dla aplikacji w chmurze została omówiona w temacie Transient Fault Handling (Java, .NET).

Obsługa błędów przejściowych może współistnieć naturalnie ze wzorcem routingu zależnego od danych. Kluczowym wymaganiem jest ponowienie próby całego żądania dostępu do danych, w tym bloku używającego , który uzyskał połączenie routingu zależnego od danych. Powyższy przykład może zostać przepisany w następujący sposób.

Przykład — routing zależny od danych z obsługą błędów przejściowych

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

Pakiety niezbędne do zaimplementowania obsługi błędów przejściowych są pobierane automatycznie podczas kompilowania przykładowej aplikacji elastycznej bazy danych.

Spójność transakcyjna

Właściwości transakcyjne są gwarantowane dla wszystkich operacji lokalnych do fragmentu. Na przykład transakcje przesyłane za pośrednictwem routingu zależnego od danych są wykonywane w zakresie docelowego fragmentu dla połączenia. W tej chwili nie ma dostępnych możliwości wprowadzania wielu połączeń do transakcji i dlatego nie ma gwarancji transakcyjnych dla operacji wykonywanych między fragmentami.

Następne kroki

Aby odłączyć fragment lub ponownie dołączyć fragment, zobacz Rozwiązywanie problemów z mapą fragmentu przy użyciu klasy RecoveryManager.

Dodatkowe zasoby

Jeszcze nie korzystasz z narzędzi elastycznych baz danych? Zapoznaj się z naszym przewodnikiem Wprowadzenie. W przypadku pytań skontaktuj się z nami na stronie pytań i odpowiedzi dotyczących usługi SQL Database oraz w przypadku żądań funkcji, dodaj nowe pomysły lub zagłosuj na istniejące pomysły na forum opinii usługi SQL Database.