Een schaalbare partitioneringsstrategie ontwerpen voor Azure Table Storage

In dit artikel wordt het partitioneren van een tabel in Azure Table Storage en strategieën besproken die u kunt gebruiken om efficiënte schaalbaarheid te garanderen.

Azure biedt cloudopslag die maximaal beschikbaar en zeer schaalbaar is. Het onderliggende opslagsysteem voor Azure wordt geleverd via een set services, waaronder Azure Blob Storage, Azure Table Storage, Azure Queue Storage en Azure Files.

Azure Table Storage is ontworpen voor het opslaan van gestructureerde gegevens. De Azure Storage-service ondersteunt een onbeperkt aantal tabellen. Elke tabel kan worden geschaald tot enorme niveaus en terabytes aan fysieke opslag bieden. Als u optimaal wilt profiteren van tabellen, moet u uw gegevens optimaal partitioneren. In dit artikel worden strategieën besproken die u kunt gebruiken om gegevens efficiënt te partitioneren voor Azure Table Storage.

Tabelentiteiten

Tabelentiteiten vertegenwoordigen de gegevenseenheden die in een tabel zijn opgeslagen. Tabelentiteiten zijn vergelijkbaar met rijen in een typische relationele databasetabel. Elke entiteit definieert een verzameling eigenschappen. Elke eigenschap wordt gedefinieerd als een sleutel-waardepaar op basis van de naam, waarde en het gegevenstype van de waarde. Entiteiten moeten de volgende drie systeemeigenschappen definiëren als onderdeel van de eigenschapverzameling:

  • PartitionKey: de eigenschap PartitionKey slaat tekenreekswaarden op die de partitie identificeren waartoe een entiteit behoort. Partities, zoals we later bespreken, zijn integraal voor de schaalbaarheid van de tabel. Entiteiten met dezelfde PartitionKey-waarde worden opgeslagen in dezelfde partitie.

  • RowKey: de eigenschap RowKey slaat tekenreekswaarden op die entiteiten binnen elke partitie uniek identificeren. PartitionKey en RowKey vormen samen de primaire sleutel voor de entiteit.

  • Timestamp: de eigenschap Timestamp biedt traceerbaarheid voor een entiteit. Een tijdstempel is een datum/tijd-waarde die aangeeft wanneer de entiteit voor het laatst is gewijzigd. Een tijdstempel wordt ook wel de versie van de entiteit genoemd. Wijzigingen in tijdstempels worden genegeerd omdat de tabelservice de waarde voor deze eigenschap behoudt tijdens alle invoeg- en updatebewerkingen.

Primaire tabelsleutel

De primaire sleutel voor een Azure-entiteit bestaat uit de gecombineerde eigenschappen PartitionKey en RowKey . De twee eigenschappen vormen één geclusterde index in de tabel. De waarden PartitionKey en RowKey kunnen maximaal 1024 tekens groot zijn. Lege tekenreeksen zijn ook toegestaan; Null-waarden zijn echter niet toegestaan.

De geclusterde index sorteert op partitionkey in oplopende volgorde en vervolgens op Rijsleutel in oplopende volgorde. De sorteervolgorde wordt waargenomen in alle queryantwoorden. Lexicale vergelijkingen worden gebruikt tijdens de sorteerbewerking. Een tekenreekswaarde van '111' wordt weergegeven vóór een tekenreekswaarde van '2'. In sommige gevallen wilt u mogelijk dat de sorteervolgorde numeriek is. Als u in een numerieke en oplopende volgorde wilt sorteren, moet u tekenreeksen met een vaste lengte zonder padding gebruiken. In het voorgaande voorbeeld wordt '002' weergegeven vóór '111'.

Tabelpartities

Partities vertegenwoordigen een verzameling entiteiten met dezelfde PartitionKey-waarden . Partities worden altijd geleverd vanaf één partitieserver. Elke partitieserver kan een of meer partities bedienen. Een partitieserver heeft een frequentielimiet van het aantal entiteiten dat in de loop van de tijd van één partitie kan worden gebruikt. Een partitie heeft een schaalbaarheidsdoel van 2000 entiteiten per seconde. Deze doorvoer kan hoger zijn tijdens minimale belasting op het opslagknooppunt, maar deze wordt beperkt wanneer het knooppunt hot of actief wordt.

