Udostępnij za pośrednictwem


Skalowanie baz danych w poziomie za pomocą menedżera mapy fragmentów

Dotyczy: Azure SQL Database

Aby łatwo skalować bazy danych w poziomie w usłudze Azure SQL Database, użyj menedżera map fragmentów. Menedżer map fragmentów to specjalna baza danych, która przechowuje globalne informacje o mapowaniu wszystkich fragmentów (baz danych) w zestawie fragmentów. Metadane umożliwiają aplikacji łączenie się z poprawną bazą danych na podstawie wartości klucza fragmentowania. Ponadto każdy fragment w zestawie zawiera mapy, które śledzą lokalne dane fragmentów (nazywane fragmentami).

Zarządzanie mapami fragmentów

Zrozumienie sposobu konstruowania tych map jest niezbędne do zarządzania mapami fragmentów. Odbywa się to przy użyciu klasy ShardMapManager (Java, .NET) znajdującej się w bibliotece klienta elastic database w celu zarządzania mapami fragmentów.

Mapy fragmentów i mapowania fragmentów

Dla każdego fragmentu należy wybrać typ mapy fragmentów do utworzenia. Wybór zależy od architektury bazy danych:

  1. Pojedyncza dzierżawa na bazę danych
  2. Wiele dzierżaw na bazę danych (dwa typy):
    1. Mapowanie listy
    2. Mapowanie zakresu

W przypadku modelu z jedną dzierżawą utwórz mapę fragmentów mapowania listy. Model z jedną dzierżawą przypisuje jedną bazę danych na dzierżawę. Jest to skuteczny model dla deweloperów SaaS, ponieważ upraszcza zarządzanie mapami fragmentów.

Mapowanie listy

Model wielodostępny przypisuje kilka dzierżaw do pojedynczej bazy danych (i można dystrybuować grupy dzierżaw w wielu bazach danych). Użyj tego modelu, gdy oczekujesz, że każda dzierżawa będzie miała niewielkie potrzeby dotyczące danych. W tym modelu przypisz zakres dzierżaw do bazy danych przy użyciu mapowania zakresu.

Mapowanie zakresu

Możesz też zaimplementować model wielodostępnej bazy danych przy użyciu mapowania listy w celu przypisania wielu dzierżaw do pojedynczej bazy danych. Na przykład baza danych DB1 służy do przechowywania informacji o identyfikatorze dzierżawy 1 i 5, a baza danych DB2 przechowuje dane dla dzierżawy 7 i dzierżawy 10.

Wiele dzierżaw w pojedynczej bazie danych

Obsługiwane typy kluczy fragmentowania

Elastyczna skala obsługuje następujące typy jako klucze fragmentowania:

.NET Java
integer integer
długi długi
Identyfikator GUID uuid
byte[] byte[]
datetime timestamp
zakres czasu czas trwania
datetimeoffset offsetdatetime

Mapy list i zakresów fragmentów

Mapy fragmentów można tworzyć przy użyciu list poszczególnych wartości klucza fragmentowania lub można je tworzyć przy użyciu zakresów wartości klucza fragmentowania.

Mapy fragmentów listy

Fragmenty zawierają fragmenty, a mapowanie fragmentów na fragmenty jest obsługiwane przez mapę fragmentów. Mapa fragmentów listy to skojarzenie między poszczególnymi wartościami kluczy, które identyfikują podfragmenty i bazy danych, które służą jako fragmenty. Mapowania list są jawne i różne wartości kluczy można mapować na tę samą bazę danych. Na przykład wartość klucza 1 mapuje na bazę danych A, a wartości klucza 3 i 6 mapuje na bazę danych B.

Klucz Lokalizacja fragmentu
1 Database_A
3 Database_B
100 Database_C
6 Database_B
... ...

Mapy fragmentów zakresu

Na mapie fragmentów zakresu zakres kluczy jest opisywany przez parę [Niska wartość, Wartość wysoka), gdzie wartość niska jest kluczem minimalnym w zakresie, a wartość wysoka jest pierwszą wartością wyższą niż zakres.

Na przykład [0, 100) zawiera wszystkie liczby całkowite większe lub równe 0 i mniejsze niż 100. Należy pamiętać, że wiele zakresów może wskazywać tę samą bazę danych, a rozłączne zakresy są obsługiwane (na przykład [100 200) i [400 600) wskazują bazę danych C w poniższym przykładzie).

