Dela via


Hierarkiska partitionsnycklar i Azure Cosmos DB

GÄLLER FÖR: NoSQL

Azure Cosmos DB distribuerar dina data över logiska och fysiska partitioner baserat på dina partitionsnycklar för att stödja horisontell skalning. Genom att använda hierarkiska partitionsnycklar (kallas även underpartitonering) kan du konfigurera upp till en hierarki på tre nivåer för dina partitionsnycklar för att ytterligare optimera datadistributionen och för en högre skalningsnivå.

Om du använder syntetiska nycklar i dag eller om du har scenarier där partitionsnycklar kan överskrida 20 GB data kan underpartitionering hjälpa. Om du använder den här funktionen kan de logiska partitionsnyckelprefixen överskrida 20 GB och 10 000 enheter för begäranden per sekund (RU/s). Frågor efter prefix dirigeras effektivt till den delmängd av partitioner som innehåller data.

Välj dina hierarkiska partitionsnycklar

Om du har program med flera klienter rekommenderar vi att du använder hierarkiska partitionsnycklar. Med hierarkiska partitioner kan du skala bortom den logiska partitionsnyckelgränsen på 20 GB. Om den aktuella partitionsnyckeln eller om en enskild partitionsnyckel ofta når 20 GB är hierarkiska partitioner ett bra val för din arbetsbelastning.

När du väljer dina hierarkiska partitionsnycklar är det viktigt att ha följande allmänna partitioneringsbegrepp i åtanke:

  • För alla containrar bör varje nivå av den fullständiga sökvägen (från och med den första nivån) för den hierarkiska partitionsnyckeln:

    • Ha hög kardinalitet. De första, andra och tredje (om tillämpligt) nycklarna för den hierarkiska partitionen bör alla ha ett brett utbud av möjliga värden.
    • Sprida ru-förbrukning (request unit) och datalagring jämnt över alla logiska partitioner. Den här spridningen säkerställer även RU-förbrukning och lagringsdistribution över dina fysiska partitioner.
  • För stora, läsintensiva arbetsbelastningar rekommenderar vi att du väljer hierarkiska partitionsnycklar som visas ofta i dina frågor. Till exempel kan en arbetsbelastning som ofta kör frågor för att filtrera bort specifika användarsessioner i ett program med flera klientorganisationer dra nytta av hierarkiska partitionsnycklar för TenantId, UserIdoch SessionId, i den ordningen. Frågor kan effektivt dirigeras till endast relevanta fysiska partitioner genom att inkludera partitionsnyckeln i filterpredikatet. Mer information om hur du väljer partitionsnycklar för läsintensiva arbetsbelastningar finns i partitioneringsöversikten.

Exempel på användningsfall

Anta att du har ett scenario med flera klienter där du lagrar händelseinformation för användare i varje klientorganisation. Händelseinformationen kan ha händelsehändelser, inklusive men inte begränsat till inloggning, klickström eller betalningshändelser.

I ett verkligt scenario kan vissa klienter växa sig stora, med tusentals användare, medan de många andra klienterna är mindre och har några få användare. Partitionering efter /TenantId kan leda till att azure Cosmos DB-lagringsgränsen på 20 GB överskrids på en enda logisk partition. Partitionering efter /UserId gör att alla frågor på en klientorganisation korspartitioneras. Båda metoderna har betydande nackdelar.

Använda en syntetisk partitionsnyckel som kombinerar TenantId och UserId lägger till komplexitet i programmet. Dessutom är de syntetiska partitionsnyckelfrågorna för en klientorganisation fortfarande korspartitionerade, såvida inte alla användare är kända och angivna i förväg.

Med hierarkiska partitionsnycklar kan du partitioneras först på TenantIdoch sedan på UserId. Om du förväntar TenantId dig att kombinationen och UserId ska producera partitioner som överskrider 20 GB kan du till och med partitioneras längre ned till en annan nivå, till exempel på SessionId. Det totala djupet får inte överstiga tre nivåer. När en fysisk partition överskrider 50 GB lagringsutrymme delar Azure Cosmos DB automatiskt upp den fysiska partitionen så att ungefär hälften av data finns på en fysisk partition och hälften är på den andra. I praktiken innebär underpartitionering att ett enda TenantId värde kan överstiga 20 GB data, och det är möjligt för TenantId data att sträcka sig över flera fysiska partitioner.