Om het concept van partitionering beter te illustreren, ziet u in de volgende afbeelding een tabel met een kleine subset gegevens voor registraties van voetraces. De afbeelding toont een conceptuele weergave van partitionering waarbij de PartitionKey drie verschillende waarden bevat: de naam van het evenement in combinatie met drie afstanden (volledige marathon, halve marathon en 10 km). In dit voorbeeld worden twee partitieservers gebruikt. Server A bevat registraties voor de halve marathon en 10 km afstanden. Server B bevat alleen de volledige marathonafstanden. De RowKey-waarden worden weergegeven om context te bieden, maar de waarden zijn niet zinvol voor dit voorbeeld.

Een diagram met een tabel met drie partities
Een tabel met drie partities

Schaalbaarheid

Omdat een partitie altijd wordt geleverd vanaf één partitieserver en elke partitieserver een of meer partities kan bedienen, is de efficiëntie van het leveren van entiteiten gecorreleerd met de status van de server. Servers die te maken krijgen met veel verkeer voor hun partities, kunnen mogelijk geen hoge doorvoer ondersteunen. Als in de voorgaande afbeelding bijvoorbeeld veel aanvragen voor '2011 New York City Marathon__Half' worden ontvangen, kan server A te heet worden. Om de doorvoer van de server te verhogen, balanceert het opslagsysteem de partities naar andere servers. Het resultaat is dat het verkeer wordt verdeeld over veel andere servers. Voor een optimale taakverdeling van verkeer moet u meer partities gebruiken, zodat Azure Table Storage de partities naar meer partitieservers kan distribueren.

Transacties van entiteitsgroepen

Een entiteitsgroeptransactie is een set opslagbewerkingen die atomisch worden geïmplementeerd op entiteiten met dezelfde PartitionKey-waarde . Als een opslagbewerking in de entiteitsgroep mislukt, worden alle opslagbewerkingen in de entiteit teruggedraaid. Een entiteitsgroeptransactie bestaat uit niet meer dan 100 opslagbewerkingen en kan niet groter zijn dan 4 MiB. Transacties van entiteitsgroepen bieden Azure Table Storage met een beperkte vorm van de semantiek atomiciteit, consistentie, isolatie en duurzaamheid (ACID) die wordt geleverd door relationele databases.

Entiteitsgroeptransacties verbeteren de doorvoer omdat ze het aantal afzonderlijke opslagbewerkingen verminderen dat moet worden verzonden naar Azure Table Storage. Entiteitsgroeptransacties bieden ook een economisch voordeel. Een entiteitsgroeptransactie wordt gefactureerd als één opslagbewerking, ongeacht hoeveel opslagbewerkingen deze bevat. Omdat alle opslagbewerkingen in een entiteitsgroeptransactie van invloed zijn op entiteiten met dezelfde PartitionKey-waarde , kan een noodzaak om entiteitsgroepstransacties te gebruiken de selectie van partitionKey-waarde aandrijven.

Bereikpartities

Als u unieke PartitionKey-waarden gebruikt voor uw entiteiten, behoort elke entiteit tot een eigen partitie. Als de unieke waarden die u gebruikt, in waarde toenemen of afnemen, is het mogelijk dat Azure bereikpartities maakt. Range Partitions groepeert entiteiten die sequentiële, unieke PartitionKey-waarden hebben om de prestaties van bereikquery's te verbeteren. Zonder bereikpartities moet een bereikquery partitiegrenzen of servergrenzen overschrijden, waardoor de queryprestaties kunnen afnemen. Overweeg een toepassing die gebruikmaakt van de volgende tabel, die een toenemende reekswaarde heeft voor PartitionKey:

PartitionKey RowKey
"0001" -
"0002" -
"0003" -
"0004" -
"0005" -
"0006" -

Azure kan de eerste drie entiteiten groeperen in een bereikpartitie. Als u een bereikquery toepast op de tabel die de PartitionKey als criterium gebruikt en entiteiten aanvraagt van '0001' tot '0003', kan de query efficiënt worden uitgevoerd omdat de entiteiten worden geleverd vanaf één partitieserver. Er is geen garantie wanneer en hoe een bereikpartitie wordt gemaakt.

