Riktlinjer för datapartitionering

Azure Blob Storage

I många storskaliga lösningar delas data in i partitioner som kan hanteras och nås separat. Partitionering kan förbättra skalbarheten, minska konkurrensen och ge bästa möjliga prestanda. Det kan också ge en mekanism för att dela upp data efter användningsmönster. Du kan till exempel arkivera äldre data i billigare datalagring.

Partitioneringsstrategin måste dock väljas noggrant för att maximera fördelarna samtidigt som negativa effekter minimeras.

Anteckning

I den här artikeln betyder termen partitionering att en process delar in data i fysiskt separata datalager. Det är inte detsamma som SQL Server-tabellpartitionering.

Därför ska du partitionera data

  • Bättre skalbarhet. När du skalar upp ett enskilt databassystem når du så småningom gränsen för den fysiska maskinvaran. Om du delar upp data mellan flera partitioner, som var och en finns på en separat server, kan du skala ut systemet nästan på obestämd tid.

  • Förbättra prestanda. Dataåtkomståtgärder på varje partition sker över en mindre datavolym. Partitionering kan göra systemet mer effektivt på rätt sätt. Åtgärder som påverkar mer än en partition kan köras parallellt.

  • Bättre säkerhet. I vissa fall kan du separera känsliga och meningslösa data i olika partitioner och tillämpa olika säkerhetskontroller på känsliga data.

  • Gör verksamheten flexibel. Partitionering ger många möjligheter till finjusteringsåtgärder, maximera administrativ effektivitet och minimera kostnader. Du kan definiera olika strategier för hantering, övervakning, säkerhetskopiering, återställning och andra administrativa uppgifter, beroende på hur viktiga data i varje partition är.

  • Dela upp datalager efter användningsmönster. Med partitionering kan varje partition distribueras på rätt typ av datalager. Du kan titta på kostnaderna och de inbyggda funktionerna i varje datalager. Till exempel kan stora binära data lagras i bloblagring, medan mer strukturerade data kan lagras i en dokumentdatabas. Se Välja rätt datalager.

  • Bättre tillgänglighet. Genom att dela upp data på flera servrar kan du undvika felkritiska systemdelar. Om en instans misslyckas är endast data i partitionen otillgängliga. Du kan fortsätta att använda andra partitioner som vanligt. För hanterade PaaS-datalager är det här övervägandet mindre relevant eftersom dessa tjänster är utformade med inbyggd redundans.

Utforma partitioner

Det finns tre vanliga strategier för partitionering av data:

  • Horisontell (vågrät) partitionering (kallas även sharding). I den här strategin är varje partition ett separat datalager, men alla partitioner har samma schema. Varje partition kallas för en shard och innehåller en specifik delmängd av data, till exempel alla beställningar för en specifik uppsättning kunder.

  • Vertikal (lodrät) partitionering. Vid vertikal partitionering innehåller varje partition en delmängd av fälten för objekten i datalagret. Fälten är uppdelade enligt användningsmönster. Du kan till exempel placera ofta använda fält i en vertikal partition och fält som används mer sällan i en annan.

  • Funktionell partitionering. Här samlas data enligt hur de används av varje begränsad kontext i systemet. Ett e-handelssystem kan till exempel lagra fakturadata i en partition och produktinventeringsdata i en annan.

Dessa strategier kan kombineras och vi rekommenderar att du överväger dem alla när du utformar ett partitioneringsschema. Du kan till exempel dela upp data i fragment och sedan dela upp ytterligare inom fragmenten med vertikal partitionering.

Horisontell partitionering (sharding)

Bild 1 visar horisontell partitionering eller horisontell partitionering. I det här exemplet är produktlagerdata uppdelade baserat på produktnyckeln. Varje fragment innehåller data för ett sammanhängande intervall fragmentnycklar (A-G och H-Z), ordnade i alfabetisk ordning. Horisontell partitionering sprider belastningen över fler datorer, vilket minskar konkurrensen och förbättrar prestandan.

