Sdílet prostřednictvím


Škálování databází pomocí správce mapy shardů

Platí pro:Azure SQL databáze

K snadnému škálování databází ve službě Azure SQL Database použijte správce oddílů. Správce mapování shardů je speciální databáze, která udržuje globální mapové informace o všech shardech (databázích) v sadě shardů. Metadata umožňuje aplikaci připojit se ke správné databázi na základě hodnoty shardovacího klíče. Kromě toho každý horizontální oddíl v sadě obsahuje mapy, které sledují místní data horizontálních oddílů (označovaná jako shardlety).

Správa mapy shardů

Pochopení konstrukce těchto map je nezbytné pro správu map fragmentů. To se provádí pomocí třídy ShardMapManager (Java, .NET), která se nachází v klientské knihovně elastické databáze ke správě map horizontálních oddílů.

Mapy fragmentů a mapování fragmentů

U každého datového fragmentu musíte vybrat typ mapy fragmentů, který chcete vytvořit. Volba závisí na architektuře databáze:

  1. Jeden tenant na jedné databázi
  2. Více tenantů v databázi (dva typy):
    1. Mapování seznamu
    2. Mapování rozsahu

Pro model s jedním nájemcem vytvořte shard mapu pro mapování seznamů. Model s jedním tenantem přiřazuje jednu databázi na tenanta. Jedná se o efektivní model pro vývojáře SaaS, protože zjednodušuje správu shardových map.

Mapování seznamu

Model s více tenanty přiřazuje jednotlivým databázím několik tenantů (a můžete distribuovat skupiny tenantů napříč několika databázemi). Tento model použijte, pokud očekáváte, že každý tenant bude potřebovat malá data. V tomto modelu přiřaďte k databázi rozsah tenantů pomocí mapování rozsahu.

Mapování rozsahu

Nebo můžete implementovat model databáze s více tenanty pomocí mapování seznamu pro přiřazení více tenantů k jednotlivým databázím. Db1 se například používá k ukládání informací o ID tenanta 1 a 5 a DB2 ukládá data pro tenanta 7 a tenanta 10.

Více tenantů v jedné databázi

Podporované typy klíčů horizontálního dělení

Elastic Scale podporuje následující typy jako klíče horizontálního dělení:

.NET Java
integer integer
dlouhý dlouhý
globálně unikátní identifikátor (GUID) Uuid
byte[] byte[]
datum a čas časové razítko
časový úsek doba trvání
datetimeoffset offsetdatetime

Mapy rozdělení seznamu a rozsahu

Shard maps lze vytvořit pomocí seznamů jednotlivých hodnot klíče pro dělení, nebo pomocí rozsahů hodnot klíče pro dělení.

Seznam fragmentačních map

Shardy obsahují shardlety a mapování shardletů na shardy se udržuje pomocí shardové mapy. Mapa horizontálních oddílů seznamu je přidružení mezi hodnotami jednotlivých klíčů, které identifikují shardlety a databáze, které slouží jako horizontální oddíly. Mapování seznamů jsou explicitní a různé klíčové hodnoty lze mapovat na stejnou databázi. Například hodnota klíče 1 se mapuje na databázi A a hodnoty klíče 3 a 6 se mapuje na databázi B.

Klíč Umístění fragmentu
1 Databáze_A
3 Database_B
4 Database_C
6 Database_B
... ...

Mapy fragmentů rozsahu

V mapě rozsahu horizontálních částí je rozsah klíčů popsán dvojicí [Nízká hodnota, Vysoká hodnota), kde Nízká hodnota je minimální klíč v rozsahu a Vysoká hodnota je první hodnota vyšší než rozsah.

Například [0, 100) obsahuje všechna celá čísla větší nebo rovna 0 a menší než 100. Všimněte si, že více oblastí může odkazovat na stejnou databázi, a jsou podporovány nesouvislé oblasti (například [100,200) a [400,600), které obě odkazují na databázi C v následujícím příkladu.)

Klíč Umístění shardu
[1,50) Database_A
[50,100) Database_B
[100,200) Database_C
[400,600) Database_C
... ...