Het bestaan van bereikpartities voor uw tabel kan van invloed zijn op de prestaties van uw invoegbewerkingen als u entiteiten invoegt met toenemende of aflopende PartitionKey-waarden . Het invoegen van entiteiten met toenemende PartitionKey-waarden wordt een toevoegpatroon genoemd. Het invoegen van entiteiten met afnemende waarden wordt een prepend-only-patroon genoemd. Overweeg dit soort patronen niet te gebruiken, omdat de totale doorvoer van uw invoegaanvragen wordt beperkt door één partitieserver. Dit komt doordat, als er bereikpartities bestaan, de eerste en laatste partitie (bereik) respectievelijk de laagste en hoogste PartitionKey-waarden bevatten. Daarom is de invoeging van een nieuwe entiteit, een entiteit met een opeenvolgend lagere of hogere PartitionKey-waarde , gericht op een van de eindpartities. In de volgende afbeelding ziet u een mogelijke set bereikpartities die zijn gebaseerd op het voorgaande voorbeeld. Als een set entiteiten '0007', '0008' en '0009' wordt ingevoegd, worden deze toegewezen aan de laatste (oranje) partitie.

Diagram met een set bereikpartities
Een set bereikpartities

Het is belangrijk te weten dat er geen negatief effect op de prestaties is als de invoegbewerkingen PartitionKey-waarden gebruiken die meer verspreid zijn.

Gegevens analyseren

In tegenstelling tot een tabel in een relationele database die u kunt gebruiken voor het beheren van indexen, kunnen tabellen in Azure Table Storage slechts één index hebben. Een index in Azure Table Storage bestaat altijd uit de eigenschappen PartitionKey en RowKey .

In een Azure-tabel hebt u niet de luxe om de prestaties van uw tabel af te stemmen door meer indexen toe te voegen of door een bestaande tabel te wijzigen nadat u deze hebt geïmplementeerd. U moet de gegevens analyseren tijdens het ontwerpen van de tabel. De belangrijkste aspecten om rekening mee te houden voor optimale schaalbaarheid en voor de efficiëntie van query's en invoegen zijn de waarden PartitionKey en RowKey . In dit artikel wordt benadrukt hoe u de PartitionKey kiest, omdat deze rechtstreeks betrekking heeft op de manier waarop tabellen worden gepartitioneerd.

Partitiegrootte aanpassen

Partitiegrootte verwijst naar het aantal entiteiten dat een partitie bevat. Zoals we in Schaalbaarheid bespreken, betekent het hebben van meer partities dat u een betere taakverdeling krijgt. De granulariteit van de partitionkey-waarde is van invloed op de grootte van de partities. Op het grofste niveau, als één waarde wordt gebruikt als de PartitionKey, bevinden alle entiteiten zich in één partitie die erg groot is. Op het beste granulariteitsniveau kan de PartitionKey unieke waarden voor elke entiteit bevatten. Het resultaat is dat er een partitie is voor elke entiteit. In de volgende tabel ziet u de voor- en nadelen voor het bereik van granulaties:

PartitionKey-granulariteit Partitiegrootte Voordelen Nadelen
Eén waarde Klein aantal entiteiten Batchtransacties zijn mogelijk met elke entiteit.

Alle entiteiten zijn lokaal en worden geleverd vanuit hetzelfde opslagknooppunt.
Eén waarde Groot aantal entiteiten Entiteitsgroeptransacties zijn mogelijk met elke entiteit. Zie Entiteitsgroepstransacties uitvoeren voor meer informatie over de limieten van entiteitsgroepstransacties. Schalen is beperkt.

De doorvoer is beperkt tot de prestaties van één server.
Meerdere waarden Meerdere partities

Partitiegrootten zijn afhankelijk van de verdeling van de entiteit.
Batchtransacties zijn mogelijk op sommige entiteiten.

Dynamische partitionering is mogelijk.

Query's met één aanvraag zijn mogelijk (geen vervolgtokens).

Taakverdeling over meer partitieservers is mogelijk.
Een zeer ongelijke verdeling van entiteiten over partities kan de prestaties van de grotere en actievere partities beperken.
Unieke waarden Veel kleine partities De tabel is zeer schaalbaar.

Bereikpartities kunnen de prestaties van query's voor bereik tussen partities verbeteren.
Query's die betrekking hebben op bereiken, vereisen mogelijk bezoeken aan meer dan één server.

