Partitionering och horisontell skalning i Azure Cosmos DB
GÄLLER FÖR: NoSQL MongoDB Kassandra Gremlin Bord
Azure Cosmos DB använder partitionering för att skala enskilda containrar i en databas för att uppfylla programmets prestandabehov. Objekten i en container är indelade i distinkta delmängder som kallas logiska partitioner. Logiska partitioner skapas baserat på värdet för en partitionsnyckel som är associerad med varje objekt i en container. Alla objekt i en logisk partition har samma partitionsnyckelvärde.
En container innehåller till exempel objekt. Varje objekt har ett unikt värde för egenskapen UserID
. Om UserID
fungerar som partitionsnyckel för objekten i containern och det finns 1 000 unika UserID
värden skapas 1 000 logiska partitioner för containern.
Förutom en partitionsnyckel som avgör objektets logiska partition har varje objekt i en container ett objekt-ID (unikt inom en logisk partition). Genom att kombinera partitionsnyckeln och objekt-ID :t skapas objektets index, som unikt identifierar objektet. Att välja en partitionsnyckel är ett viktigt beslut som påverkar programmets prestanda.
Den här artikeln förklarar relationen mellan logiska och fysiska partitioner. Den beskriver även metodtips för partitionering och ger en djupgående vy över hur horisontell skalning fungerar i Azure Cosmos DB. Det är inte nödvändigt att förstå den här interna informationen för att välja din partitionsnyckel, men vi täcker dem så att du kan få klarhet i hur Azure Cosmos DB fungerar.
Logiska partitioner
En logisk partition består av en uppsättning objekt som har samma partitionsnyckel. I en container som till exempel innehåller data om matnäring innehåller alla objekt en foodGroup
egenskap. Du kan använda foodGroup
som partitionsnyckel för containern. Grupper med objekt som har specifika värden för foodGroup
, till exempel Beef Products
, Baked Products
och Sausages and Luncheon Meats
, bildar distinkta logiska partitioner.
En logisk partition definierar också omfattningen för databastransaktioner. Du kan uppdatera objekt i en logisk partition med hjälp av en transaktion med ögonblicksbildisolering. När nya objekt läggs till i en container skapar systemet transparent nya logiska partitioner. Du behöver inte bekymra dig om att ta bort en logisk partition när underliggande data tas bort.
Det finns ingen gräns för antalet logiska partitioner i containern. Varje logisk partition kan lagra upp till 20 GB data. Bra partitionsnyckelval har ett brett utbud av möjliga värden. I en container där alla objekt innehåller en foodGroup
egenskap kan data i den Beef Products
logiska partitionen till exempel växa upp till 20 GB. Om du väljer en partitionsnyckel med ett stort antal möjliga värden ser du till att containern kan skalas.
Du kan använda Azure Monitor-aviseringar för att övervaka om en logisk partitions storlek närmar sig 20 GB.
Fysiska partitioner
En container skalas genom att data och dataflöde distribueras mellan fysiska partitioner. Internt mappas en eller flera logiska partitioner till en enda fysisk partition. Vanligtvis har mindre containrar många logiska partitioner, men de kräver bara en enda fysisk partition. Till skillnad från logiska partitioner är fysiska partitioner en intern implementering av systemet och Azure Cosmos DB hanterar helt fysiska partitioner.
Antalet fysiska partitioner i containern beror på följande egenskaper:
Mängden etablerat dataflöde (varje enskild fysisk partition kan ge ett dataflöde på upp till 10 000 enheter för begäranden per sekund). Gränsen på 10 000 RU/s för fysiska partitioner innebär att logiska partitioner också har en gräns på 10 000 RU/s, eftersom varje logisk partition endast mappas till en fysisk partition.
Den totala datalagringen (varje enskild fysisk partition kan lagra upp till 50 GB data).
Kommentar
Fysiska partitioner är en intern implementering av systemet och de hanteras helt av Azure Cosmos DB. När du utvecklar dina lösningar ska du inte fokusera på fysiska partitioner eftersom du inte kan kontrollera dem. Fokusera i stället på partitionsnycklarna. Om du väljer en partitionsnyckel som jämnt distribuerar dataflödesförbrukningen mellan logiska partitioner ser du till att dataflödesförbrukningen mellan fysiska partitioner är balanserad.
Det finns ingen gräns för det totala antalet fysiska partitioner i containern. När ditt etablerade dataflöde eller datastorlek växer skapar Azure Cosmos DB automatiskt nya fysiska partitioner genom att dela upp befintliga. Fysiska partitionsdelningar påverkar inte programmets tillgänglighet. Efter den fysiska partitionsdelningen lagras alla data i en enda logisk partition på samma fysiska partition. En fysisk partitionsdelning skapar helt enkelt en ny mappning av logiska partitioner till fysiska partitioner.
Dataflödet som har etablerats för en container delas jämnt mellan fysiska partitioner. En partitionsnyckeldesign som inte distribuerar begäranden jämnt kan resultera i för många begäranden som dirigeras till en liten delmängd partitioner som blir "heta". Frekventa partitioner leder till ineffektiv användning av etablerat dataflöde, vilket kan leda till hastighetsbegränsning och högre kostnader.
Du kan till exempel överväga en container med sökvägen /foodGroup
som anges som partitionsnyckel. Containern kan ha valfritt antal fysiska partitioner, men i det här exemplet antar vi att den har tre. En enda fysisk partition kan innehålla flera partitionsnycklar. Till exempel kan den största fysiska partitionen innehålla de tre viktigaste logiska partitionerna: Beef Products
, Vegetable and Vegetable Products
och Soups, Sauces, and Gravies
.
Om du tilldelar ett dataflöde på 18 000 enheter per sekund (RU/s) kan var och en av de tre fysiska partitionerna använda 1/3 av det totala etablerade dataflödet. I den valda fysiska partitionen kan de logiska partitionsnycklarna Beef Products
, Vegetable and Vegetable Products
och Soups, Sauces, and Gravies
tillsammans använda den fysiska partitionens 6 000 etablerade RU/s. Eftersom etablerat dataflöde är jämnt fördelat mellan containerns fysiska partitioner är det viktigt att välja en partitionsnyckel som jämnt distribuerar dataflödesförbrukningen. Mer information finns i välja rätt logisk partitionsnyckel.
Hantera logiska partitioner
Azure Cosmos DB hanterar transparent och automatiskt placeringen av logiska partitioner på fysiska partitioner för att effektivt uppfylla containerns skalbarhets- och prestandabehov. När dataflödet och lagringskraven för ett program ökar flyttar Azure Cosmos DB logiska partitioner för att automatiskt sprida belastningen över ett större antal fysiska partitioner. Du kan lära dig mer om fysiska partitioner.
Azure Cosmos DB använder hash-baserad partitionering för att sprida logiska partitioner över fysiska partitioner. Azure Cosmos DB hashar partitionsnyckelvärdet för ett objekt. Det hashade resultatet avgör den logiska partitionen. Sedan allokerar Azure Cosmos DB nyckelutrymmet för partitionsnyckelns hashvärden jämnt över de fysiska partitionerna.
Transaktioner (i lagrade procedurer eller utlösare) tillåts endast mot objekt i en enda logisk partition.
Replikuppsättningar
Varje fysisk partition består av en uppsättning repliker, som även kallas för en replikuppsättning. Varje replik är värd för en instans av databasmotorn. En replikuppsättning gör datalagret i den fysiska partitionen beständigt, högtillgängligt och konsekvent. Varje replik som utgör den fysiska partitionen ärver partitionens lagringskvot. Alla repliker av en fysisk partition stöder tillsammans det dataflöde som allokeras till den fysiska partitionen. Azure Cosmos DB hanterar automatiskt replikuppsättningar.
Vanligtvis kräver mindre containrar bara en enda fysisk partition, men de har fortfarande minst fyra repliker.
Följande bild visar hur logiska partitioner mappas till fysiska partitioner som distribueras globalt. Partitionsuppsättningen i avbildningen refererar till en grupp fysiska partitioner som hanterar samma logiska partitionsnycklar i flera regioner:
Välja en partitionsnyckel
En partitionsnyckel har två komponenter: partitionsnyckelsökvägen och partitionsnyckelvärdet. Tänk dig till exempel ett objekt { "userId" : "Andrew", "worksFor": "Microsoft" }
om du väljer "userId" som partitionsnyckel, följande är de två partitionsnyckelkomponenterna:
Sökvägen till partitionsnyckeln (till exempel "/userId"). Sökvägen till partitionsnyckeln accepterar alfanumeriska tecken och understreck (_). Du kan också använda kapslade objekt med hjälp av standardsökvägs notation(/).
Värdet för partitionsnyckeln (till exempel "Andrew"). Partitionsnyckelvärdet kan vara av sträng- eller numeriska typer.
Mer information om gränserna för dataflöde, lagring och längd för partitionsnyckeln finns i artikeln azure Cosmos DB-tjänstkvoter .
Att välja partitionsnyckeln är ett enkelt men viktigt designval i Azure Cosmos DB. När du har valt partitionsnyckeln går det inte att ändra den på plats. Om du behöver ändra partitionsnyckeln bör du flytta dina data till en ny container med den nya önskade partitionsnyckeln. (Containerkopieringsjobb hjälper dig med den här processen.)
För alla containrar bör partitionsnyckeln:
Vara en egenskap som har ett värde som inte ändras. Om en egenskap är partitionsnyckeln kan du inte uppdatera egenskapens värde.
Bör endast innehålla
String
värden – eller tal bör helst konverteras till enString
, om det finns någon chans att de ligger utanför gränserna för dubbla precisionsnummer enligt IEEE 754 binary64. Json-specifikationen anger orsakerna till varför användning av siffror utanför den här gränsen i allmänhet är en dålig metod på grund av sannolika samverkansproblem. Dessa problem är särskilt relevanta för kolumnen partitionsnyckel eftersom den är oföränderlig och kräver datamigrering för att ändra den senare.Ha en hög kardinalitet. Med andra ord bör egenskapen 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.
Har värden som normalt inte är större än 2 048 byte eller 101 byte om stora partitionsnycklar inte är aktiverade. Mer information finns i stora partitionsnycklar
Om du behöver ACID-transaktioner med flera objekt i Azure Cosmos DB måste du använda lagrade procedurer eller utlösare. Alla JavaScript-baserade lagrade procedurer och utlösare är begränsade till en enda logisk partition.
Kommentar
Om du bara har en fysisk partition kanske värdet för partitionsnyckeln inte är relevant eftersom alla frågor riktar sig mot samma fysiska partition.
Partitionsnycklar för läsintensiva containrar
För de flesta containrar är ovanstående kriterier allt du behöver tänka på när du väljer en partitionsnyckel. För stora läsintensiva containrar kanske du dock vill välja en partitionsnyckel som ofta visas som ett filter i dina frågor. Frågor kan effektivt dirigeras till endast relevanta fysiska partitioner genom att inkludera partitionsnyckeln i filterpredikatet.
Den här egenskapen kan vara ett bra partitionsnyckelval om de flesta av arbetsbelastningens begäranden är frågor och de flesta av dina frågor har ett likhetsfilter på samma egenskap. Om du till exempel ofta kör en fråga som filtrerar på UserID
skulle valet som partitionsnyckel minska antalet frågor mellan partitioner.UserID
Men om containern är liten har du förmodligen inte tillräckligt med fysiska partitioner för att behöva oroa dig för prestanda för frågor mellan partitioner. De flesta små containrar i Azure Cosmos DB kräver bara en eller två fysiska partitioner.
Om containern kan växa till fler än några fysiska partitioner bör du se till att du väljer en partitionsnyckel som minimerar frågor mellan partitioner. Containern kräver mer än några fysiska partitioner när något av följande är sant:
Containern har över 30 000 RU:er etablerade
Din container lagrar över 100 GB data
Använda objekt-ID som partitionsnyckel
Kommentar
Det här avsnittet gäller främst API:et för NoSQL. Andra API:er, till exempel API:et för Gremlin, stöder inte den unika identifieraren som partitionsnyckel.
Om containern har en egenskap som har ett brett utbud av möjliga värden är det förmodligen ett bra val av partitionsnyckel. Ett möjligt exempel på en sådan egenskap är objekt-ID :t. För små läsintensiva containrar eller skrivintensiva containrar av valfri storlek är objekt-ID:t (/id
) naturligtvis ett bra val för partitionsnyckeln.
Systemegenskapens objekt-ID finns i varje objekt i containern. Du kan ha andra egenskaper som representerar ett logiskt ID för ditt objekt. I många fall är dessa ID:er också bra partitionsnyckelval av samma skäl som objekt-ID:t.
Objekt-ID :t är ett bra partitionsnyckelval av följande skäl:
- Det finns ett stort antal möjliga värden (ett unikt objekt-ID per objekt).
- Eftersom det finns ett unikt objekt-ID per objekt gör objekt-ID:t ett bra jobb med att balansera RU-förbrukning och datalagring jämnt.
- Du kan enkelt göra effektiva punktläsningar eftersom du alltid känner till ett objekts partitionsnyckel om du känner till dess objekt-ID.
Några saker att tänka på när du väljer objekt-ID som partitionsnyckel är:
- Om objekt-ID :t är partitionsnyckeln blir det en unik identifierare i hela containern. Du kan inte skapa objekt som har duplicerade objekt-ID:t.
- Om du har en läsintensiv container med många fysiska partitioner är frågorna mer effektiva om de har ett likhetsfilter med objekt-ID:t.
- Du kan inte köra lagrade procedurer eller utlösare som är inriktade på flera logiska partitioner.