Klucz Lokalizacja fragmentu
[1,50) Database_A
[50,100) Database_B
[100,200) Database_C
[400,600) Database_C
... ...

Każda z powyższych tabel jest przykładem koncepcyjnym obiektu ShardMap . Każdy wiersz jest uproszczonym przykładem pojedynczego obiektu PointMapping (dla mapy fragmentów listy) lub RangeMapping (dla mapy fragmentów zakresu).

Menedżer map fragmentów

W bibliotece klienta menedżer map fragmentów jest kolekcją map fragmentów. Dane zarządzane przez wystąpienie ShardMapManager są przechowywane w trzech miejscach:

  1. Globalna mapa fragmentów (GSM): należy określić bazę danych, która będzie służyć jako repozytorium dla wszystkich map i mapowań fragmentów. Specjalne tabele i procedury składowane są tworzone automatycznie w celu zarządzania informacjami. Jest to zazwyczaj mała baza danych i lekko uzyskiwany dostęp i nie powinna być używana w innych potrzebach aplikacji. Tabele znajdują się w specjalnym schemacie o nazwie __ShardManagement.
  2. Lokalna mapa fragmentów (LSM): każda określona baza danych, która ma być fragmentem, jest modyfikowana tak, aby zawierała kilka małych tabel i specjalnych procedur składowanych zawierających informacje mapy fragmentów specyficzne dla tego fragmentu i zarządzać nimi. Te informacje są nadmiarowe z informacjami w GSM i umożliwiają aplikacji weryfikowanie buforowanych informacji mapy fragmentów bez umieszczenia żadnego obciążenia na GSM; aplikacja używa maszyny LSM do określenia, czy mapowanie buforowane jest nadal prawidłowe. Tabele odpowiadające LSM dla każdego fragmentu znajdują się również w __ShardManagement schematu.
  3. Pamięć podręczna aplikacji: każde wystąpienie aplikacji, które uzyskuje dostęp do obiektu ShardMapManager , przechowuje lokalną pamięć podręczną w pamięci mapowań. Przechowuje informacje o routingu, które zostały ostatnio pobrane.

Konstruowanie elementu ShardMapManager

Obiekt ShardMapManager jest konstruowany przy użyciu wzorca fabryki (Java, .NET). Metoda ShardMapManagerFactory.GetSqlShardMapManager (Java, .NET) przyjmuje poświadczenia (w tym nazwę serwera i nazwę bazy danych przechowującą gsm) w postaci elementu ConnectionString i zwraca wystąpienie elementu ShardMapManager.

Uwaga: Element ShardMapManager powinien zostać utworzone tylko raz na domenę aplikacji w kodzie inicjowania aplikacji. Utworzenie dodatkowych wystąpień narzędzia ShardMapManager w tej samej domenie aplikacji powoduje zwiększenie wykorzystania pamięci i procesora CPU aplikacji. Element ShardMapManager może zawierać dowolną liczbę map fragmentów. Chociaż pojedyncza mapa fragmentów może być wystarczająca dla wielu aplikacji, czasami różne zestawy baz danych są używane do różnych schematów lub do unikatowych celów; w takich przypadkach preferowane może być wiele map fragmentów.

W tym kodzie aplikacja próbuje otworzyć istniejący element ShardMapManager za pomocą metody TryGetSqlShardMapManager (Java, .NET ). Jeśli obiekty reprezentujące globalną elementy ShardMapManager (GSM) nie istnieją jeszcze w bazie danych, biblioteka kliencka tworzy je przy użyciu metody CreateSqlShardMapManager (Java, .NET).

// Try to get a reference to the Shard Map Manager in the shardMapManager database.
// If it doesn't already exist, then create it.
ShardMapManager shardMapManager = null;
boolean shardMapManagerExists = ShardMapManagerFactory.tryGetSqlShardMapManager(shardMapManagerConnectionString,ShardMapManagerLoadPolicy.Lazy, refShardMapManager);
shardMapManager = refShardMapManager.argValue;