Batchtransacties zijn niet mogelijk.

Patronen met alleen-toevoegen of alleen-prepend-only kunnen van invloed zijn op de doorvoer van invoegen.

De tabel laat zien hoe het schalen wordt beïnvloed door PartitionKey-waarden . Het is een best practice om kleinere partities te begunstigen, omdat deze een betere taakverdeling bieden. Grotere partities kunnen in sommige scenario's geschikt zijn en ze zijn niet noodzakelijkerwijs nadelig. Als uw toepassing bijvoorbeeld geen schaalbaarheid vereist, kan één grote partitie geschikt zijn.

Query's bepalen

Query's halen gegevens op uit tabellen. Wanneer u de gegevens voor een tabel in Azure Table Storage analyseert, is het belangrijk om te overwegen welke query's de toepassing gaat gebruiken. Als een toepassing meerdere query's heeft, moet u deze mogelijk prioriteren, hoewel uw beslissingen mogelijk subjectief zijn. In veel gevallen zijn dominante query's te onderscheiden van andere query's. Wat de prestaties betreft, vallen query's in verschillende categorieën. Omdat een tabel slechts één index heeft, zijn de queryprestaties meestal gerelateerd aan de eigenschappen PartitionKey en RowKey . In de volgende tabel ziet u de verschillende typen query's en hun prestatiebeoordelingen:

Querytype PartitionKey-overeenkomst RowKey-overeenkomst Prestatieclassificatie
Scan van rijbereik Exact Gedeeltelijk Beter met kleinere partities.

Slecht met partities die erg groot zijn.
Partitiebereik scannen Gedeeltelijk Gedeeltelijk Goed met een klein aantal partitieservers die worden aangeraakt.

Erger dat er meer servers worden aangeraakt.
Volledige tabelscan Gedeeltelijk, geen Gedeeltelijk, geen Nog erger met een subset van partities die wordt gescand.

Het slechtste met alle partities die worden gescand.

Notitie

De tabel definieert prestatieclassificaties ten opzichte van elkaar. Het aantal en de grootte van de partities kunnen uiteindelijk bepalen hoe de query wordt uitgevoerd. Een partitiebereikscan voor een tabel met veel grote partities kan bijvoorbeeld slecht presteren in vergelijking met een volledige tabelscan voor een tabel met enkele kleine partities.

De querytypen die in de voorgaande tabel worden vermeld, tonen een voortgang van de beste typen query's om te gebruiken tot de slechtste typen, op basis van hun prestatieclassificaties. Puntquery's zijn de beste typen query's om te gebruiken, omdat ze volledig gebruikmaken van de geclusterde index van de tabel. De volgende puntquery gebruikt de gegevens uit de registratietabel voor voetraces:

http://<account>.windows.core.net/registrations(PartitionKey=”2011 New York City Marathon__Full”,RowKey=”1234__John__M__55”)  
  

Als de toepassing meerdere query's gebruikt, kunnen deze niet allemaal puntquery's zijn. Wat de prestaties betreft, volgen bereikquery's puntquery's. Er zijn twee soorten bereikquery's: de scan van het rijbereik en de scan van het partitiebereik. Met de scan van het rijbereik wordt één partitie opgegeven. Omdat de bewerking plaatsvindt op één partitieserver, zijn rijbereikscans over het algemeen efficiënter dan partitiebereikscans. Een belangrijke factor in de prestaties van het scannen van rijbereiken is echter hoe selectief een query is. Queryselectiviteit bepaalt hoeveel rijen moeten worden ge itereerd om de overeenkomende rijen te vinden. Meer selectieve query's zijn efficiënter tijdens het scannen van rijbereiken.

Als u de prioriteiten van uw query's wilt beoordelen, moet u rekening houden met de frequentie- en reactietijdvereisten voor elke query. Query's die regelmatig worden uitgevoerd, krijgen mogelijk een hogere prioriteit. Een belangrijke, maar zelden gebruikte query kan echter lage latentievereisten hebben waardoor deze hoger op de prioriteitenlijst kan worden gerangschikt.

Kies de waarde PartitionKey