Každá z výše uvedených tabulek představuje koncepční příklad objektu ShardMap . Každý řádek představuje zjednodušený příklad jednotlivého PointMapping (pro mapu fragmentů seznamu) nebo RangeMapping (pro mapu fragmentů rozsahu).

Správce mapy datových fragmentů

V klientské knihovně je správce fragmentů kolekcí fragmentových map. Data spravovaná instancí ShardMapManager se uchovávají na třech místech:

  1. Globální mapa fragmentů (GSM): Určíte databázi, která bude sloužit jako úložiště pro všechny její mapy fragmentů a mapování. Pro správu informací se automaticky vytvoří speciální tabulky a uložené procedury. Obvykle se jedná o malou databázi a mírně se k ní přistupuje a nemělo by se používat pro jiné potřeby aplikace. Tabulky jsou ve speciálním schématu s názvem __ShardManagement.
  2. Mapa místních horizontálních oddílů (LSM):: Každá databáze, kterou určíte jako horizontální oddíl, se upraví tak, aby obsahovala několik malých tabulek a speciální uložené procedury, které obsahují a spravují informace mapy horizontálních oddílů specifické pro tento horizontální oddíl. Tyto informace jsou redundantní s informacemi v GSM a umožňují aplikaci ověřit informace mapy horizontálních oddílů v mezipaměti bez jakéhokoli zatížení GSM; aplikace pomocí LSM určí, jestli je mapování v mezipaměti stále platné. Tabulky odpovídající LSM na každém shardu jsou také ve schématu __ShardManagement.
  3. Mezipaměť aplikací: Každá instance aplikace, která přistupuje k objektu ShardMapManager , udržuje místní mezipaměť v paměti mapování. Ukládá informace o směrování, které byly nedávno načteny.

Vytvoření objektu ShardMapManager

Objekt ShardMapManager je vytvořen pomocí vzoru továrny (Java, .NET). Metoda ShardMapManagerFactory.GetSqlShardMapManager (Java, .NET) přebírá přihlašovací údaje (včetně názvu serveru a názvu databáze držícího GSM) ve formě ConnectionString a vrací instanci ShardMapManager.

Poznámka: Objekt ShardMapManager by se měl vytvořit pouze jednou pro každou doménu aplikace v rámci inicializačního kódu aplikace. Vytvoření dalších instancí ShardMapManager ve stejné doméně aplikace vede ke zvýšení využití paměti a procesoru aplikace. ShardMapManager může obsahovat libovolný počet map shardů. I když jedna mapa horizontálních oddílů může stačit pro mnoho aplikací, existují časy, kdy se různé sady databází používají pro různá schémata nebo pro jedinečné účely; v takových případech může být vhodnější více map horizontálních oddílů.

V tomto kódu se aplikace pokusí otevřít existující ShardMapManager pomocí TryGetSqlShardMapManager (Java, metoda .NET . Pokud objekty představující globální ShardMapManager (GSM) ještě neexistují uvnitř databáze, klientská knihovna je vytvoří pomocí 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.
}

Pro verzi .NET můžete vytvořit nový správce Shard Map pomocí PowerShellu.

Získejte RangeShardMap nebo ListShardMap

Po vytvoření správce mapování horizontálních oddílů můžete získat RangeShardMap (Java, .NET) nebo ListShardMap (Java, .NET) pomocí metody TryGetRangeShardMap (Java, .NET), TryGetListShardMap (Java, .NET) nebo metody 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;
}

Přihlašovací údaje pro správu shardových map

Aplikace, které spravují mapy horizontálních oddílů a manipulují s nimi, se liší od aplikací, které ke směrování připojení používají mapy horizontálních oddílů.