if (shardMapManagerExists) {
    ConsoleUtils.writeInfo("Shard Map %s already exists", shardMapManager);
}
else {
    // The Shard Map Manager does not exist, so create it
    shardMapManager = ShardMapManagerFactory.createSqlShardMapManager(shardMapManagerConnectionString);
    ConsoleUtils.writeInfo("Created Shard Map %s", shardMapManager);
}
// Try to get a reference to the Shard Map Manager via the Shard Map Manager database.  
// If it doesn't already exist, then create it.
ShardMapManager shardMapManager;
bool shardMapManagerExists = ShardMapManagerFactory.TryGetSqlShardMapManager(
                                        connectionString,
                                        ShardMapManagerLoadPolicy.Lazy,
                                        out shardMapManager);

if (shardMapManagerExists)
{
    Console.WriteLine("Shard Map Manager already exists");
}
else
{
    // Create the Shard Map Manager.
    ShardMapManagerFactory.CreateSqlShardMapManager(connectionString);
    Console.WriteLine("Created SqlShardMapManager");

    shardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
            connectionString,
            ShardMapManagerLoadPolicy.Lazy);

// The connectionString contains server name, database name, and admin credentials for privileges on both the GSM and the shards themselves.
}

W przypadku wersji platformy .NET możesz użyć programu PowerShell do utworzenia nowego Menedżera map fragmentów.

Pobieranie elementu RangeShardMap lub ListShardMap

Po utworzeniu menedżera mapy fragmentów można pobrać mapę RangeShardMap (Java, .NET) lub ListShardMap (Java, .NET) przy użyciu metody TryGetRangeShardMap (Java, .NET), TryGetListShardMap (Java, .NET) lub GetShardMap (Java, .NET).