De kern van het ontwerp van een tabel is de schaalbaarheid, de query's die worden gebruikt om de tabel te openen en de vereisten voor opslagbewerkingen. De PartitionKey-waarden die u kiest, bepalen hoe een tabel wordt gepartitioneerd en welk type query's u kunt gebruiken. Opslagbewerkingen, en met name invoegingen, kunnen ook van invloed zijn op uw keuze van PartitionKey-waarden . De PartitionKey-waarden kunnen variëren van enkele waarden tot unieke waarden. Ze kunnen ook worden gemaakt met behulp van meerdere waarden. U kunt entiteitseigenschappen gebruiken om de partitionkey-waarde te vormen. Of de toepassing kan de waarde berekenen. In de volgende secties worden belangrijke overwegingen besproken.

Entiteitsgroeptransacties

Ontwikkelaars moeten eerst overwegen of de toepassing entiteitsgroepstransacties (batch-updates) gebruikt. Entiteitsgroeptransacties vereisen dat entiteiten dezelfde PartitionKey-waarde hebben. Omdat batchupdates voor een hele groep zijn, kunnen de keuzemogelijkheden van PartitionKey-waarden ook beperkt zijn. Een banktoepassing die contante transacties onderhoudt, moet bijvoorbeeld contante transacties atomisch in de tabel invoegen. Contante transacties vertegenwoordigen zowel de debet- als de creditzijde en moeten tot nul netto worden gerekend. Deze vereiste betekent dat het rekeningnummer niet kan worden gebruikt als onderdeel van de partitionkey-waarde , omdat aan elke zijde van de transactie verschillende rekeningnummers worden gebruikt. In plaats daarvan is een transactie-id mogelijk een betere keuze.

Partities

Partitienummers en -grootten zijn van invloed op de schaalbaarheid van een tabel die wordt belast. Ze worden ook bepaald door hoe gedetailleerd de PartitionKey-waarden zijn. Het kan lastig zijn om de PartitionKey te bepalen op basis van de partitiegrootte, met name als de verdeling van waarden moeilijk te voorspellen is. Een goede vuistregel is om meerdere, kleinere partities te gebruiken. Veel tabelpartities maken het eenvoudiger voor Azure Table Storage om de opslagknooppunten te beheren van waaruit de partities worden bediend.

Het kiezen van unieke of fijnere waarden voor de PartitionKey resulteert in kleinere maar meer partities. Dit is over het algemeen gunstig omdat het systeem de vele partities kan verdelen om de belasting over veel partities te verdelen. U moet echter rekening houden met het effect van het hebben van veel partities op query's voor verschillende partitiebereiken. Deze typen query's moeten meerdere partities bezoeken om aan een query te voldoen. Het is mogelijk dat de partities zijn verdeeld over veel partitieservers. Als een query de grens van een server overschrijdt, moeten vervolgtokens worden geretourneerd. Vervolgtokens geven de volgende PartitionKey - of RowKey-waarden op om de volgende set gegevens voor de query op te halen. Met andere woorden, vervolgtokens vertegenwoordigen ten minste één aanvraag voor de service, wat de algehele prestaties van de query kan verminderen.

Queryselectie is een andere factor die de prestaties van de query kan beïnvloeden. Queryselectiviteit is een meting van het aantal rijen dat moet worden gehalveerd voor elke partitie. Hoe selectiever een query is, hoe efficiënter de query de gewenste rijen retourneert. De algehele prestaties van bereikquery's kunnen afhankelijk zijn van het aantal partitieservers dat moet worden aangeraakt of hoe selectief de query is. U moet ook voorkomen dat u de patronen alleen toevoegen of alleen-toevoegen gebruikt wanneer u gegevens invoegt in uw tabel. Als u deze patronen gebruikt, kunt u, ondanks het maken van kleine en veel partities, de doorvoer van uw invoegbewerkingen beperken. De patronen alleen toevoegen en alleen-toevoegen worden besproken in Bereikpartities.

Query's

Als u weet welke query's u gaat gebruiken, kunt u bepalen welke eigenschappen belangrijk zijn voor de waarde PartitionKey . De eigenschappen die u in de query's gebruikt, zijn kandidaten voor de waarde PartitionKey . De volgende tabel bevat een algemene richtlijn voor het bepalen van de partitionkey-waarde :