Frågor som anger antingen TenantId, eller både TenantId och och UserId, dirigeras effektivt till endast den delmängd av fysiska partitioner som innehåller relevanta data. Om du anger den fullständiga partitionsnyckelsökvägen eller prefixets underpartitionerade sökväg undviker du i praktiken en fullständig utfläkt fråga. Om containern till exempel hade 1 000 fysiska partitioner, men ett specifikt TenantId värde bara fanns på 5 fysiska partitioner, dirigeras frågan till det mindre antalet relevanta fysiska partitioner.

Använda objekt-ID i hierarkin

Om containern har en egenskap som har ett stort antal möjliga värden är egenskapen förmodligen ett bra partitionsnyckelval för den sista nivån i hierarkin. Ett möjligt exempel på den här typen av egenskap är objekt-ID :t. Systemegenskapens objekt-ID finns i varje objekt i containern. Om du lägger till objekt-ID:t som en annan nivå kan du skala över den logiska partitionsnyckelgränsen på 20 GB. Du kan skala över den här gränsen för den första nivån eller för den första och andra nivån av nycklar.

Du kan till exempel ha en container för en arbetsbelastning med flera klientorganisationer som partitioneras av TenantId och UserId. Om det är möjligt för en enskild kombination av TenantId och UserId överskrider 20 GB rekommenderar vi att du partitioneras med hjälp av tre nivåer av nycklar och där nyckeln på tredje nivån har hög kardinalitet. Ett exempel på det här scenariot är om nyckeln på tredje nivån är ett GUID som har naturligt hög kardinalitet. Det är osannolikt att kombinationen av TenantId, UserIdoch ett GUID överskrider 20 GB, så kombinationen av TenantId och UserId kan effektivt skalas över 20 GB.

Mer information om hur du använder objekt-ID som partitionsnyckel finns i partitioneringsöversikten.

Kom igång

Viktigt!

Att arbeta med containrar som använder hierarkiska partitionsnycklar stöds endast i följande SDK-versioner. Du måste använda en SDK som stöds för att skapa nya containrar med hierarkiska partitionsnycklar och för att kunna skapa, läsa, uppdatera och ta bort (CRUD) eller frågeåtgärder på data. Om du vill använda en SDK eller anslutningsprogram som för närvarande inte stöds kan du skicka en begäran i vårt communityforum.

Hitta den senaste förhandsversionen av varje SDK som stöds:

SDK Versioner som stöds Pakethanterarens länk
.NET SDK v3 >= 3.33.0 https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.33.0/
Java SDK v4 >= 4.42.0 https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/cosmos/azure-cosmos/CHANGELOG.md#4420-2023-03-17/
JavaScript SDK v4 4.0.0 https://www.npmjs.com/package/@azure/cosmos/
Python SDK >= 4.6.0 https://pypi.org/project/azure-cosmos/4.6.0/

Skapa en container med hjälp av hierarkiska partitionsnycklar

Kom igång genom att skapa en ny container med hjälp av en fördefinierad lista över underpartitioneringsnyckelsökvägar på upp till tre djupnivåer.

Du kan skapa en ny container med något av följande alternativ:

  • Azure Portal
  • SDK
  • Azure Resource Manager-mall
  • Azure Cosmos DB-emulator

Azure Portal

Det enklaste sättet att skapa en container och ange hierarkiska partitionsnycklar är att använda Azure-portalen.

  1. Logga in på Azure-portalen.

  2. Gå till den befintliga kontosidan för Azure Cosmos DB för NoSQL.

  3. Välj Datautforskaren på den vänstra menyn.

    Skärmbild som visar sidan för ett nytt Azure Cosmos DB för NoSQL-konto med menyalternativet Datautforskaren markerat.

  4. I Datautforskaren väljer du alternativet Ny container.

    Skärmbild av alternativet Ny container i Datautforskaren.

  5. I Ny container för Partitionsnyckel anger du /TenantId. För de återstående fälten anger du ett värde som matchar ditt scenario.

    Kommentar

    Vi använder /TenantId som exempel här. Du kan ange valfri nyckel för den första nivån när du implementerar hierarkiska partitionsnycklar på dina egna containrar.

  6. Välj Lägg till hierarkisk partitionsnyckel två gånger.

    Skärmbild av knappen för att lägga till en ny hierarkisk partitionsnyckel.

  7. För den andra och tredje nivån av underpartitionering anger du /UserId/SessionId respektive.

    Skärmbild av en lista med tre hierarkiska partitionsnycklar.

  8. Skapa behållare genom att välja OK.