Horisontell partitionering (sharding) av data baserat på partitionsnyckel

Bild 1 – Horisontell partitionering av data (horisontell partitionering) baserat på en partitionsnyckel.

Den viktigaste faktorn är valet av en horisontell partitioneringsnyckel. Det kan vara svårt att ändra nyckeln när systemet väl är i drift. Nyckeln måste se till att data partitioneras för att sprida arbetsbelastningen så jämnt som möjligt över fragmenten.

Fragmenten behöver inte ha samma storlek. Det är viktigare att balansera antalet begäranden. Vissa shards kan vara mycket stora, men varje objekt har ett lågt antal åtkomståtgärder. Andra fragment kan vara mindre, men varje objekt används oftare. Det är också viktigt att se till att ett enskilt fragment inte överskrider skalningsgränserna (när det gäller kapacitet och bearbetningsresurser) för datalagret.

Undvik att skapa "frekventa" partitioner som kan påverka prestanda och tillgänglighet. Om du till exempel använder den första bokstaven i en kunds namn uppstår en obalanserad fördelning, eftersom vissa bokstäver är vanligare. Använd i stället en hash för en kundidentifierare för att distribuera data jämnare mellan partitioner.

Välj en horisontell partitioneringsnyckel som minimerar framtida krav för att dela upp stora shards, slå samman små shards i större partitioner eller ändra schemat. Dessa åtgärder kan var mycket tidskrävande och du kan behöva stänga ned ett eller flera fragment under tiden de utförs.

Om fragment replikeras kan det vara möjligt att behålla vissa repliker online medan andra delas, sammanfogas och konfigureras om. Systemet kan dock behöva begränsa de åtgärder som kan utföras under omkonfigurationen. Data i replikerna kan till exempel markeras som skrivskyddade för att förhindra datainkonsekvenser.

Mer information om horisontell partitionering finns i mönster för horisontell partitionering.

Vertikal partitionering

Den vanligaste användningen för vertikal partitionering är att minska I/O- och prestandakostnaderna för att hämta objekt som används ofta. I bild 2 visas ett exempel på vertikal partitionering. I det här exemplet lagras olika egenskaper för ett objekt i olika partitioner. En partition innehåller data som används oftare, inklusive produktnamn, beskrivning och pris. En annan partition innehåller inventeringsdata: lagerantal och senaste beställningsdatum.

Vertikalt partitionerade data efter användningsmönster

Bild 2 – Vertikal partitionering av data med dess användningsmönster.

I det här exemplet frågar programmet regelbundet efter produktens namn, beskrivning och pris när produktinformation visas för kunder. Lagerantal och senaste sorteringsdatum lagras i en separat partition eftersom dessa två objekt ofta används tillsammans.

Andra fördelar med vertikal partitionering:

  • Relativt långsamma data (produktnamn, beskrivning och pris) kan separeras från mer dynamiska data (lagernivå och senaste beställningsdatum). Långsamma data är en bra kandidat för att ett program ska cachelagrat i minnet.

  • Känsliga data kan lagras i en separat partition med ytterligare säkerhetskontroller.

  • Vertikal partitionering kan minska mängden samtidig åtkomst som behövs.

Vertikal partitionering fungerar på enhetsnivå inom datalagret. En enhet normaliseras delvis för att bryta ned den från ett brett objekt till en uppsättning mer begränsade objekt. Det passar väl för kolumnorienterade datalager, exempelvis HBase och Cassandra. Om data i en samling kolumner sannolikt inte kommer att ändras kan du överväga att använda kolumnlager i SQL Server.

Funktionell partitionering

När det är möjligt att identifiera en avgränsad kontext för varje distinkt affärsområde i ett program är funktionell partitionering ett sätt att förbättra isolerings- och dataåtkomstprestanda. En annan vanlig användning för funktionell partitionering är att separera skrivskyddade data från skrivskyddade data. I bild 3 visas en översikt över funktionell partitionering där lagerdata avgränsas från kunddata.