Als de entiteit... Actie
Heeft één sleuteleigenschap Gebruik deze als de PartitionKey.
Heeft twee belangrijke eigenschappen Gebruik de ene als de PartitionKey en de andere als de RowKey.
Heeft meer dan twee sleuteleigenschappen Gebruik een samengestelde sleutel van samengevoegde waarden.

Als er meer dan één even dominante query is, kunt u de informatie meerdere keren invoegen met behulp van verschillende RowKey-waarden die u nodig hebt. Uw toepassing beheert secundaire (of tertiaire rijen, enzovoort). U kunt dit type patroon gebruiken om te voldoen aan de prestatievereisten van uw query's. In het volgende voorbeeld worden de gegevens uit het voorbeeld van de registratie van de voetrace gebruikt. Het heeft twee dominante query's:

  • Query uitvoeren op rugnummer
  • Query's uitvoeren op leeftijd

Als u beide dominante query's wilt uitvoeren, voegt u twee rijen in als een entiteitsgroepstransactie. In de volgende tabel ziet u de eigenschappen PartitionKey en RowKey voor dit scenario. De RowKey-waarden bieden een voorvoegsel voor de bib en age, zodat de toepassing onderscheid kan maken tussen de twee waarden.

PartitionKey RowKey
2011 New York City Marathon__Full BIB:01234__John__M__55
2011 New York City Marathon__Full LEEFTIJD:055__1234__John__M

In dit voorbeeld is een entiteitsgroeptransactie mogelijk omdat de PartitionKey-waarden hetzelfde zijn. De groepstransactie biedt atomiciteit van de invoegbewerking. Hoewel het mogelijk is om dit patroon te gebruiken met verschillende PartitionKey-waarden , raden we u aan dezelfde waarden te gebruiken om dit voordeel te verkrijgen. Anders moet u mogelijk extra logica schrijven om ervoor te zorgen dat atomische transacties verschillende PartitionKey-waarden gebruiken.

Opslagbewerkingen

Tabellen in Azure Table Storage kunnen niet alleen worden belast door query's. Ze kunnen ook last ondervinden van opslagbewerkingen, zoals invoegen, bijwerken en verwijderen. Overweeg welk type opslagbewerkingen u op de tabel wilt uitvoeren en met welke snelheid. Als u deze bewerkingen af en toe uitvoert, hoeft u zich er mogelijk geen zorgen over te maken. Voor frequente bewerkingen, zoals het uitvoeren van veel invoegingen in een korte tijd, moet u echter overwegen hoe deze bewerkingen worden uitgevoerd als gevolg van de PartitionKey-waarden die u kiest. Belangrijke voorbeelden zijn de patronen alleen toevoegen en alleen-toevoegen. De patronen alleen toevoegen en alleen-toevoegen worden besproken in Bereikpartities.

Wanneer u een patroon met alleen toevoegen of vooraf toevoegen gebruikt, gebruikt u unieke oplopende of aflopende waarden voor de PartitionKey bij volgende invoegingen. Als u dit patroon combineert met frequente invoegbewerkingen, kan uw tabel de invoegbewerkingen niet met grote schaalbaarheid onderhouden. De schaalbaarheid van uw tabel wordt beïnvloed omdat Azure de bewerkingsaanvragen niet kan verdelen over andere partitieservers. In dat geval kunt u overwegen willekeurige waarden te gebruiken, zoals GUID-waarden. Vervolgens kunnen uw partitiegrootten klein blijven en toch de taakverdeling behouden tijdens opslagbewerkingen.

Stresstests voor tabelpartitie

Wanneer de partitionkey-waarde complex is of vergelijkingen met andere PartitionKey-toewijzingen vereist, moet u mogelijk de prestaties van de tabel testen. De test moet onderzoeken hoe goed een partitie presteert onder piekbelastingen.

Een stresstest uitvoeren

  1. Creatie een testtabel.
  2. Laad de testtabel met gegevens, zodat deze entiteiten bevat met de partitionkey-waarde die u als doel wilt gebruiken.
  3. Gebruik de toepassing om piekbelasting voor de tabel te simuleren. Richt u op één partitie met behulp van de partitionkey-waarde uit stap 2. Deze stap verschilt voor elke toepassing, maar de simulatie moet alle vereiste query's en opslagbewerkingen bevatten. Mogelijk moet u de toepassing aanpassen zodat deze is gericht op één partitie.
  4. Controleer de doorvoer van de GET- of PUT-bewerkingen in de tabel.