Ke správě map horizontálních oddílů (přidání nebo změna horizontálních oddílů, map horizontálních oddílů, mapování horizontálních oddílů atd.) musíte vytvořit instanci ShardMapManager pomocí přihlašovacích údajů, které mají oprávnění ke čtení a zápisu pro databázi GSM i pro každou databázi, která slouží jako horizontální oddíl. Přihlašovací údaje musí umožňovat zápis do tabulek v GSM i LSM, protože jsou zadávány nebo měněny informace o mapách fragmentů, a také pro vytváření tabulek LSM na nových fragmentech.

Viz Přihlašovací údaje používané pro přístup k klientské knihovně elastické databáze.

Ovlivněná pouze metadata

Metody používané pro naplnění nebo změnu dat ShardMapManager nemění uživatelská data uložená v samotných shardech. Například metody, jako CreateShard, DeleteShard, UpdateMapping atd. ovlivňují pouze metadata mapy horizontálních oddílů. Neodstraňují, nepřidávají ani nemění uživatelská data obsažená ve shardech. Místo toho jsou tyto metody navrženy tak, aby se používaly ve spojení s samostatnými operacemi, které provedete při vytváření nebo odebírání skutečných databází, nebo které přesouvají řádky z jednoho horizontálního oddílu do druhého, aby bylo možné znovu vyvážit horizontálně dělené prostředí. (Nástroj rozdělování a slučování, který je součástí nástrojů pro elastické databáze, využívá tato rozhraní API spolu s orchestrací skutečného přesunu dat mezi shardami.) Viz Škálování pomocí nástroje Elastic Database split-merge.

Směrování závislé na datech

Správce map úlomků se používá v aplikacích, které vyžadují připojení k databázi k provádění operací s daty specifickými pro danou aplikaci. Tato připojení musí být přidružená ke správné databázi. To se označuje jako směrování závislé na datech. Pro tyto aplikace vytvořte instanci objektu správce mapování horizontálních oddílů z továrny pomocí přihlašovacích údajů, které mají přístup jen pro čtení v databázi GSM. Jednotlivé požadavky na pozdější připojení poskytují přihlašovací údaje potřebné pro připojení k příslušné shardované databázi.

Všimněte si, že tyto aplikace (pomocí ShardMapManager otevřené s přihlašovacími údaji jen pro čtení) nemohou provádět změny map nebo mapování. Pro tyto potřeby vytvořte aplikace specifické pro správu nebo skripty PowerShellu, které poskytují přihlašovací údaje s vyššími oprávněními, jak je popsáno výše. Viz Přihlašovací údaje používané pro přístup k klientské knihovně elastické databáze.

Další informace naleznete v tématu Směrování závislé na datech.

Úprava mapy shardů

Mapu shardů je možné změnit různými způsoby. Všechny následující metody upravují metadata popisující horizontální oddíly a jejich mapování, ale neupravují fyzicky data v rámci horizontálních oddílů, ani nevytvoří ani neodstraní skutečné databáze. Některé operace na mapě horizontálních oddílů popsané níže mohou být potřeba koordinovat s akcemi správy, které fyzicky přesouvají data nebo přidávají a odebírat databáze sloužící jako horizontální oddíly.