SDK

När du skapar en ny container med hjälp av SDK definierar du en lista över underpartitioneringsnyckelsökvägar på upp till tre djupnivåer. Använd listan med underpartitionsnycklar när du konfigurerar egenskaperna för den nya containern.

// List of partition keys, in hierarchical order. You can have up to three levels of keys.
List<string> subpartitionKeyPaths = new List<string> { 
    "/TenantId",
    "/UserId",
    "/SessionId"
};

// Create a container properties object
ContainerProperties containerProperties = new ContainerProperties(
    id: "<container-name>",
    partitionKeyPaths: subpartitionKeyPaths
);

// Create a container that's subpartitioned by TenantId > UserId > SessionId
Container container = await database.CreateContainerIfNotExistsAsync(containerProperties, throughput: 400);

Azure Resource Manager-mallar

Azure Resource Manager-mallen för en underpartitionerad container är nästan identisk med en standardcontainer. Den enda viktiga skillnaden är värdet för properties/partitionKey sökvägen. Mer information om hur du skapar en Azure Resource Manager-mall för en Azure Cosmos DB-resurs finns i mallreferensen för Azure Resource Manager för Azure Cosmos DB.

Konfigurera objektet partitionKey med hjälp av värdena i följande tabell för att skapa en underpartitionerad container:

Sökväg Värde
paths Lista över hierarkiska partitionsnycklar (max tre djupnivåer)
kind MultiHash
version 2

Exempel på definition av partitionsnyckel

Anta till exempel att du har en hierarkisk partitionsnyckel som består av TenantIdSessionId>UserId>. Objektet partitionKey skulle konfigureras för att inkludera alla tre värdena i paths egenskapen, värdet kindMultiHash, och värdet version2.

partitionKey: {
  paths: [
    '/TenantId'
    '/UserId'
    '/SessionId'
  ]
  kind: 'MultiHash'
  version: 2
}

Mer information om objektet finns i partitionKeyContainerPartitionKey-specifikationen.

Azure Cosmos DB-emulator

Du kan testa underpartitioneringsfunktionen med hjälp av den senaste versionen av den lokala emulatorn för Azure Cosmos DB. Starta emulatorn från installationskatalogen med /EnablePreview flaggan för att aktivera underparitionering på emulatorn:

.\CosmosDB.Emulator.exe /EnablePreview

Varning

Emulatorn stöder för närvarande inte alla hiearkiska partitionsnyckelfunktioner som portalen. Emulatorn stöder för närvarande inte:

  • Använda Datautforskaren för att skapa containrar med hierarkiska partitionsnycklar
  • Använda Datautforskaren för att navigera till och interagera med objekt med hjälp av hierarkiska partitionsnycklar

Mer information finns i Azure Cosmos DB-emulatorn.

Använd SDK:erna för att arbeta med containrar som har hierarkiska partitionsnycklar

När du har en container som har hierarkiska partitionsnycklar använder du tidigare angivna versioner av .NET- eller Java-SDK:erna för att utföra åtgärder och köra frågor på containern.

Lägga till ett objekt i en container

Det finns två alternativ för att lägga till ett nytt objekt i en container med hierarkiska partitionsnycklar aktiverade:

  • Automatisk extrahering
  • Ange sökvägen manuellt

Automatisk extrahering

Om du skickar in ett objekt med partitionsnyckelns värdeuppsättning kan SDK:et automatiskt extrahera den fullständiga partitionsnyckelsökvägen.

// Create a new item
UserSession item = new UserSession()
{
    id = "f7da01b0-090b-41d2-8416-dacae09fbb4a",
    TenantId = "Microsoft",
    UserId = "8411f20f-be3e-416a-a3e7-dcd5a3c1f28b",
    SessionId = "0000-11-0000-1111"
};