// Creates a new Range Shard Map with the specified name, or gets the Range Shard Map if it already exists.
static <T> RangeShardMap<T> createOrGetRangeShardMap(ShardMapManager shardMapManager,
            String shardMapName,
            ShardKeyType keyType) {
    // Try to get a reference to the Shard Map.
    ReferenceObjectHelper<RangeShardMap<T>> refRangeShardMap = new ReferenceObjectHelper<>(null);
    boolean isGetSuccess = shardMapManager.tryGetRangeShardMap(shardMapName, keyType, refRangeShardMap);
    RangeShardMap<T> shardMap = refRangeShardMap.argValue;

    if (isGetSuccess && shardMap != null) {
        ConsoleUtils.writeInfo("Shard Map %1$s already exists", shardMap.getName());
    }
    else {
        // The Shard Map does not exist, so create it
        try {
            shardMap = shardMapManager.createRangeShardMap(shardMapName, keyType);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        ConsoleUtils.writeInfo("Created Shard Map %1$s", shardMap.getName());
    }

    return shardMap;
}
// Creates a new Range Shard Map with the specified name, or gets the Range Shard Map if it already exists.
public static RangeShardMap<T> CreateOrGetRangeShardMap<T>(ShardMapManager shardMapManager, string shardMapName)
{
    // Try to get a reference to the Shard Map.
    RangeShardMap<T> shardMap;
    bool shardMapExists = shardMapManager.TryGetRangeShardMap(shardMapName, out shardMap);

    if (shardMapExists)
    {
        ConsoleUtils.WriteInfo("Shard Map {0} already exists", shardMap.Name);
    }
    else
    {
        // The Shard Map does not exist, so create it
        shardMap = shardMapManager.CreateRangeShardMap<T>(shardMapName);
        ConsoleUtils.WriteInfo("Created Shard Map {0}", shardMap.Name);
    }

    return shardMap;
}

Poświadczenia administracyjne mapy fragmentów

Aplikacje, które zarządzają mapami fragmentów i manipulują nimi, różnią się od tych, które używają map fragmentów do kierowania połączeń.

Aby administrować mapami fragmentów (dodawać lub zmieniać fragmenty, mapy fragmentów, mapowania fragmentów itp.) należy utworzyć wystąpienie elementu ShardMapManager przy użyciu poświadczeń, które mają uprawnienia odczytu/zapisu zarówno w bazie danych GSM, jak i w każdej bazie danych, która służy jako fragment. Poświadczenia muszą zezwalać na zapisy względem tabel zarówno w gsm, jak i LSM, ponieważ informacje o mapie fragmentów są wprowadzane lub zmieniane, a także do tworzenia tabel LSM na nowych fragmentach.

Zobacz Poświadczenia używane do uzyskiwania dostępu do biblioteki klienta elastycznej bazy danych.

Dotyczy to tylko metadanych

Metody używane do wypełniania lub zmieniania danych ShardMapManager nie zmieniają danych użytkownika przechowywanych w samych fragmentach. Na przykład metody, takie jak CreateShard, DeleteShard, UpdateMapping itp., mają wpływ tylko na metadane mapy fragmentów. Nie usuwają, dodawają ani nie zmieniają danych użytkownika zawartych w fragmentach. Zamiast tego te metody są przeznaczone do użycia w połączeniu z oddzielnymi operacjami wykonywanymi w celu utworzenia lub usunięcia rzeczywistych baz danych albo przenoszenia wierszy z jednego fragmentu do drugiego w celu ponownego zrównoważenia środowiska podzielonego na fragmenty. (Narzędzie do dzielenia scalania dołączone do narzędzi elastycznej bazy danych korzysta z tych interfejsów API wraz z organizowaniem rzeczywistego przenoszenia danych między fragmentami). Zobacz Scaling using the Elastic Database split-merge tool (Skalowanie przy użyciu narzędzia do dzielenia i scalania elastycznej bazy danych).

Routing zależny od danych

Menedżer map fragmentów jest używany w aplikacjach, które wymagają połączeń bazy danych w celu wykonywania operacji danych specyficznych dla aplikacji. Te połączenia muszą być skojarzone z poprawną bazą danych. Jest to nazywane routingiem zależnym od danych. W przypadku tych aplikacji utwórz wystąpienie obiektu menedżera map fragmentów z fabryki przy użyciu poświadczeń, które mają dostęp tylko do odczytu w bazie danych GSM. Pojedyncze żądania dla późniejszych połączeń dostarczają poświadczenia niezbędne do nawiązania połączenia z odpowiednią bazą danych fragmentów.

Należy pamiętać, że te aplikacje (przy użyciu narzędzia ShardMapManager otwarte z poświadczeniami tylko do odczytu) nie mogą wprowadzać zmian w mapach lub mapowaniach. W przypadku tych potrzeb utwórz aplikacje specyficzne dla administratora lub skrypty programu PowerShell, które dostarczają poświadczenia uprzywilejowane zgodnie z wcześniejszym opisem. Zobacz Poświadczenia używane do uzyskiwania dostępu do biblioteki klienta elastycznej bazy danych.

Aby uzyskać więcej informacji, zobacz Routing zależny od danych.

Modyfikowanie mapy fragmentów

Mapa fragmentów może być zmieniana na różne sposoby. Wszystkie poniższe metody modyfikują metadane opisujące fragmenty i ich mapowania, ale nie modyfikują fizycznie danych w fragmentach ani nie tworzą ani nie usuwają rzeczywistych baz danych. Niektóre operacje na mapie fragmentów opisanej poniżej mogą wymagać koordynacji z akcjami administracyjnymi, które fizycznie przenoszą dane lub dodają i usuwają bazy danych obsługujące jako fragmenty.

Te metody współpracują ze sobą jako bloki konstrukcyjne dostępne do modyfikowania ogólnej dystrybucji danych w środowisku bazy danych podzielonych na fragmenty.

  • Aby dodać lub usunąć fragmenty: użyj klasy CreateShard (Java, .NET) i DeleteShard (Java, .NET) z klasy shardmap (Java, .NET).

    Serwer i baza danych reprezentująca docelowy fragment muszą już istnieć, aby te operacje były wykonywane. Te metody nie mają żadnego wpływu na same bazy danych, tylko na metadane na mapie fragmentów.

  • Aby utworzyć lub usunąć punkty lub zakresy mapowane na fragmenty: użyj metody CreateRangeMapping (Java, .NET), DeleteMapping (Java, .NET) klasy RangeShardMapping (Java, .NET) i createPointMapping (Java, .NET) klasy ListShardMapMap (Java, .NET).

    Wiele różnych punktów lub zakresów można mapować na ten sam fragment. Te metody mają wpływ tylko na metadane — nie mają wpływu na żadne dane, które mogą być już obecne w fragmentach. Jeśli dane muszą zostać usunięte z bazy danych w celu zapewnienia spójności z operacjami DeleteMapping , należy wykonać te operacje oddzielnie, ale w połączeniu z użyciem tych metod.

  • Aby podzielić istniejące zakresy na dwa lub scalić sąsiadujące zakresy na jeden: użyj funkcji SplitMapping (Java, .NET) i MergeMappings (Java, .NET).

    Należy pamiętać, że operacje dzielenia i scalania nie zmieniają fragmentu, na który są mapowane wartości kluczy. Podział dzieli istniejący zakres na dwie części, ale pozostawia oba jako zamapowane na ten sam fragment. Scalanie działa na dwóch sąsiednich zakresach, które są już mapowane na ten sam fragment, łącząc je w jeden zakres. Ruch punktów lub zakresów między fragmentami musi być skoordynowany przy użyciu funkcji UpdateMapping w połączeniu z rzeczywistym przenoszeniem danych. Możesz użyć usługi Split/Merge , która jest częścią narzędzi elastycznej bazy danych, aby koordynować zmiany mapy fragmentów z przenoszeniem danych, gdy jest to konieczne.

  • Aby ponownie mapować (lub przenosić) poszczególne punkty lub zakresy do różnych fragmentów: użyj funkcji UpdateMapping (Java, .NET).

    Ponieważ dane mogą być przenoszone z jednego fragmentu do innego w celu zapewnienia spójności z operacjami UpdateMapping , należy wykonać ten ruch oddzielnie, ale w połączeniu z użyciem tych metod.

  • Aby przejąć mapowania w trybie online i offline: użyj języka MarkMappingOffline (Java, .NET) i markMappingOnline (Java, .NET), aby kontrolować stan online mapowania.

    Niektóre operacje na mapowaniach fragmentów są dozwolone tylko wtedy, gdy mapowanie jest w stanie offline , w tym UpdateMapping i DeleteMapping. Gdy mapowanie jest w trybie offline, żądanie zależne od danych na podstawie klucza uwzględnionego w tym mapowaniu zwraca błąd. Ponadto po pierwszym przełączeniu zakresu do trybu offline wszystkie połączenia z dotkniętym fragmentem są automatycznie zabijane, aby zapobiec niespójnym lub niekompletnym wynikom zapytań kierowanych do zakresów.

Mapowania są niezmiennymi obiektami na platformie .NET. Wszystkie powyższe metody, które zmieniają mapowania, również unieważniają wszystkie odwołania do nich w kodzie. Aby ułatwić wykonywanie sekwencji operacji, które zmieniają stan mapowania, wszystkie metody, które zmieniają mapowanie, zwracają nowe odwołanie mapowania, dzięki czemu operacje mogą być łańcuchowe. Aby na przykład usunąć istniejące mapowanie w mapie fragmentów sm zawierającej klucz 25, można wykonać następujące czynności:

    sm.DeleteMapping(sm.MarkMappingOffline(sm.GetMappingForKey(25)));

Dodawanie fragmentu

Aplikacje często muszą dodawać nowe fragmenty do obsługi danych oczekiwanych z nowych kluczy lub zakresów kluczy dla mapy fragmentów, która już istnieje. Na przykład aplikacja podzielone na fragmenty według identyfikatora dzierżawy może wymagać aprowizacji nowego fragmentu dla nowej dzierżawy lub co miesiąc podzielone na fragmenty dane mogą wymagać nowej aprowizacji fragmentu przed rozpoczęciem każdego nowego miesiąca.

Jeśli nowy zakres wartości klucza nie jest już częścią istniejącego mapowania i nie jest konieczne przenoszenie danych, wystarczy dodać nowy fragment i skojarzyć nowy klucz lub zakres z tym fragmentem. Aby uzyskać szczegółowe informacje na temat dodawania nowych fragmentów, zobacz Dodawanie nowego fragmentu.

W scenariuszach wymagających przenoszenia danych potrzebne jest jednak narzędzie do dzielenia scalania w celu organizowania przenoszenia danych między fragmentami w połączeniu z niezbędnymi aktualizacjami mapy fragmentów. Aby uzyskać szczegółowe informacje na temat korzystania z narzędzia split-merge, zobacz Overview of split-merge (Omówienie dzielenia scalania)

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.