Data med funktionell partitionering, per begränsad kontext eller underdomän

Bild 3 – Funktionell partitionering av data via begränsad kontext eller underdomän.

Den här partitioneringsstrategin kan minska konkurrensen i dataåtkomsten i olika delar av ett system.

Utforma partitioner för skalbarhet

Det är viktigt att beakta storlek och arbetsbelastning för varje partition och balansera dem så att data distribueras för maximal skalbarhet. Du måste också partitionera data så att du inte överskrider skalningsgränserna för något enskilt partitionslager.

Följ de här stegen när du skapar partitioner för skalbarhet:

  1. Analysera programmet för att få förståelse för dataåtkomstmönstren. Det kan vara storleken på resultatuppsättningen för varje fråga, åtkomstfrekvensen, den inneboende latensen och beräkningskraven på serversidan. I många fall kräver några få större enheter de flesta bearbetningsresurserna.
  2. Använd den här analysen för att bestämma aktuella och framtida skalbarhetsmål, till exempel datastorlek och arbetsbelastning. Distribuera sedan data över partitionerna för att uppfylla skalbarhetsmålen. För horisontell partitionering är det viktigt att välja rätt shardnyckel för att se till att distributionen är jämn. Mer information finns i mönstret för horisontell partitionering.
  3. Kontrollera att varje partition har tillräckligt med resurser för att hantera skalbarhetskraven när det gäller datastorlek och dataflöde. Beroende på datalagret kan det finnas en gräns för mängden lagringsutrymme, bearbetningskraft eller nätverksbandbredd per partition. Om kraven sannolikt överskrider dessa gränser kan du behöva förfina partitioneringsstrategin eller dela upp data ytterligare, eventuellt genom att kombinera två eller flera strategier.
  4. Övervaka systemet för att kontrollera att data distribueras som förväntat och att partitionerna kan hantera belastningen. Den faktiska användningen matchar inte alltid vad en analys förutsäger. I så fall kan det vara möjligt att balansera om partitionerna, eller omdesigna vissa delar av systemet för att få det saldo som krävs.

Vissa molnmiljöer allokerar resurser när det gäller infrastrukturgränser. Se till att de gränser du väljer ger tillräckligt utrymme för eventuell datatillväxt, vad gäller datalagring, bearbetningskraft och bandbredd.

Om du till exempel använder Azure Table Storage finns det en gräns för mängden begäranden som kan hanteras av en enskild partition under en viss tidsperiod. (Mer information finns i Skalbarhets- och prestandamål för Azure Storage.) En upptagen shard kan kräva fler resurser än en enskild partition kan hantera. I så fall kan fragmentet behöva partitioneras om för att sprida belastningen. Om den totala storleken eller dataflödet för dessa tabeller överskrider kapaciteten för ett lagringskonto kan du behöva skapa ytterligare lagringskonton och sprida tabellerna över dessa konton.

Designa partitioner för frågeprestanda

Det går ofta att höja frågeprestanda genom att använda mindre datauppsättningar och köra parallella förfrågningar. Varje partition bör innehålla en liten del av hela datauppsättningen. Den här minskningen i volym kan ge bättre prestanda för frågor. Partitionering är däremot inget alternativ för att utforma och konfigurera en databas på lämpligt sätt. Kontrollera till exempel att du har de nödvändiga indexen på plats.