// Pass in the object, and the SDK automatically extracts the full partition key path
ItemResponse<UserSession> createResponse = await container.CreateItemAsync(item);

Ange sökvägen manuellt

Klassen PartitionKeyBuilder i SDK kan konstruera ett värde för en tidigare definierad hierarkisk partitionsnyckelsökväg. Använd den här klassen när du lägger till ett nytt objekt i en container som har underpartitionering aktiverat.

Dricks

I stor skala kan prestanda förbättras om du anger den fullständiga partitionsnyckelsökvägen, även om SDK:t kan extrahera sökvägen från objektet.

// Create a new item object
PaymentEvent item = new PaymentEvent()
{
    id = Guid.NewGuid().ToString(),
    TenantId = "Microsoft",
    UserId = "8411f20f-be3e-416a-a3e7-dcd5a3c1f28b",
    SessionId = "0000-11-0000-1111"
};

// Specify the full partition key path when creating the item
PartitionKey partitionKey = new PartitionKeyBuilder()
            .Add(item.TenantId)
            .Add(item.UserId)
            .Add(item.SessionId)
            .Build();

// Create the item in the container
ItemResponse<PaymentEvent> createResponse = await container.CreateItemAsync(item, partitionKey);

Utföra ett nyckel-/värde-uppslag (punktläsning) för ett objekt

Nyckel-/värdesökningar (punktläsningar) utförs på ett sätt som liknar en container som inte är en underpartitionerad container. Anta till exempel att du har en hierarkisk partitionsnyckel som består av TenantIdSessionId>UserId>. Den unika identifieraren för objektet är ett GUID. Den representeras som en sträng som fungerar som en unik dokumenttransaktionsidentifierare. Om du vill utföra en punkt som lästs på ett enda objekt skickar du in id egenskapen för objektet och det fullständiga värdet för partitionsnyckeln, inklusive alla tre komponenterna i sökvägen.

// Store the unique identifier
string id = "f7da01b0-090b-41d2-8416-dacae09fbb4a";

// Build the full partition key path
PartitionKey partitionKey = new PartitionKeyBuilder()
    .Add("Microsoft") //TenantId
    .Add("8411f20f-be3e-416a-a3e7-dcd5a3c1f28b") //UserId
    .Add("0000-11-0000-1111") //SessionId
    .Build();

// Perform a point read
ItemResponse<UserSession> readResponse = await container.ReadItemAsync<UserSession>(
    id,
    partitionKey
);

Köra en fråga

SDK-koden som du använder för att köra en fråga på en underpartitionerad container är identisk med att köra en fråga på en container som inte är underpartitionerad.

När frågan anger alla värden för partitionsnycklarna i WHERE filtret eller i ett prefix i nyckelhierarkin dirigerar SDK:t automatiskt frågan till motsvarande fysiska partitioner. Frågor som endast tillhandahåller "mitten" av hierarkin är frågor mellan partitioner.

Tänk dig till exempel en hierarkisk partitionsnyckel som består av TenantIdSessionId>UserId>. Komponenterna i frågans filter avgör om frågan är en fråga med en partition, en riktad fråga mellan partitioner eller en utspringad fråga.

Fråga Routning
SELECT * FROM c WHERE c.TenantId = 'Microsoft' AND c.UserId = '8411f20f-be3e-416a-a3e7-dcd5a3c1f28b' AND c.SessionId = '0000-11-0000-1111' Dirigerad till den enda logiska och fysiska partitionen som innehåller data för de angivna värdena TenantId, UserIdoch SessionId.
SELECT * FROM c WHERE c.TenantId = 'Microsoft' AND c.UserId = '8411f20f-be3e-416a-a3e7-dcd5a3c1f28b' Dirigeras endast till den riktade delmängden av logiska och fysiska partitioner som innehåller data för de angivna värdena TenantId för och UserId. Den här frågan är en riktad fråga mellan partitioner som returnerar data för en specifik användare i klientorganisationen.
SELECT * FROM c WHERE c.TenantId = 'Microsoft' Dirigeras endast till den riktade delmängden av logiska och fysiska partitioner som innehåller data för det angivna värdet TenantId. Den här frågan är en riktad fråga mellan partitioner som returnerar data för alla användare i en klientorganisation.
SELECT * FROM c WHERE c.UserId = '8411f20f-be3e-416a-a3e7-dcd5a3c1f28b' Dirigeras till alla fysiska partitioner, vilket resulterar i en utskärmad korspartitionsfråga.
SELECT * FROM c WHERE c.SessionId = '0000-11-0000-1111' Dirigeras till alla fysiska partitioner, vilket resulterar i en utskärmad korspartitionsfråga.

