Skala ut databaser med shard map manager

Gäller för:Azure SQL Database

Använd en shard map manager för att enkelt skala ut databaser i Azure SQL Database. Karthanteraren för fragment är en särskild databas som upprätthåller global mappningsinformation om alla shards (databaser) i en sharduppsättning. Med metadata kan ett program ansluta till rätt databas baserat på värdet för partitioneringsnyckeln. Dessutom innehåller varje shard i uppsättningen kartor som spårar lokala sharddata (kallas shardletar).

Shard map management

Att förstå hur dessa kartor konstrueras är viktigt för hantering av fragmentkartor. Detta görs med hjälp av klassen ShardMapManager (Java, .NET) som finns i Elastic Database-klientbiblioteket för att hantera shardkartor.

Fragmentkartor och shardmappningar

För varje shard måste du välja den typ av shardkarta som ska skapas. Valet beror på databasarkitekturen:

  1. Enskild klientorganisation per databas
  2. Flera klientorganisationer per databas (två typer):
    1. Listmappning
    2. Intervallmappning

Skapa en shardkarta för listmappning för en enskild klientorganisationsmodell. Modellen med en klient tilldelar en databas per klientorganisation. Det här är en effektiv modell för SaaS-utvecklare eftersom den förenklar hantering av fragmentkartor.

List mapping

Modellen med flera klientorganisationer tilldelar flera klientorganisationer till en enskild databas (och du kan distribuera grupper av klientorganisationer över flera databaser). Använd den här modellen när du förväntar dig att varje klientorganisation har små databehov. I den här modellen tilldelar du ett intervall med klienter till en databas med hjälp av intervallmappning.

Range mapping

Eller så kan du implementera en databasmodell för flera klientorganisationer med hjälp av en listmappning för att tilldela flera klienter till en enskild databas. Db1 används till exempel för att lagra information om klientorganisations-ID 1 och 5, och DB2 lagrar data för klientorganisation 7 och klient 10.

Multiple tenants on single DB

Typer som stöds för horisontell partitioneringsnycklar

Elastisk skalning stöder följande typer som horisontell partitioneringsnycklar:

.NET Java
integer integer
lång lång
guid uuid
byte[] byte[]
datetime timestamp
tidsintervall varaktighet
datetimeoffset offsetdatetime

Lista och intervallshardkartor

Shard-kartor kan konstrueras med hjälp av listor över enskilda värden för horisontell partitioneringsnyckel, eller så kan de konstrueras med hjälp av intervall med partitioneringsnyckelvärden.

Lista fragmentkartor

Shards innehåller shardletar och mappningen av shardlets till shards underhålls av en shardkarta. En listshardkarta är en association mellan de enskilda nyckelvärdena som identifierar shardlets och de databaser som fungerar som shards. Listmappningar är explicita och olika nyckelvärden kan mappas till samma databas. Till exempel mappar nyckelvärdet 1 till Databas A och nyckelvärdena 3 och 6 mappar båda till Databas B.

Key Shard-plats
1 Database_A
3 Database_B
4 Database_C
6 Database_B
... ...

Range shard maps

I en intervallshardkarta beskrivs nyckelintervallet av ett par [Lågt värde, högt värde) där det låga värdet är miniminyckeln i intervallet och det höga värdet är det första värdet som är högre än intervallet.

[0, 100) innehåller till exempel alla heltal som är större än eller lika med 0 och mindre än 100. Observera att flera intervall kan peka på samma databas och att de olika intervallen stöds (till exempel [100 200) och [400 600) båda pekar på Databas C i följande exempel.)

Key Shard-plats
[1,50) Database_A
[50,100) Database_B
[100,200) Database_C
[400,600) Database_C
... ...

Var och en av tabellerna som visas ovan är ett konceptuellt exempel på ett ShardMap-objekt . Varje rad är ett förenklat exempel på ett enskilt PointMapping-objekt (för list-shardkartan) eller RangeMapping-objekt (för intervallshardkartan).

Karthanterare för shard

I klientbiblioteket är karthanteraren för shard en samling shardkartor. Data som hanteras av en ShardMapManager-instans behålls på tre platser:

  1. Global Shard Map (GSM): Du anger en databas som ska fungera som lagringsplats för alla dess fragmentkartor och mappningar. Särskilda tabeller och lagrade procedurer skapas automatiskt för att hantera informationen. Detta är vanligtvis en liten databas och lätt åtsåt, och den bör inte användas för andra behov i programmet. Tabellerna finns i ett särskilt schema med namnet __ShardManagement.
  2. Lokal Shard Map (LSM): Varje databas som du anger som en shard ändras så att den innehåller flera små tabeller och särskilda lagrade procedurer som innehåller och hanterar shardmappningsinformation som är specifik för fragmentet. Den här informationen är redundant med informationen i GSM och gör det möjligt för programmet att verifiera cachelagrad shardkarta utan att lägga någon belastning på GSM; programmet använder LSM för att avgöra om en cachelagrad mappning fortfarande är giltig. Tabellerna som motsvarar LSM på varje shard finns också i schemat __ShardManagement.
  3. Programcache: Varje programinstans som har åtkomst till ett ShardMapManager-objekt har en lokal minnesintern cache för sina mappningar. Den lagrar routningsinformation som nyligen har hämtats.