Tyto metody spolupracují jako stavební bloky, které jsou k dispozici pro úpravu celkové distribuce dat v prostředí horizontálně dělené databáze.

  • Přidání nebo odebrání shardů: použijte CreateShard (Java, .NET) a DeleteShard (Java, .NET) třídy shardmap (Java, .NET).

    Server a databáze představující cílový horizontální oddíl už musí existovat, aby se tyto operace spustily. Tyto metody nemají žádný vliv na samotné databáze, pouze na metadata v mapě shardů.

  • K vytvoření nebo odebrání bodů nebo rozsahů mapovaných na shardy: použijte CreateRangeMapping (Java, .NET), DeleteMapping (Java, .NET) třídy RangeShardMapping (Java, .NET) a CreatePointMapping (Java, .NET) třídy ListShardMap (Java, .NET).

    Mnoho různých bodů nebo oblastí je možné mapovat na stejný horizontální oddíl. Tyto metody ovlivňují pouze metadata – neovlivňují žádná data, která již mohou být v shardech. Pokud je potřeba data z databáze odebrat, aby byla konzistentní s operacemi DeleteMapping , provedete tyto operace samostatně, ale ve spojení s těmito metodami.

  • Pokud chcete rozdělit existující rozsahy do dvou nebo sloučit sousední oblasti do jedné: použijte SplitMapping (Java, .NET) a MergeMappings (Java, .NET).

    Uvědomte si, že operace rozdělení a sloučení nemění shard, na který jsou mapovány hodnoty klíče. Rozdělení rozdělí existující oblast na dvě části, ale obě ponechá namapované na stejný fragment. Sloučení funguje se dvěma sousedními oblastmi, které jsou už namapované na stejný horizontální oddíl, a slučuje je do jedné oblasti. Přesun bodů nebo rozsahů mezi shardy je potřeba koordinovat pomocí UpdateMapping ve spojení se skutečným přesunem dat. Službu Split/Merge, která je součástí nástrojů elastické databáze, můžete použít ke koordinaci změn mapování horizontálních oddílů s přesunem dat v případě potřeby přesunu.

  • Pokud chcete znovu namapovat (nebo přesunout) jednotlivé body nebo rozsahy do různých horizontálních oddílů: použijte UpdateMapping (Java, .NET).

    Vzhledem k tomu, že dat může být potřeba přesunout z jednoho shardu do jiného, aby byla konzistentní s operacemi UpdateMapping, je nutné tento přesun provést samostatně, ale ve spojení s využitím těchto metod.

  • K online a offline mapování: K řízení online stavu mapování použijte MarkMappingOffline (Java, .NET) a MarkMappingOnline (Java, .NET).

    Některé operace s mapováním shardů jsou povoleny pouze v případě, že je mapování ve stavu offline, včetně UpdateMapping a DeleteMapping. Když je mapování offline, požadavek závislý na datech založený na klíči, který je součástí mapování, vrátí chybu. Kromě toho se při prvním přepnutí rozsahu do offline režimu automaticky ukončí všechna připojení k ovlivněným shardům, aby se zabránilo nekonzistentním nebo neúplným výsledkům pro dotazy směrované proti měněným rozsahům.

Mapování jsou neměnné objekty v prostředí .NET. Všechny výše uvedené metody, které mění mapování, také zneplatní všechny odkazy na ně v kódu. Aby bylo snazší provádět posloupnosti operací, které mění stav mapování, všechny metody, které mění mapování, vrátí nový odkaz na mapování, takže operace mohou být zřetězeny. Pokud chcete například odstranit existující mapování v objektu shardmap s klíčem 25, můžete provést následující:

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

Přidání shardu

Aplikace často potřebují přidat nové shardy pro zpracování dat očekávaných z nových klíčů nebo rozsahů klíčů, pro mapu shardů, která již existuje. Například aplikace horizontálně dělené podle ID tenanta může potřebovat zřídit nový horizontální oddíl pro nového tenanta nebo data horizontálně dělené měsíčně můžou potřebovat nové horizontální oddíly zřízené před začátkem každého nového měsíce.

Pokud nový rozsah hodnot klíče ještě není součástí existujícího mapování a není potřeba přesun dat, je jednoduché přidat nový horizontální oddíl a přidružit nový klíč nebo rozsah k ho horizontálnímu oddílu. Podrobnosti o přidávání nových shardů naleznete v tématu Přidání nového shardu.

V případě scénářů, které vyžadují přesun dat, je však potřeba nástroj pro rozdělení a sloučení k orchestraci přesunu dat mezi shardy v kombinaci s potřebnými aktualizacemi mapování shardů. Podrobnosti o použití nástroje pro rozdělení a sloučení naleznete v tématu Přehled rozdělení-sloučení

Ještě nepoužíváte nástroje elastické databáze? Podívejte se na naši příručku Začínáme. Pokud máte dotazy, kontaktujte nás na stránce otázek Microsoft Q&A pro SLUŽBU SQL Database a žádosti o funkce, přidejte nové nápady nebo hlasujte pro stávající nápady ve fóru pro zpětnou vazbu ke službě SQL Database.