Fråga med en partition i en underpartitionerad container

Här är ett exempel på hur du kör en fråga som innehåller alla nivåer av underpartitionering, vilket effektivt gör frågan till en fråga med en partition.

// Define a single-partition query that specifies the full partition key path
QueryDefinition query = new QueryDefinition(
    "SELECT * FROM c WHERE c.TenantId = @tenant-id AND c.UserId = @user-id AND c.SessionId = @session-id")
    .WithParameter("@tenant-id", "Microsoft")
    .WithParameter("@user-id", "8411f20f-be3e-416a-a3e7-dcd5a3c1f28b")
    .WithParameter("@session-id", "0000-11-0000-1111");

// Retrieve an iterator for the result set
using FeedIterator<PaymentEvent> results = container.GetItemQueryIterator<PaymentEvent>(query);

while (results.HasMoreResults)
{
    FeedResponse<UserSession> resultsPage = await resultSet.ReadNextAsync();
    foreach(UserSession result in resultsPage)
    {
        // Process result
    }
}

Riktad fråga med flera partitioner i en underpartitionerad container

Här är ett exempel på en fråga som innehåller en delmängd av nivåerna för underpartitionering, vilket effektivt gör den här frågan till en riktad fråga med flera partitioner.

// Define a targeted cross-partition query specifying prefix path[s]
QueryDefinition query = new QueryDefinition(
    "SELECT * FROM c WHERE c.TenantId = @tenant-id")
    .WithParameter("@tenant-id", "Microsoft")

// Retrieve an iterator for the result set
using FeedIterator<PaymentEvent> results = container.GetItemQueryIterator<PaymentEvent>(query);

while (results.HasMoreResults)
{
    FeedResponse<UserSession> resultsPage = await resultSet.ReadNextAsync();
    foreach(UserSession result in resultsPage)
    {
        // Process result
    }
}

Begränsningar och kända problem

  • Att arbeta med containrar som använder hierarkiska partitionsnycklar stöds endast i .NET v3 SDK, i Java v4 SDK och i förhandsversionen av JavaScript SDK. Du måste använda en SDK som stöds för att skapa nya containrar som har hierarkiska partitionsnycklar och för att utföra CRUD- eller frågeåtgärder på data. Stöd för andra SDK:er, inklusive Python, är inte tillgängligt för närvarande.
  • Det finns begränsningar med olika Azure Cosmos DB-anslutningsappar (till exempel med Azure Data Factory).
  • Du kan ange hierarkiska partitionsnycklar endast upp till tre lager på djupet.
  • Hierarkiska partitionsnycklar kan för närvarande endast aktiveras på nya containrar. Du måste ange partitionsnyckelsökvägar när containern skapas och du kan inte ändra dem senare. Om du vill använda hierarkiska partitioner på befintliga containrar skapar du en ny container med de hierarkiska partitionsnycklarna inställda och flyttar data med hjälp av containerkopieringsjobb.
  • Hierarkiska partitionsnycklar stöds för närvarande endast för API:et för NoSQL-konton. API:erna för MongoDB och Cassandra stöds inte för närvarande.
  • Hierarkiska partitionsnycklar stöds för närvarande inte med funktionen Behörigheter. Du kan inte tilldela en behörighet till ett partiellt prefix för den hierarkiska partitionsnyckelsökvägen. Behörigheter kan bara tilldelas till hela sökvägen till den logiska partitionsnyckeln. Om du till exempel har partitionerat av TenantId – >UserIdkan du inte tilldela en behörighet som är för ett specifikt värde på TenantId. Du kan dock tilldela en behörighet för en partitionsnyckel om du anger både värdet för TenantId och "UserId".

Nästa steg