Skapa en ShardMapManager

Ett ShardMapManager-objekt skapas med hjälp av ett fabriksmönster (Java, .NET). Metoden ShardMapManagerFactory.GetSqlShardMapManager (Java, .NET) tar autentiseringsuppgifter (inklusive servernamnet och databasnamnet som innehåller GSM) i form av en Anslut ionString och returnerar en instans av en ShardMapManager.

Obs!ShardMapManager ska bara instansieras en gång per appdomän, inom initieringskoden för ett program. Skapande av ytterligare instanser av ShardMapManager i samma appdomän resulterar i ökad minnes- och CPU-användning av programmet. En ShardMapManager kan innehålla valfritt antal shardkartor. Även om en enda fragmentkarta kan vara tillräcklig för många program, finns det tillfällen då olika uppsättningar databaser används för olika scheman eller för unika ändamål. i dessa fall kan flera fragmentkartor vara att föredra.

I den här koden försöker ett program öppna en befintlig ShardMapManager med TryGetSqlShardMapManager (Java, .NET-metoden. Om objekt som representerar en Global ShardMapManager (GSM) ännu inte finns i databasen skapar klientbiblioteket dem med metoden 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.
}

För .NET-versionen kan du använda PowerShell för att skapa en ny Shard Map Manager. Ett exempel finns här.

Hämta en RangeShardMap eller ListShardMap

När du har skapat en shardkarthanterare kan du hämta RangeShardMap (Java, .NET) eller ListShardMap (Java, .NET) med hjälp av metoden TryGetRangeShardMap (Java, .NET), TryGetListShardMap (Java, .NET) eller metoden 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;
}

Autentiseringsuppgifter för Shard-mappningsadministration

Program som administrerar och manipulerar shardkartor skiljer sig från dem som använder shardkartorna för att dirigera anslutningar.

För att administrera shardkartor (lägga till eller ändra shards, shardkartor, shardmappningar osv.) måste du instansiera ShardMapManager med autentiseringsuppgifter som har läs-/skrivbehörighet för både GSM-databasen och på varje databas som fungerar som en shard. Autentiseringsuppgifterna måste tillåta skrivningar mot tabellerna i både GSM och LSM eftersom information om fragmentkartan anges eller ändras, samt för att skapa LSM-tabeller på nya shards.

Se Autentiseringsuppgifter som används för att komma åt Elastic Database-klientbiblioteket.

Endast metadata som påverkas

Metoder som används för att fylla i eller ändra ShardMapManager-data ändrar inte användardata som lagras i själva shardsna. Till exempel påverkar metoder som CreateShard, DeleteShard, UpdateMapping osv. endast metadata för horisontell mappning. De tar inte bort, lägger till eller ändrar användardata som finns i fragmenten. I stället är dessa metoder utformade för att användas tillsammans med separata åtgärder som du utför för att skapa eller ta bort faktiska databaser, eller som flyttar rader från en shard till en annan för att balansera om en fragmenterad miljö. (Verktyget för delad sammanfogning som ingår i elastiska databasverktyg använder dessa API:er tillsammans med orkestrering av faktisk dataförflyttning mellan shards.) Se Skalning med hjälp av verktyget För delad sammanfogning i Elastic Database.

Databeroende routning

Karthanteraren för shard används i program som kräver databasanslutningar för att utföra appspecifika dataåtgärder. Dessa anslutningar måste associeras med rätt databas. Detta kallas databeroende routning. För dessa program instansierar du ett shard map manager-objekt från fabriken med autentiseringsuppgifter som har skrivskyddad åtkomst i GSM-databasen. Enskilda begäranden om senare anslutningar anger de autentiseringsuppgifter som krävs för att ansluta till lämplig sharddatabas.

Observera att dessa program (med ShardMapManager som öppnats med skrivskyddade autentiseringsuppgifter) inte kan göra ändringar i kartorna eller mappningarna. För dessa behov skapar du administrativa program eller PowerShell-skript som tillhandahåller högre privilegierade autentiseringsuppgifter enligt beskrivningen tidigare. Se Autentiseringsuppgifter som används för att komma åt Elastic Database-klientbiblioteket.

Mer information finns i Databeroende routning.

Ändra en fragmentkarta

En fragmentkarta kan ändras på olika sätt. Alla följande metoder ändrar metadata som beskriver shards och deras mappningar, men de ändrar inte data fysiskt i fragmenten, och de skapar eller tar inte heller bort de faktiska databaserna. Vissa av åtgärderna på fragmentkartan som beskrivs nedan kan behöva samordnas med administrativa åtgärder som fysiskt flyttar data eller som lägger till och tar bort databaser som fungerar som shards.