Als u de doorvoer wilt onderzoeken, vergelijkt u de werkelijke waarden met de opgegeven limiet van één partitie op één server. Partities zijn beperkt tot 2000 entiteiten per seconde. Als de doorvoer meer dan 2000 entiteiten per seconde voor een partitie overschrijdt, wordt de server mogelijk te heet in een productie-instelling. In dit geval zijn de PartitionKey-waarden mogelijk te grof, zodat er onvoldoende partities zijn of de partities te groot zijn. Mogelijk moet u de partitionkey-waarde wijzigen, zodat de partities over meer servers worden verdeeld.

Taakverdeling

Taakverdeling op de partitielaag treedt op wanneer een partitie te heet wordt. Wanneer een partitie te heet is, werkt de partitie, met name de partitieserver, verder dan de doelschaalbaarheid. Voor Azure Storage heeft elke partitie een schaalbaarheidsdoel van 2000 entiteiten per seconde. Taakverdeling vindt ook plaats op de DFS-laag (Distributed File System).

De taakverdeling op de DFS-laag heeft betrekking op I/O-belasting en valt buiten het bereik van dit artikel. Taakverdeling op de partitielaag vindt niet onmiddellijk plaats nadat het schaalbaarheidsdoel is overschreden. In plaats daarvan wacht het systeem enkele minuten voordat het taakverdelingsproces wordt gestart. Dit zorgt ervoor dat een partitie echt heet is geworden. Het is niet nodig om partities te primeren met gegenereerde belasting die taakverdeling activeert, omdat het systeem de taak automatisch uitvoert.

Als een tabel is geprimeerd met een bepaalde belasting, kan het systeem mogelijk de partities verdelen op basis van de werkelijke belasting, wat resulteert in een aanzienlijk andere verdeling van de partities. In plaats van partities te primen, kunt u code schrijven die de time-out- en server bezet-fouten verwerkt. De fouten worden geretourneerd wanneer de taakverdeling van het systeem wordt uitgevoerd. Door deze fouten af te handelen met behulp van een strategie voor opnieuw proberen, kan uw toepassing piekbelastingen beter verwerken. Strategieën voor opnieuw proberen worden uitgebreid besproken in de volgende sectie.

Wanneer taakverdeling plaatsvindt, wordt de partitie een paar seconden offline. Tijdens de offlineperiode wordt de partitie opnieuw toegewezen aan een andere partitieserver. Het is belangrijk om te weten dat uw gegevens niet worden opgeslagen door de partitieservers. In plaats daarvan dienen de partitieservers entiteiten van de DFS-laag. Omdat uw gegevens niet worden opgeslagen op de partitielaag, is het verplaatsen van partities naar verschillende servers een snel proces. Deze flexibiliteit beperkt aanzienlijk de downtime, indien aanwezig, die uw toepassing kan tegenkomen.

Strategie voor opnieuw proberen

Het is belangrijk dat uw toepassing fouten met opslagbewerkingen afhandelt om ervoor te zorgen dat u geen gegevensupdates kwijtraakt. Voor sommige fouten is geen strategie voor opnieuw proberen vereist. Updates die de fout 401 Niet geautoriseerd retourneren, hebben bijvoorbeeld geen baat bij het opnieuw proberen van de bewerking, omdat de toepassingsstatus waarschijnlijk niet verandert tussen nieuwe pogingen waarmee de 401-fout wordt opgelost. Fouten zoals Server bezet of Time-out zijn echter gerelateerd aan de taakverdelingsfuncties van Azure die schaalbaarheid van tabellen bieden. Wanneer de opslagknooppunten voor uw entiteiten dynamisch worden, wordt de belasting in Azure verdeeld door partities naar andere knooppunten te verplaatsen. Gedurende deze tijd is de partitie mogelijk niet toegankelijk, wat resulteert in server bezet of time-outfouten. Uiteindelijk wordt de partitie opnieuw ingeschakeld en worden de updates hervat.