Följ de här stegen när du skapar partitioner för frågeprestanda:

  1. Granska kraven på program och prestanda:

    • Använd affärskrav för att fastställa de kritiska frågor som alltid måste utföras snabbt.
    • Övervaka systemet för att identifiera frågor som utförs för långsamt.
    • Ta reda på vilka frågor som utförs oftast. Även om en enskild fråga har en minimal kostnad kan den kumulativa resursförbrukningen vara betydande.
  2. Partitionera data som sänker prestanda:

    • Begränsa storleken på varje partition så att svarstiden för frågorna ligger inom målet.
    • Om du använder horisontell partitionering utformar du shardnyckeln så att programmet enkelt kan välja rätt partition. Frågan slipper att söka igenom varje partition.
    • Överväg placeringen av partitionen. Försök om möjligt att lagra data i partitioner som ligger geografiskt nära program och användare som har åtkomst till dem.
  3. Om en entitet har krav på genomflöde och frågeprestanda ska du använda funktionell partitionering baserad på den enheten. Om det fortfarande inte uppfyller kraven ska du tillämpa horisontell partitionering också. I de flesta fall räcker det med en enda partitioneringsstrategi, men i vissa fall är det mer effektivt att kombinera båda strategierna.

  4. Överväg att köra frågor parallellt mellan partitioner för att förbättra prestanda.

Utforma partitioner för tillgänglighet

Genom att partitionera data kan du förbättra tillgängligheten för program genom att se till att hela datauppsättningar inte utför en enskild felpunkt. De enskilda delmängderna data kan hanteras oberoende av varandra.

Tänk på följande faktorer som påverkar tillgängligheten:

Hur kritiska data är för verksamheten. Identifiera vilka data som är viktig affärsinformation, till exempel transaktioner, och vilka data som är mindre kritiska driftdata, till exempel loggfiler.

  • Överväg att lagra kritiska data i partitioner med hög tillgänglighet med en lämplig säkerhetskopieringsplan.

  • Upprätta separata hanterings- och övervakningsförfaranden för de olika datauppsättningarna.

  • Placera data med samma prioritetsnivå i samma partition, så att den kan säkerhetskopieras tillsammans med lämplig frekvens. Till exempel kan partitioner som innehåller transaktionsdata behöva säkerhetskopieras oftare än partitioner som innehåller loggnings- eller spårningsinformation.

Så kan du hantera enskilda partitioner. Det finns flera fördelar med att utforma partitioner så att de går att hantera och underhålla oberoende av andra. Exempel:

  • Om en partition misslyckas kan den återställas oberoende av varandra utan program som har åtkomst till data i andra partitioner.

  • Genom att partitionera data efter geografiskt område kan du schemalägga underhåll så att det sker vid tidpunkter med låg belastning för varje plats. Se till att partitionerna inte är för stora för att förhindra att planerat underhåll slutförs under den här perioden.

Överväga att replikera data på kritiska partitioner. Den här strategin kan förbättra tillgängligheten och prestandan, men kan också medföra konsekvensproblem. Det tar tid att synkronisera ändringar med varje replik. Under den här tiden innehåller olika partitioner olika datavärden.

Designöverväganden för program

Partitionering ökar komplexiteten i systemets design och utveckling. Överväg att lägga in partitionering som grundläggande del i systemutformningen, även om systemet till en början bara har en enda partition. Om du hanterar partitionering som en eftertanke blir det svårare eftersom du redan har ett live-system att underhålla:

  • Dataåtkomstlogik måste ändras.
  • Stora mängder befintliga data kan behöva migreras för att distribuera dem mellan partitioner.
  • Användarna förväntar sig att kunna fortsätta använda systemet under migreringen.

I vissa fall anses partitionering inte vara viktigt, eftersom den initiala datauppsättningen är liten och enkelt kan hanteras på en server. Detta kan vara sant för vissa arbetsbelastningar, men många kommersiella system måste utökas när antalet användare ökar.

Dessutom är det inte bara stora datalager som har nytta av partitionering. Ett litet datalager kan till exempel ha kraftig trafik med hundratals samtidiga klienter. Om du i det här läget partitionerar data kan det minska konkurrensen och förbättra genomflödet.

Tänk på det här när du utformar datapartitioneringsscheman:

Minimera dataåtkomståtgärder mellan partitioner. Håll om möjligt samman data för de vanligaste databasåtgärderna i varje partition. Då undviker du korsåtkomst till data på flera olika partitioner. Det kan vara mer tidskrävande att fråga mellan partitioner än att fråga inom en enda partition, men optimering av partitioner för en uppsättning frågor kan påverka andra uppsättningar frågor negativt. Om du måste fråga mellan partitioner minimerar du frågetiden genom att köra parallella frågor och aggregera resultaten i programmet. (Den här metoden är kanske inte möjlig i vissa fall, till exempel när resultatet från en fråga används i nästa fråga.)

Överväg att replikera statiska referensdata. Om frågor använder relativt statiska referensdata, till exempel postnummertabeller eller produktlistor, bör du överväga att replikera dessa data i alla partitioner för att minska separata uppslagsåtgärder i olika partitioner. Den här metoden kan också minska sannolikheten för att referensdata blir en "frekvent" datauppsättning, med tung trafik från hela systemet. Det finns dock en extra kostnad som är associerad med synkronisering av eventuella ändringar av referensdata.

Minimera kopplingar mellan partitioner. När det är möjligt ska du minimera kraven på referensintegritet mellan lodräta och funktionella partitioner. I dessa scheman ansvarar programmet för att upprätthålla referensintegriteten mellan partitioner. Frågor som kopplar data över flera partitioner är ineffektiva eftersom programmet vanligtvis behöver utföra efterföljande frågor baserat på en nyckel och sedan en sekundärnyckel. Överväg istället att replikera eller avnormalisera relevanta data. Om det krävs kopplingar mellan partitioner kör du parallella frågor över partitionerna och ansluter data i programmet.

Tänk på den slutliga konsekvensen. Utvärdera om stark konsekvens är ett faktiskt krav. En vanlig metod i distribuerade system är att implementera slutlig konsekvens. Data i varje partition uppdateras separat och programlogiken säkerställer att alla uppdateringar slutförs. Den hanterar också inkonsekvenser som kan uppstå om datafrågor skickas medan en eventuellt överensstämmande åtgärd körs.

Fundera på hur frågor hittar rätt partition. Om en fråga måste genomsöka alla partitioner för att hitta data ger det betydande prestandapåverkan, även när flera frågor körs parallellt. Med vertikal och funktionell partitionering kan frågor ange partitionen naturligt. Horisontell partitionering kan å andra sidan göra det svårt att hitta ett objekt, eftersom varje fragment har samma schema. En typisk lösning för att underhålla en karta som används för att söka efter shardplatsen för specifika objekt. Kartan kan implementeras i shardinglogiken i programmet. Det går också att underhålla den via datalagret, om det finns funktioner för transparent partitionering.

Överväg att regelbundet ombalansera shards. Med horisontell partitionering kan ombalansering av shards hjälpa till att fördela data jämnt efter storlek och arbetsbelastning för att minimera hotspots, maximera frågeprestanda och kringgå begränsningar för fysisk lagring. Det här är dock en komplicerad uppgift som ofta kräver anpassade verktyg och processer.

Replikera partitioner. Om du replikerar varje partition får du ytterligare skydd mot fel. Om en enskild replik misslyckas kan frågor riktas mot en fungerande kopia.

Om du når de fysiska begränsningarna för en partitioneringsstrategi kan du behöva utöka skalbarheten en nivå. Om du till exempel partitionerar på databasnivå kan behöva du hitta eller replikera partitioner i flera databaser. Om du redan partitionerar på databasnivå och det finns problem med fysiska begränsningar kan du behöva hitta eller replikera partitioner i flera värdkonton.

Undvik transaktioner som kommer åt data i flera partitioner. Vissa datalager implementerar transaktionell konsekvens och integritet för åtgärder som ändrar data, men bara när data finns i en enda partition. Om du behöver transaktionell konsekvens för flera partitioner måste du sannolikt lägga in det i programlogiken. De flesta partitioneringssystem har inte inbyggda funktioner för det här.