Dessa metoder fungerar tillsammans som de byggstenar som är tillgängliga för att ändra den övergripande fördelningen av data i din fragmenterade databasmiljö.

  • Om du vill lägga till eller ta bort shards använder du klassen CreateShard (Java, .NET) och DeleteShard (Java, .NET) i klassen shardmap (Java, .NET).

    Servern och databasen som representerar målshard måste redan finnas för att dessa åtgärder ska kunna köras. Dessa metoder har ingen inverkan på själva databaserna, bara på metadata i fragmentkartan.

  • Om du vill skapa eller ta bort punkter eller intervall som är mappade till shards: använd CreateRangeMapping (Java, .NET), DeleteMapping (Java, .NET) för klassen RangeShardMapping (Java, .NET) och CreatePointMapping (Java, .NET) i klassen ListShardMap (Java, .NET).

    Många olika punkter eller intervall kan mappas till samma fragment. Dessa metoder påverkar endast metadata – de påverkar inte data som redan finns i shards. Om data måste tas bort från databasen för att vara konsekventa med DeleteMapping-åtgärder utför du dessa åtgärder separat men tillsammans med att använda dessa metoder.

  • Om du vill dela upp befintliga intervall i två eller sammanfoga angränsande intervall i ett: använd SplitMapping (Java, .NET) och MergeMappings (Java, .NET).

    Observera att delnings- och sammanslagningsåtgärder inte ändrar shard till vilka nyckelvärden mappas. En delning delar upp ett befintligt intervall i två delar, men lämnar båda som mappade till samma shard. En sammanslagning körs på två angränsande intervall som redan är mappade till samma fragment och sammanfogar dem till ett enda intervall. Själva förflyttningen av punkter eller intervall mellan shards måste samordnas med hjälp av UpdateMapping tillsammans med faktisk dataförflyttning. Du kan använda tjänsten Split/Merge som är en del av elastiska databasverktyg för att samordna shard map-ändringar med dataflytt när förflyttning behövs.

  • Om du vill mappa om (eller flytta) enskilda punkter eller intervall till olika shards: använd UpdateMapping (Java, .NET).

    Eftersom data kan behöva flyttas från en shard till en annan för att vara konsekventa med UpdateMapping-åtgärder måste du utföra den förflyttningen separat men tillsammans med dessa metoder.

  • Så här tar du mappningar online och offline: använd MarkMappingOffline (Java, .NET) och MarkMappingOnline (Java, .NET) för att styra onlinetillståndet för en mappning.

    Vissa åtgärder på shardmappningar tillåts endast när en mappning är i offlineläge, inklusive UpdateMapping och DeleteMapping. När en mappning är offline returnerar en databeroende begäran baserat på en nyckel som ingår i mappningen ett fel. När ett intervall först tas offline avbryts dessutom alla anslutningar till det berörda fragmentet automatiskt för att förhindra att inkonsekventa eller ofullständiga resultat för frågor som riktas mot intervall ändras.

Mappningar är oföränderliga objekt i .NET. Alla metoder ovan som ändrar mappningar ogiltigförklarar även alla referenser till dem i koden. För att göra det enklare att utföra sekvenser av åtgärder som ändrar en mappnings tillstånd returnerar alla metoder som ändrar en mappning en ny mappningsreferens, så att åtgärder kan länkas. Om du till exempel vill ta bort en befintlig mappning i shardmap sm som innehåller nyckeln 25 kan du köra följande:

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

Lägga till en shard

Program behöver ofta lägga till nya shards för att hantera data som förväntas från nya nycklar eller nyckelintervall, för en fragmentkarta som redan finns. Till exempel kan ett program som är fragmenterat av klientorganisations-ID behöva etablera en ny shard för en ny klientorganisation, eller så kan data som partitioneras varje månad behöva en ny shard etablerad före början av varje ny månad.

Om det nya intervallet med nyckelvärden inte redan är en del av en befintlig mappning och ingen dataflytt krävs är det enkelt att lägga till det nya fragmentet och associera den nya nyckeln eller intervallet till fragmentet. Mer information om hur du lägger till nya shards finns i Lägga till en ny shard.

För scenarier som kräver dataförflyttning krävs dock verktyget split-merge för att orkestrera dataförflyttningen mellan shards i kombination med nödvändiga uppdateringar av fragmentkartan. Mer information om hur du använder verktyget för delningskoppling finns i Översikt över delningskoppling

Ytterligare resurser

Använder du inte elastiska databasverktyg än? Kolla in vår komma igång-guide. Om du har frågor kan du kontakta oss på microsofts Q&A-frågesida för SQL Database och för funktionsförfrågningar, lägga till nya idéer eller rösta på befintliga idéer i SQL Database-feedbackforumet.