Utforma en skalbar partitioneringsstrategi för Azure Table Storage
Den här artikeln beskriver partitionering av en tabell i Azure Table Storage och strategier som du kan använda för att säkerställa effektiv skalbarhet.
Azure tillhandahåller molnlagring som är mycket tillgängligt och mycket skalbart. Det underliggande lagringssystemet för Azure tillhandahålls via en uppsättning tjänster, inklusive Azure Blob Storage, Azure Table Storage, Azure Queue Storage och Azure Files.
Azure Table Storage är utformat för att lagra strukturerade data. Azure Storage-tjänsten stöder ett obegränsat antal tabeller. Varje tabell kan skalas till enorma nivåer och tillhandahålla terabyte fysisk lagring. För att du ska kunna dra nytta av tabeller på bästa sätt måste du partitionera dina data optimalt. Den här artikeln utforskar strategier som du kan använda för att effektivt partitioneras data för Azure Table Storage.
Tabellentiteter
Tabellentiteter representerar de dataenheter som lagras i en tabell. Tabellentiteter liknar rader i en typisk relationsdatabastabell. Varje entitet definierar en samling egenskaper. Varje egenskap definieras som ett nyckel/värde-par med dess namn, värde och värdets datatyp. Entiteter måste definiera följande tre systemegenskaper som en del av egenskapssamlingen:
PartitionKey: Egenskapen PartitionKey lagrar strängvärden som identifierar partitionen som en entitet tillhör. Partitioner är, som vi diskuterar senare, en integrerad del av tabellens skalbarhet. Entiteter som har samma PartitionKey-värde lagras i samma partition.
RowKey: Egenskapen RowKey lagrar strängvärden som unikt identifierar entiteter inom varje partition. PartitionKey och RowKey utgör tillsammans den primära nyckeln för entiteten.
Tidsstämpel: Tidsstämpelegenskapen ger spårbarhet för en entitet. En tidsstämpel är ett datum/tid-värde som anger när entiteten senast ändrades. En tidsstämpel kallas ibland entitetens version. Ändringar av tidsstämplar ignoreras eftersom tabelltjänsten behåller värdet för den här egenskapen under alla infognings- och uppdateringsåtgärder.
Primärnyckel för tabell
Primärnyckeln för en Azure-entitet består av de kombinerade egenskaperna PartitionKey och RowKey . De två egenskaperna utgör ett enda grupperat index i tabellen. Värdena PartitionKey och RowKey kan vara upp till 1 024 tecken stora. Tomma strängar tillåts också. Null-värden tillåts dock inte.
Det klustrade indexet sorterar efter PartitionKey i stigande ordning och sedan efter RowKey i stigande ordning. Sorteringsordningen observeras i alla frågesvar. Lexikala jämförelser används under sorteringsåtgärden. Ett strängvärde på "111" visas före ett strängvärde på "2". I vissa fall kanske du vill att sorteringsordningen ska vara numerisk. Om du vill sortera i en numerisk och stigande ordning måste du använda strängar med fast längd och noll vadderade strängar. I föregående exempel visas "002" före "111".
Tabellpartitioner
Partitioner representerar en samling entiteter med samma PartitionKey-värden . Partitioner hanteras alltid från en partitionsserver. Varje partitionsserver kan hantera en eller flera partitioner. En partitionsserver har en hastighetsgräns för hur många entiteter den kan hantera från en partition över tid. Mer specifikt har en partition ett skalbarhetsmål på 2 000 entiteter per sekund. Det här dataflödet kan vara högre vid minimal belastning på lagringsnoden, men det begränsas när noden blir frekvent eller aktiv.
För att bättre illustrera begreppet partitionering visar följande bild en tabell som innehåller en liten delmängd data för registreringar av fotloppshändelser. Bilden visar en konceptuell vy över partitionering där PartitionKey innehåller tre olika värden: händelsens namn kombinerat med tre avstånd (fullständigt maraton, halvmaraton och 10 km). I det här exemplet används två partitionsservrar. Server A innehåller registreringar för halvmaraton och 10 km avstånd. Server B innehåller endast helmaratonavstånd. RowKey-värdena visas för att ge kontext, men värdena är inte meningsfulla för det här exemplet.
En tabell med tre partitioner
Skalbarhet
Eftersom en partition alltid hanteras från en enskild partitionsserver och varje partitionsserver kan hantera en eller flera partitioner, korreleras effektiviteten för att betjäna entiteter med serverns hälsotillstånd. Servrar som stöter på hög trafik för sina partitioner kanske inte kan upprätthålla ett högt dataflöde. Om till exempel många begäranden för "2011 New York City Marathon__Half" tas emot i föregående bild kan server A bli för frekvent. För att öka dataflödet för servern belastningsutjämnas partitionerna till andra servrar i lagringssystemet. Resultatet är att trafiken distribueras över många andra servrar. För optimal belastningsutjämning av trafik bör du använda fler partitioner så att Azure Table Storage kan distribuera partitionerna till fler partitionsservrar.
Entitetsgrupptransaktioner
En entitetsgrupptransaktion är en uppsättning lagringsåtgärder som implementeras atomiskt på entiteter som har samma PartitionKey-värde . Om någon lagringsåtgärd i entitetsgruppen misslyckas återställs alla lagringsåtgärder i entiteten. En entitetsgrupptransaktion består av högst 100 lagringsåtgärder och kanske inte är större än 4 MiB. Entitetsgrupptransaktioner ger Azure Table Storage en begränsad form av semantiken atomicitet, konsekvens, isolering och hållbarhet (ACID) som tillhandahålls av relationsdatabaser.
Entitetsgrupptransaktioner förbättrar dataflödet eftersom de minskar antalet enskilda lagringsåtgärder som måste skickas till Azure Table Storage. Entitetsgrupptransaktioner ger också en ekonomisk fördel. En entitetsgrupptransaktion faktureras som en enda lagringsåtgärd oavsett hur många lagringsåtgärder den innehåller. Eftersom alla lagringsåtgärder i en entitetsgrupptransaktion påverkar entiteter som har samma PartitionKey-värde kan ett behov av att använda entitetsgrupptransaktioner driva valet av PartitionKey-värde .
Intervallpartitioner
Om du använder unika PartitionKey-värden för dina entiteter hör varje entitet till sin egen partition. Om de unika värden som du använder ökar eller minskar i värde är det möjligt att Azure skapar intervallpartitioner. Intervallpartitioner grupperar entiteter som har sekventiella, unika PartitionKey-värden för att förbättra prestandan för intervallfrågor. Utan intervallpartitioner måste en intervallfråga korsa partitionsgränser eller servergränser, vilket kan minska frågeprestandan. Överväg ett program som använder följande tabell, som har ett ökande sekvensvärde för PartitionKey:
PartitionKey | RowKey |
---|---|
"0001" | - |
"0002" | - |
"0003" | - |
"0004" | - |
"0005" | - |
"0006" | - |
Azure kan gruppera de tre första entiteterna i en intervallpartition. Om du använder en intervallfråga i tabellen som använder PartitionKey som kriterier och begär entiteter från "0001" till "0003" kan frågan fungera effektivt eftersom entiteterna hanteras från en enda partitionsserver. Det finns ingen garanti för när och hur en intervallpartition ska skapas.
Förekomsten av intervallpartitioner för tabellen kan påverka prestandan för dina infogningsåtgärder om du infogar entiteter som har ökande eller minskande PartitionKey-värden . Infogning av entiteter som har ökande PartitionKey-värden kallas för ett tilläggsmönster. Infogning av entiteter som har fallande värden kallas för ett prepend-only-mönster. Överväg att inte använda den här typen av mönster eftersom det totala dataflödet för dina infogningsbegäranden begränsas av en enda partitionsserver. Detta beror på att om det finns intervallpartitioner innehåller de första och sista partitionerna (intervall) de minst respektive största PartitionKey-värdena . Därför är infogningen av en ny entitet, en som har ett sekventiellt lägre eller högre PartitionKey-värde , mål för en av slutpartitionerna. Följande bild visar en möjlig uppsättning intervallpartitioner som baseras på föregående exempel. Om en uppsättning "0007", "0008" och "0009"-entiteter infogades, skulle de tilldelas till den sista (orange) partitionen.
En uppsättning intervallpartitioner
Observera att prestanda inte påverkas negativt om infogningsåtgärderna använder PartitionKey-värden som är mer spridda.
Analysera data
Till skillnad från en tabell i en relationsdatabas som du kan använda för att hantera index kan tabeller i Azure Table Storage bara ha ett index. Ett index i Azure Table Storage består alltid av egenskaperna PartitionKey och RowKey .
I en Azure-tabell har du inte lyxen att prestandajustera tabellen genom att lägga till fler index eller genom att ändra en befintlig tabell när du har distribuerat den. Du måste analysera data när du utformar tabellen. De viktigaste aspekterna att tänka på för optimal skalbarhet och för fråge- och infogningseffektivitet är värdena PartitionKey och RowKey . Den här artikeln beskriver hur du väljer PartitionKey eftersom den direkt relaterar till hur tabeller partitioneras.
Partitionsstorlek
Partitionsstorlek avser antalet entiteter som en partition innehåller. När vi diskuterar skalbarhet innebär fler partitioner att du får bättre belastningsutjämning. PartitionKey-värdets kornighet påverkar storleken på partitionerna. På den grövste nivån, om ett enda värde används som PartitionKey, finns alla entiteter i en enda partition som är mycket stor. På den högsta detaljnivån kan PartitionKey innehålla unika värden för varje entitet. Resultatet är att det finns en partition för varje entitet. I följande tabell visas fördelar och nackdelar med kornighetsintervallet:
PartitionKey-kornighet | Partitionsstorlek | Fördelar | Nackdelar |
---|---|---|---|
Enskilt värde | Litet antal entiteter | Batchtransaktioner är möjliga med valfri entitet. Alla entiteter är lokala och hanteras från samma lagringsnod. |
|
Enskilt värde | Stort antal entiteter | Entitetsgrupptransaktioner kan vara möjliga med valfri entitet. Mer information om gränserna för entitetsgrupptransaktioner finns i Utföra entitetsgrupptransaktioner. | Skalningen är begränsad. Dataflödet är begränsat till prestanda för en enskild server. |
Flera värden | Flera partitioner Partitionsstorlekar beror på entitetsdistribution. |
Batchtransaktioner är möjliga för vissa entiteter. Dynamisk partitionering är möjlig. Frågor med en begäran är möjliga (inga fortsättningstoken). Belastningsutjämning över fler partitionsservrar är möjligt. |
En mycket ojämn fördelning av entiteter mellan partitioner kan begränsa prestanda för större och mer aktiva partitioner. |
Unika värden | Många små partitioner | Tabellen är mycket skalbar. Intervallpartitioner kan förbättra prestandan för frågor mellan partitioner. |
Frågor som omfattar intervall kan kräva besök på mer än en server. Batchtransaktioner är inte möjliga. Mönster med endast tillägg eller endast förberedelse kan påverka infogningsdataflödet. |
Tabellen visar hur skalning påverkas av PartitionKey-värden . Det är en bra idé att prioritera mindre partitioner eftersom de ger bättre belastningsutjämning. Större partitioner kan vara lämpliga i vissa scenarier och de är inte nödvändigtvis ofördelaktiga. Om ditt program till exempel inte kräver skalbarhet kan en enda stor partition vara lämplig.
Fastställa frågor
Frågor hämtar data från tabeller. När du analyserar data för en tabell i Azure Table Storage är det viktigt att överväga vilka frågor programmet ska använda. Om ett program har flera frågor kan du behöva prioritera dem, även om dina beslut kan vara subjektiva. I många fall kan dominerande frågor urskiljas från andra frågor. När det gäller prestanda delas frågorna in i olika kategorier. Eftersom en tabell bara har ett index är frågeprestanda vanligtvis relaterade till egenskaperna PartitionKey och RowKey . I följande tabell visas de olika typerna av frågor och deras prestandaklassificeringar:
Frågetyp | PartitionKey-matchning | RowKey-matchning | Prestandaklassificering |
---|---|---|---|
Genomsökning av radintervall | Exact | Delvis | Bättre med partitioner med mindre storlek. Dåligt med partitioner som är mycket stora. |
Genomsökning av partitionsintervall | Delvis | Delvis | Bra med ett litet antal partitionsservrar som rörs. Värre med fler servrar som rörs. |
Fullständig tabellgenomsökning | Partiell, ingen | Partiell, ingen | Värre med en delmängd partitioner som genomsöks. Sämst med alla partitioner som genomsöks. |
Anteckning
Tabellen definierar prestandaklassificeringar i förhållande till varandra. Partitionernas antal och storlek kan i slutändan avgöra hur frågan presterar. En partitionsintervallsökning efter en tabell som har många stora partitioner kan till exempel fungera dåligt jämfört med en fullständig tabellsökning efter en tabell som har några små partitioner.
De frågetyper som anges i föregående tabell visar en status från de bästa typerna av frågor att använda till de sämsta typerna, baserat på deras prestandaklassificeringar. Punktfrågor är de bästa typerna av frågor att använda eftersom de helt använder tabellens klustrade index. Följande punktfråga använder data från registreringstabellen för fotlopp:
http://<account>.windows.core.net/registrations(PartitionKey=”2011 New York City Marathon__Full”,RowKey=”1234__John__M__55”)
Om programmet använder flera frågor kan inte alla vara punktfrågor. När det gäller prestanda följer intervallfrågor punktfrågor. Det finns två typer av intervallfrågor: genomsökning av radintervall och genomsökning av partitionsintervall. Genomsökningen av radintervallet anger en enda partition. Eftersom åtgärden utförs på en enda partitionsserver är radintervallgenomsökningar vanligtvis effektivare än genomsökningar av partitionsintervall. En viktig faktor i prestandan för radintervallgenomsökningar är dock hur selektiv en fråga är. Frågans selektivitet avgör hur många rader som måste itereras för att hitta matchande rader. Mer selektiva frågor är mer effektiva vid genomsökningar av radintervall.
Om du vill utvärdera prioriteringarna för dina frågor bör du överväga kraven på frekvens- och svarstid för varje fråga. Frågor som körs ofta kan prioriteras högre. En viktig men sällan använd fråga kan dock ha krav på låg svarstid som kan rangordna den högre i prioritetslistan.
Välj värdet PartitionKey
Kärnan i en tabells design är dess skalbarhet, de frågor som används för att komma åt den och krav på lagringsåtgärd. De PartitionKey-värden som du väljer avgör hur en tabell partitioneras och vilken typ av frågor du kan använda. Lagringsåtgärder, och särskilt infogningar, kan också påverka ditt val av PartitionKey-värden . PartitionKey-värdena kan variera från enskilda värden till unika värden. De kan också skapas med hjälp av flera värden. Du kan använda entitetsegenskaper för att skapa värdet PartitionKey . Eller så kan programmet beräkna värdet. I följande avsnitt beskrivs viktiga överväganden.
Entitetsgrupptransaktioner
Utvecklare bör först överväga om programmet ska använda entitetsgrupptransaktioner (batchuppdateringar). Entitetsgrupptransaktioner kräver att entiteter har samma PartitionKey-värde . Eftersom batchuppdateringar gäller för en hel grupp kan också alternativen för PartitionKey-värden vara begränsade. Ett bankprogram som underhåller kontanttransaktioner måste till exempel infoga kontanttransaktioner i tabellen atomiskt. Kontanttransaktioner representerar både debet- och kreditsidorna och måste netto till noll. Det här kravet innebär att kontonumret inte kan användas som någon del av PartitionKey-värdet eftersom varje sida av transaktionen använder olika kontonummer. I stället kan ett transaktions-ID vara ett bättre alternativ.
Partitioner
Partitionsnummer och -storlekar påverkar skalbarheten för en tabell som är under belastning. De styrs också av hur detaljerade PartitionKey-värdena är. Det kan vara svårt att fastställa PartitionKey baserat på partitionsstorleken, särskilt om fördelningen av värden är svår att förutsäga. En bra tumregel är att använda flera mindre partitioner. Många tabellpartitioner gör det enklare för Azure Table Storage att hantera lagringsnoderna som partitionerna hanteras från.
Om du väljer unika eller finare värden för PartitionKey blir partitionerna mindre men fler. Detta är vanligtvis fördelaktigt eftersom systemet kan belastningsutjämning många partitioner för att distribuera belastningen över många partitioner. Du bör dock överväga effekten av att ha många partitioner på frågor mellan partitioner. Dessa typer av frågor måste besöka flera partitioner för att uppfylla en fråga. Det är möjligt att partitionerna distribueras över många partitionsservrar. Om en fråga korsar en servergräns måste fortsättningstoken returneras. Fortsättningstoken anger nästa PartitionKey - eller RowKey-värden för att hämta nästa uppsättning data för frågan. Med andra ord representerar fortsättningstoken minst en begäran till tjänsten, vilket kan försämra frågans övergripande prestanda.
Frågans selektivitet är en annan faktor som kan påverka frågans prestanda. Frågeväljare är ett mått på hur många rader som måste itereras för varje partition. Ju mer selektiv en fråga är, desto effektivare är frågan när du returnerar de rader du vill ha. Den övergripande prestandan för intervallfrågor kan bero på antalet partitionsservrar som måste vidröras eller hur selektiv frågan är. Du bör också undvika att använda tilläggs- eller prepend-only-mönstren när du infogar data i tabellen. Om du använder dessa mönster, trots att du skapar små och många partitioner, kan du begränsa dataflödet för dina infogningsåtgärder. Mönstren för endast tillägg och endast förberedelse beskrivs i Intervallpartitioner.
Frågor
Att känna till de frågor som du ska använda kan hjälpa dig att avgöra vilka egenskaper som är viktiga att tänka på för PartitionKey-värdet . De egenskaper som du använder i frågorna är kandidater för partitionsnyckelvärdet . Följande tabell innehåller en allmän riktlinje för hur du fastställer partitionsnyckelvärdet :
Om entiteten... | Åtgärd |
---|---|
Har en nyckelegenskap | Använd den som PartitionKey. |
Har två nyckelegenskaper | Använd den ena som PartitionKey och den andra som RowKey. |
Har fler än två nyckelegenskaper | Använd en sammansatt nyckel med sammanfogade värden. |
Om det finns fler än en lika dominerande fråga kan du infoga informationen flera gånger med hjälp av olika RowKey-värden som du behöver. Ditt program hanterar sekundära (eller tertiära och så vidare) rader. Du kan använda den här typen av mönster för att uppfylla prestandakraven för dina frågor. I följande exempel används data från exemplet med registrering av fotlopp. Den har två dominerande frågor:
- Fråga efter nummerlapp
- Fråga efter ålder
Om du vill hantera båda de dominerande frågorna infogar du två rader som en entitetsgrupptransaktion. I följande tabell visas egenskaperna PartitionKey och RowKey för det här scenariot. RowKey-värdena ger ett prefix för haklapp och ålder så att programmet kan skilja mellan de två värdena.
PartitionKey | RowKey |
---|---|
2011 New York City Marathon__Full | BIB:01234__John__M__55 |
2011 New York City Marathon__Full | ÅLDER:055__1234__John__M |
I det här exemplet är en entitetsgrupptransaktion möjlig eftersom PartitionKey-värdena är desamma. Grupptransaktionen ger atomicitet för infogningsåtgärden. Även om det är möjligt att använda det här mönstret med olika PartitionKey-värden rekommenderar vi att du använder samma värden för att få den här fördelen. Annars kan du behöva skriva extra logik för att säkerställa atomiska transaktioner som använder olika PartitionKey-värden .
Lagringsåtgärder
Tabeller i Azure Table Storage kan stöta på belastning inte bara från frågor. De kan också stöta på belastning från lagringsåtgärder som infogningar, uppdateringar och borttagningar. Överväg vilken typ av lagringsåtgärder du ska utföra i tabellen och i vilken takt. Om du utför dessa åtgärder sällan behöver du kanske inte bekymra dig om dem. Men för frekventa åtgärder som att utföra många infogningar på kort tid måste du överväga hur dessa åtgärder hanteras som ett resultat av de PartitionKey-värden som du väljer. Viktiga exempel är mönster för endast tillägg och endast prepend. Mönstren för endast tillägg och endast förberedelse beskrivs i Intervallpartitioner.
När du använder ett mönster med endast tillägg eller endast förberedelse använder du unika stigande eller fallande värden för PartitionKey vid efterföljande infogningar. Om du kombinerar det här mönstret med frekventa infogningsåtgärder kommer tabellen inte att kunna hantera infogningsåtgärderna med stor skalbarhet. Tabellens skalbarhet påverkas eftersom Azure inte kan belastningsbalansera åtgärdsbegäranden till andra partitionsservrar. I så fall kanske du vill överväga att använda värden som är slumpmässiga, till exempel GUID-värden. Sedan kan partitionsstorlekarna vara små och ändå upprätthålla belastningsutjämningen under lagringsåtgärderna.
Stresstestning av tabellpartition
När partitionsnyckelvärdet är komplext eller kräver jämförelser med andra PartitionKey-mappningar kan du behöva testa tabellens prestanda. Testet bör undersöka hur väl en partition presterar under belastningstoppar.
Så här utför du ett stresstest
- Skapa en testtabell.
- Läs in testtabellen med data så att den innehåller entiteter som har det PartitionKey-värde som du ska rikta in dig på.
- Använd programmet för att simulera belastningstoppar i tabellen. Rikta en enskild partition med hjälp av PartitionKey-värdet från steg 2. Det här steget skiljer sig åt för varje program, men simuleringen bör innehålla alla nödvändiga frågor och lagringsåtgärder. Du kan behöva justera programmet så att det riktar in sig på en enda partition.
- Granska dataflödet för GET- eller PUT-åtgärderna i tabellen.
Om du vill undersöka dataflödet jämför du de faktiska värdena med den angivna gränsen för en enskild partition på en enskild server. Partitioner är begränsade till 2 000 entiteter per sekund. Om dataflödet överskrider 2 000 entiteter per sekund för en partition kan servern köras för frekvent i en produktionsinställning. I det här fallet kan PartitionKey-värdena vara för grova, så att det inte finns tillräckligt med partitioner eller att partitionerna är för stora. Du kan behöva ändra partitionsnyckelvärdet så att partitionerna distribueras mellan fler servrar.
Belastningsutjämning
Belastningsutjämning på partitionsskiktet sker när en partition blir för frekvent. När en partition är för frekvent fungerar partitionen, särskilt partitionsservern, bortom målskalbarheten. För Azure Storage har varje partition ett skalbarhetsmål på 2 000 entiteter per sekund. Belastningsutjämning sker också på DFS-lagret (Distributed File System).
Belastningsutjämningen på DFS-lagret hanterar I/O-belastning och ligger utanför omfånget för den här artikeln. Belastningsutjämning på partitionsskiktet sker inte omedelbart när skalbarhetsmålet har överskridits. I stället väntar systemet några minuter innan belastningsutjämningsprocessen påbörjas. Detta säkerställer att en partition verkligen har blivit het. Det är inte nödvändigt att prime-partitioner med genererad belastning som utlöser belastningsutjämning eftersom systemet utför uppgiften automatiskt.
Om en tabell var förberedd med en viss belastning kanske systemet kan balansera partitionerna baserat på den faktiska belastningen, vilket resulterar i en betydligt annorlunda fördelning av partitionerna. Överväg att skriva kod som hanterar timeout- och Server Busy-fel i stället för att skapa partitioner. Felen returneras när systemet belastningsutjämning. Genom att hantera dessa fel med hjälp av en strategi för återförsök kan ditt program bättre hantera belastningstoppar. Återförsöksstrategier beskrivs mer detaljerat i följande avsnitt.
När belastningsutjämning sker blir partitionen offline i några sekunder. Under offlineperioden tilldelar systemet partitionen till en annan partitionsserver. Observera att dina data inte lagras av partitionsservrarna. I stället hanterar partitionsservrarna entiteter från DFS-lagret. Eftersom dina data inte lagras i partitionslagret är det en snabb process att flytta partitioner till olika servrar. Den här flexibiliteten begränsar avsevärt den eventuella stilleståndstid som ditt program kan stöta på.
Återförsöksstrategi
Det är viktigt att ditt program hanterar lagringsfel för att säkerställa att du inte förlorar några datauppdateringar. Vissa fel kräver ingen strategi för återförsök. Uppdateringar som returnerar ett 401 Unauthorized-fel drar till exempel inte nytta av att försöka utföra åtgärden igen eftersom det är troligt att programtillståndet inte ändras mellan återförsök som löser 401-felet. Fel som Servern är upptagen eller tidsgränsen är dock relaterade till belastningsutjämningsfunktionerna i Azure som ger skalbarhet för tabeller. När lagringsnoderna som betjänar dina entiteter blir heta balanserar Azure belastningen genom att flytta partitioner till andra noder. Under den här tiden kan partitionen vara otillgänglig, vilket resulterar i att servern är upptagen eller att tidsgränsen överskrids. Så småningom kan partitionen återaktiveras och uppdateringarna återupptas.
En strategi för återförsök är lämplig för fel med upptagen server eller timeout. I de flesta fall kan du undanta fel på 400-nivå och cirka 500-nivåfel från logiken för omprövning. Fel som kan undantas är 501 Inte implementerad och 505 HTTP-version stöds inte. Sedan kan du implementera en återförsöksstrategi för upp till 500-nivåfel, till exempel Upptagen på servern (503) och Tidsgräns (504).
Du kan välja mellan tre vanliga återförsöksstrategier för ditt program:
- Inget nytt försök: Inga återförsök görs.
- Fast backoff: Åtgärden görs igen N gånger med ett konstant backoff-värde.
- Exponentiell backoff: Åtgärden görs på nytt N gånger med ett exponentiellt backoff-värde.
Ingen återförsöksstrategi är ett enkelt (och undvikande) sätt att hantera åtgärdsfel. En no retry-strategi är dock inte särskilt användbar. Att inte införa några återförsök innebär uppenbara risker med att data inte lagras korrekt efter misslyckade åtgärder. En bättre strategi är att använda strategin för fast backoff. vilket ger möjlighet att göra återförsök med samma varaktighet för backoff.
Strategin är dock inte optimerad för hantering av mycket skalbara tabeller. Om många trådar eller processer väntar under samma tid kan kollisioner uppstå. En rekommenderad strategi för återförsök är en strategi som använder en exponentiell backoff där varje återförsök är längre än det senaste försöket. Det liknar den algoritm för undvikande av kollision som används i datornätverk, till exempel Ethernet. Den exponentiella backoffen använder en slumpmässig faktor för att ge ytterligare varians till det resulterande intervallet. Backoff-värdet begränsas sedan till lägsta och högsta gränser. Följande formel kan användas för att beräkna nästa backoff-värde med hjälp av en exponentiell algoritm:
y = Rand(0.8z, 1.2z)(2x-1
y = Min(zmin + y, zmax
Plats:
z = standard backoff i millisekunder
zmin = standard minsta backoff i millisekunder
zmax = standard för maximal backoff i millisekunder
x = antalet återförsök
y = backoff-värdet i millisekunder
Multiplikatorerna 0,8 och 1,2 som används i funktionen Rand (slumpmässig) ger en slumpmässig varians av standardavvikelsen inom ±20 % av det ursprungliga värdet. Intervallet ±20 % är acceptabelt för de flesta återförsöksstrategier och förhindrar ytterligare kollisioner. Formeln kan implementeras med hjälp av följande kod:
int retries = 1;
// Initialize variables with default values
var defaultBackoff = TimeSpan.FromSeconds(30);
var backoffMin = TimeSpan.FromSeconds(3);
var backoffMax = TimeSpan.FromSeconds(90);
var random = new Random();
double backoff = random.Next(
(int)(0.8D * defaultBackoff.TotalMilliseconds),
(int)(1.2D * defaultBackoff.TotalMilliseconds));
backoff *= (Math.Pow(2, retries) - 1);
backoff = Math.Min(
backoffMin.TotalMilliseconds + backoff,
backoffMax.TotalMilliseconds);
Sammanfattning
Ett program i Azure Table Storage kan lagra en enorm mängd data eftersom Table Storage hanterar och omtilldelar partitioner över många lagringsnoder. Du kan använda datapartitionering för att styra tabellens skalbarhet. Planera i förväg när du definierar ett tabellschema för att säkerställa att du implementerar effektiva partitioneringsstrategier. Mer specifikt analyserar du programmets krav, data och frågor innan du väljer PartitionKey-värden . Varje partition kan omtilldelas till olika lagringsnoder när systemet svarar på trafik. Använd ett partitionsbelastningstest för att säkerställa att tabellen har rätt PartitionKey-värden . Det här testet hjälper dig att avgöra när partitionerna är för frekventa och hjälper dig att göra nödvändiga partitionsjusteringar.
För att säkerställa att programmet hanterar tillfälliga fel och att dina data sparas använder du en strategi för återförsök med backoff. Standardprincipen för återförsök som Azure Storage-klientbiblioteket använder har en exponentiell backoff som undviker kollisioner och maximerar programmets dataflöde.