Een strategie voor opnieuw proberen is geschikt voor server bezet of time-outfouten. In de meeste gevallen kunt u fouten van 400 niveaus en sommige fouten van 500 niveaus uitsluiten van de logica voor opnieuw proberen. Fouten die kunnen worden uitgesloten, zijn 501 Niet geïmplementeerd en 505 HTTP-versie niet ondersteund. Vervolgens kunt u een strategie voor opnieuw proberen implementeren voor fouten van maximaal 500 niveaus, zoals Server bezet (503) en Time-out (504).

U kunt kiezen uit drie algemene strategieën voor opnieuw proberen voor uw toepassing:

  • Geen nieuwe poging: er wordt geen nieuwe poging gedaan.
  • Opgeloste back-off: de bewerking wordt N keer opnieuw geprobeerd met een constante uitstelwaarde.
  • Exponentieel uitstel: de bewerking wordt N keer opnieuw geprobeerd met een exponentiële uitstelwaarde.

De strategie Geen nieuwe poging is een eenvoudige (en ontwijkende) manier om bewerkingsfouten af te handelen. Een strategie zonder opnieuw proberen is echter niet erg nuttig. Het niet opleggen van nieuwe pogingen brengt duidelijke risico's met zich mee dat gegevens niet correct worden opgeslagen na mislukte bewerkingen. Een betere strategie is om de vaste uitstelstrategie te gebruiken. dit biedt de mogelijkheid om bewerkingen opnieuw uit te voeren met dezelfde uitstelduur.

De strategie is echter niet geoptimaliseerd voor het verwerken van zeer schaalbare tabellen. Als veel threads of processen op dezelfde tijd wachten, kunnen er conflicten optreden. Een aanbevolen strategie voor opnieuw proberen is een strategie die een exponentieel uitstel gebruikt, waarbij elke poging langer is dan de laatste poging. Het is vergelijkbaar met het algoritme voor het vermijden van conflicten dat wordt gebruikt in computernetwerken, zoals Ethernet. De exponentiële uitstel maakt gebruik van een willekeurige factor om een extra variantie ten opzichte van het resulterende interval te bieden. De uitstelwaarde wordt vervolgens beperkt tot minimum- en maximumlimieten. De volgende formule kan worden gebruikt voor het berekenen van de volgende uitstelwaarde met behulp van een exponentiële algoritme:

y = Rand(0,8z, 1,2z)(2x-1

y = Min(zmin + y, zmax

Waar:

z = standaard uitstel in milliseconden

zmin = standaard minimale uitstel in milliseconden

zmax = standaard maximale uitstel in milliseconden

x = het aantal nieuwe pogingen

y = de uitstelwaarde in milliseconden

De vermenigvuldigers 0,8 en 1,2 die worden gebruikt in de randfunctie (willekeurig) produceren een willekeurige variantie van de standaardachterwaarde binnen ±20% van de oorspronkelijke waarde. Het bereik ±20% is acceptabel voor de meeste strategieën voor opnieuw proberen en voorkomt verdere conflicten. De formule kan worden geïmplementeerd met behulp van de volgende code:

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);  
  

Samenvatting

Een toepassing in Azure Table Storage kan een enorme hoeveelheid gegevens opslaan, omdat met Table Storage partities op veel opslagknooppunten worden beheerd en opnieuw worden toegewezen. U kunt gegevenspartitionering gebruiken om de schaalbaarheid van de tabel te beheren. Plan vooraf wanneer u een tabelschema definieert om ervoor te zorgen dat u efficiënte partitioneringsstrategieën implementeert. Analyseer met name de vereisten, gegevens en query's van de toepassing voordat u PartitionKey-waarden selecteert. Elke partitie kan opnieuw worden toegewezen aan verschillende opslagknooppunten wanneer het systeem reageert op verkeer. Gebruik een partitiestresstest om ervoor te zorgen dat de tabel de juiste PartitionKey-waarden heeft. Met deze test kunt u bepalen wanneer partities te heet zijn en kunt u de benodigde partitieaanpassingen aanbrengen.

Om ervoor te zorgen dat uw toepassing onregelmatige fouten afhandelt en dat uw gegevens behouden blijven, gebruikt u een strategie voor opnieuw proberen met uitstel. Het standaardbeleid voor opnieuw proberen dat door de Azure Storage-clientbibliotheek wordt gebruikt, heeft een exponentieel uitstel dat conflicten voorkomt en de doorvoer van uw toepassing maximaliseert.