Alla datalager kräver viss operativ hantering och övervakning. Det kan vara allt från inläsning, säkerhetskopiering, återställning och omorganisering av data till att se till att systemet fungerar och är effektivt.

Tänk på de här faktorerna som påverkar den operativa hanteringen:

  • Lämplig hantering och lämpliga åtgärder när data partitioneras. Det kan handla om säkerhetskopiering, återställning, dataarkivering, systemövervakning och andra administrativa uppgifter. Det kan till exempel vara en utmaning att upprätthålla logisk konsekvens under säkerhetskopieringar och återställningar.

  • Inläsning av data till flera partitioner och tillägg av nya data från andra källor. I vissa verktyg och hjälpmedel finns inte funktioner för fragmenterade dataåtgärder (sharding), som att läsa in data till rätt partition.

  • Regelbunden arkivering och borttagning av data. För att förhindra överdriven tillväxt av partitioner måste du arkivera och ta bort data regelbundet (till exempel varje månad). Du kan behöva transformera data så att de passar ett annat arkiveringsschema.

  • Hitta problem med dataintegriteten. Överväg att köra en periodisk process för att hitta eventuella dataintegritetsproblem, till exempel data i en partition som refererar till information som saknas i en annan. Processen kan antingen försöka åtgärda dessa problem automatiskt eller generera en rapport för manuell granskning.

Balansera om partitioner

När ett system mognar kan du behöva justera partitioneringsschemat. Enskilda partitioner kan till exempel börja få en oproportionerlig mängd trafik och bli frekventa, vilket leder till överdriven konkurrens. Eller så kanske du har underskattat mängden data i vissa partitioner, vilket gör att vissa partitioner närmar sig kapacitetsbegränsningar.

Vissa datalager, till exempel Azure Cosmos DB, kan automatiskt balansera om partitioner. I andra fall är ombalansering en administrativ uppgift som består av två steg:

  1. Fastställ en ny partitioneringsstrategi.

    • Vilka partitioner måste delas upp (eller eventuellt kombineras)?
    • Vad är den nya partitionsnyckeln?
  2. Migrera data från det gamla partitioneringsschemat till den nya uppsättningen partitioner.

Beroende på datalagret kanske du kan migrera data mellan partitioner när de används. Detta kallas onlinemigrering. Om det inte är möjligt kan du behöva göra partitioner otillgängliga när data flyttas (offlinemigrering).

Offlinemigrering

Offlinemigrering är vanligtvis enklare eftersom det minskar risken för konkurrens. Begreppsmässigt fungerar offlinemigrering på följande sätt:

  1. Markera partitionen som offline.
  2. Dela samman och flytta data till de nya partitionerna.
  3. Kontrollera data.
  4. Ta de nya partitionerna online.
  5. Ta bort den gamla partitionen.

Du kan också markera en partition som skrivskyddad i steg 1, så att program fortfarande kan läsa data medan de flyttas.

Onlinemigrering

Onlinemigrering är mer komplext att utföra men mindre störande. Processen liknar offlinemigrering, förutom att den ursprungliga partitionen inte är markerad som offline. Beroende på migreringsprocessens kornighet (till exempel objekt efter objekt jämfört med shard av shard) kan dataåtkomstkoden i klientprogrammen behöva hantera läsning och skrivning av data som lagras på två platser, den ursprungliga partitionen och den nya partitionen.

Nästa steg

Följande designmönster kan vara relevanta för ditt scenario:

  • Mönstret för horisontell partitionering beskriver några vanliga strategier för horisontell partitionering av data.

  • Indextabellmönstret visar hur du skapar sekundära index över data. Med den här metoden kan ett program snabbt hämta data via frågor som inte refererar till den primära nyckeln i en samling.

  • Det materialiserade vymönstret beskriver hur du genererar förifyllda vyer som sammanfattar data för att stödja snabba frågeåtgärder. Den här metoden kan vara användbar i partitionerade datalager, om de partitioner som innehåller de data som summeras är fördelade på flera platser.