Shardingpatroon

Een gegevensopslag onderverdelen in een set met horizontale partities of shards. Deze aanpak kan de schaalbaarheid verbeteren wanneer u grote hoeveelheden gegevens opslaat en opent.

Context en probleem

Een gegevensarchief op één server heeft de volgende beperkingen:

  • Opslagruimte: Een gegevensarchief voor een grootschalige cloudtoepassing kan een grote hoeveelheid gegevens bevatten die in de loop van de tijd groeit. Een server biedt een beperkte hoeveelheid schijfopslag en u kunt bestaande schijven vervangen door grotere schijven of meer schijven toevoegen wanneer gegevensvolumes toenemen. Het systeem bereikt uiteindelijk een limiet waarbij u de opslagcapaciteit niet op één server kunt verhogen.

  • Rekenmiddelen: Een cloudtoepassing moet een groot aantal gelijktijdige gebruikers ondersteunen die elk queries uitvoeren naar de gegevensopslag. Een enkele server biedt mogelijk onvoldoende rekenkracht voor deze belasting, wat resulteert in langere reactietijden en time-outs. U kunt geheugen toevoegen of processors upgraden, maar het systeem bereikt een limiet waar u rekenresources niet verder kunt verhogen.

  • Netwerkbandbreedte: De snelheid waarmee één server aanvragen kan ontvangen en antwoorden kan verzenden, beperkt de prestaties van het gegevensarchief. Het volume van netwerkverkeer kan de capaciteit van de netwerkverbinding overschrijden, wat resulteert in mislukte aanvragen.

  • Geografie: Juridische, nalevings- of prestatievereisten vereisen mogelijk dat u gebruikersgegevens opslaat in dezelfde geografische regio als de gebruikers. Als gebruikers zich in verschillende landen/regio's bevinden, kunt u mogelijk niet alle gegevens van de toepassing opslaan in één gegevensarchief.

Als u deze beperkingen tijdelijk wilt uitstellen, kunt u verticaal schalen door schijfcapaciteit, verwerkingskracht, geheugen en netwerkverbindingen toe te voegen. Een cloudtoepassing die ondersteuning moet bieden voor een groot aantal gebruikers en grote gegevensvolumes, moet horizontaal worden geschaald.

Solution

Verdeel de gegevensopslag in horizontale partities of shards. Elke shard heeft hetzelfde schema, maar bevat een eigen afzonderlijke subset van de gegevens. Elke shard is een volledig gegevensarchief dat gegevens kan bevatten voor veel entiteiten van verschillende typen. Een shard wordt uitgevoerd op een server die fungeert als een opslagknooppunt.

Dit patroon biedt de volgende voordelen:

  • U kunt het systeem uitschalen door meer shards toe te voegen op extra opslagknooppunten.

  • Een systeem kan vooraf gebouwde hardware gebruiken in plaats van gespecialiseerde en dure computers voor elk opslagknooppunt.

  • U kunt het aantal conflicten verminderen en de prestaties verbeteren door de workload over verschillende shards te verdelen.

  • In de cloud kunnen shards zich fysiek dicht bij de gebruikers bevinden die toegang hebben tot de gegevens.

Wanneer u een gegevensarchief opsplitst in shards, bepaalt u welke gegevens in elke shard moeten worden geplaatst. Elke shard bevat doorgaans items gegroepeerd op een of meer gegevenskenmerken. Deze attributen vormen de shardsleutel, ook wel de partitiesleutel genoemd.

Met sharding worden de gegevens fysiek gerangschikt. Wanneer een toepassing gegevens opslaat en ophaalt, wordt deze door de shardinglogica naar de juiste shard geleid. U kunt deze logica implementeren in de gegevenstoegangscode van de toepassing of in het systeem voor gegevensopslag als deze op transparante wijze ondersteuning biedt voor sharding.

Het abstraheren van de fysieke locatie van de gegevens in de shardinglogica biedt controle over welke shards welke gegevens bevatten. U kunt ook gegevens tussen shards migreren zonder de bedrijfslogica van de toepassing te wijzigen wanneer u gegevens opnieuw moet distribueren, bijvoorbeeld wanneer shards niet in evenwicht zijn. De afweging is de extra overhead voor gegevenstoegang om de locatie van elk gegevensitem te bepalen tijdens het ophalen.

Selectie van shardsleutels

De verdelingssleutel is de meest kritieke ontwerpbeslissing in een geshard systeem. Als u een shardsleutel wilt wijzigen nadat u deze hebt gekozen, moet u doorgaans alle gegevens migreren naar een nieuwe shard-indeling. Dit is een dure en riskante bewerking op een live systeem. Neem deze beslissing zorgvuldig voordat u code schrijft.

Een effectieve shardsleutel is onveranderbaar, heeft een hoge kardinaliteit, distribueert gegevens en laadt gelijkmatig en is afgestemd op uw dominante querypatronen, zodat de meeste aanvragen worden omgezet in één shard. Vermijd monotonisch toenemende waarden (autoincrement gehele getallen en sequentiële tijdstempels), kenmerken met lage kardinaliteit (booleaanse waarden en kleine enumsets) en vluchtige kenmerken die regelmatig veranderen. Deze kenmerken leiden tot hotspots of kostbare gegevensverplaatsing tussen shards.

Als geen enkel kenmerk aan deze criteria voldoet, definieert u een samengestelde shardsleutel door twee of meer kenmerken te combineren. Als query's gegevens moeten ophalen op basis van kenmerken die geen deel uitmaken van de shardsleutel, gebruikt u een patroon zoals het patroon Indextabel om secundaire zoekacties te bieden.

Zie richtlijnen voor gegevenspartitionering en strategieën voor gegevenspartitionering voor meer informatie over het kiezen van partitiesleutels in Azure-services.

Shardingstrategieën

Gebruik een van de volgende strategieën als u de shard-sleutel kiest en beslist hoe u gegevens over shards distribueert. U hebt geen een-op-een-correspondentie nodig tussen shards en de servers die deze hosten. Eén server kan meerdere shards hosten.

Opzoek-shardingstrategie

In de opzoekstrategie, ook wel de strategie op basis van directory's genoemd, implementeert de shardinglogica een kaart waarmee een gegevensaanvraag wordt gerouteerd naar de shard die die gegevens bevat met behulp van de shardsleutel. In een multitenant-toepassing kunt u alle gegevens voor een tenant samen opslaan in een shard met behulp van de tenant-id als de shardsleutel. Meerdere tenants kunnen dezelfde shard delen, maar de gegevens voor één tenant worden niet verspreid over meerdere shards. In het volgende diagram ziet u de verdeling van tenantgegevens op basis van tenant-ID's.

Diagram met tenantgegevens op basis van tenant-id's

De toewijzing tussen shardsleutelwaarden en fysieke opslag kan direct zijn, waarbij elke shardsleutelwaarde wordt toegewezen aan een fysieke partitie. Een flexibelere techniek is virtuele partitionering, waarbij shardsleutelwaarden worden toegewezen aan virtuele shards. Het systeem wijst die virtuele shards vervolgens toe aan minder fysieke partities. Een toepassing zoekt gegevens met behulp van een shardsleutelwaarde die verwijst naar een virtuele shard en het systeem wijst virtuele shards transparant toe aan fysieke partities. De toewijzing van een virtuele shard naar een fysieke partitie kan worden gewijzigd zonder dat er aanpassingen in de toepassingscode nodig zijn.

Shardingstrategie op basis van bereik

De op bereik gebaseerde strategie groepert gerelateerde items in dezelfde shard en ordent ze op sequentiële shardsleutel. Deze strategie ondersteunt toepassingen die vaak sets van items ophalen met behulp van bereikvragen. Bereikquery's geven een verzameling gegevensitems terug voor een shard-sleutel die binnen een bepaald bereik valt.

Als een toepassing bijvoorbeeld regelmatig alle orders moet vinden die in een bepaalde maand zijn geplaatst, kunt u de gegevens sneller ophalen als u alle orders voor een maand opslaat in datum- en tijdvolgorde in dezelfde shard. Als u elke bestelling in een andere shard opslaat, moet de toepassing deze individueel ophalen door veel gerichte zoekopdrachten uit te voeren. In het volgende diagram worden sequentiële sets of reeksen van gegevens getoond die zijn opgeslagen in shards.

Diagram met opeenvolgende sets, of bereiken, van gegevens die zijn opgeslagen in shards.

In dit voorbeeld is de shard-sleutel een samengestelde sleutel die de ordermaand als belangrijkste element bevat, gevolgd door de dag en tijd van de order. Nieuwe orders worden automatisch gesorteerd terwijl ze worden gemaakt en toegevoegd aan een shard.

Sommige gegevensarchieven ondersteunen tweedelige shardsleutels. Een partitiesleutel identificeert de shard en een rijsleutel identificeert een item in de shard op unieke wijze. De shard slaat doorgaans gegevens op in rijsleutelvolgorde. Voor items die bereikquery's nodig hebben en gegroepeerd moeten worden, kunt u een shard-sleutel gebruiken die dezelfde waarde heeft voor de partitiesleutel, maar een unieke waarde voor de rijsleutel.

Strategie voor sharding op basis van hash

De hash-gebaseerde strategie vermindert de kans op hotspots, wat shards zijn die een onevenredige hoeveelheid belasting ontvangen. Deze strategie distribueert gegevens over shards om de grootte en gemiddelde belasting van elke shard te balanceren. De shardinglogica berekent in welke shard een item moet worden opgeslagen op basis van een hash van een of meer attributen van de gegevens. De gekozen hashfunctie moet gegevens gelijkmatig verdelen over de shards. In het volgende diagram toont het versnipperen van tenantgegevens op basis van een hash van tenant-id's.

Diagram dat het splitsen van tenantgegevens laat zien op basis van een hash van tenant-id's.

Als u inzicht wilt krijgen in het voordeel van de hash-strategie ten opzichte van andere shardingstrategieën, kunt u overwegen hoe een multitenant-toepassing die nieuwe tenants opeenvolgend registreert, de tenants mogelijk toewijst aan shards in het gegevensarchief. Wanneer u de bereikstrategie gebruikt, worden de gegevens voor tenants 1 tot n opgeslagen in shard A, worden de gegevens voor tenants n+1 tot m opgeslagen in shard B en worden latere tenantbereiken toegewezen aan opeenvolgende shards. Als de meest recent geregistreerde tenants ook de actiefste zijn, vindt de meeste gegevensactiviteit plaats in een paar shards, wat hotspots kan veroorzaken. De hashstrategie wijst daarentegen tenants toe aan shards op basis van een hash van hun tenant-id. De hash verdeelt meestal sequentiële tenants over verschillende shards, waardoor de belasting wordt gebalanceerd. In het vorige diagram ziet u deze benadering voor tenants 55 en 56.

Strategie voor geografische sharding

De geografische strategie wijst gegevens toe aan shards op basis van de geografische oorsprong of de beoogde regio waarin die gegevens worden geconsumeerd. In veel workloads worden gebruikers en de gegevens die ze genereren, geconcentreerd in specifieke regio's. Wettelijke vereisten, zoals wetgeving voor gegevenslocatie, kunnen vereisen dat specifieke gegevens binnen een specifieke jurisdictie blijven. Zelfs zonder regelgevingsstuurprogramma's vermindert het plaatsen van gegevens dicht bij de gebruikers die er het vaakst toegang toe hebben de netwerklatentie voor lees- en schrijfbewerkingen.

Diagram dat sharding van gegevens toont op basis van de geografie van de toepassinginstantie.

In deze strategie leidt u de shardsleutel af van een geografisch kenmerk, zoals het land/de regio van de gebruiker, de oorspronkelijke datacenterregio of een regionale tenant-id. Je host elke shard in of bevestigt deze aan de infrastructuur binnen die geografische grens.

Een toepassing die klanten in Noord-Amerika, Europa en Azië-Pacific bedient, onderhoudt bijvoorbeeld drie shardgroepen: één groep in elke bijbehorende Azure-regio. Een Europese toepassing die alleen europese gebruikers bedient, stuurt een aanvraag naar de Europese shard. Deze aanpak vermindert de latentie en voldoet aan de vereisten voor gegevenslocatie.

Geografische sharding introduceert het risico op ongelijke gegevensdistributie. Als de meeste gebruikers zich in één regio bevinden, draagt de shard van die regio een onevenredig grote last en opslagcapaciteit. U kunt geografische sharding binnen elke regio combineren met een andere strategie, zoals hash of opzoekactie, om de belasting gelijkmatig over meerdere shards binnen dezelfde geografische grens te verdelen.

Voordelen en overwegingen voor elke strategie

De vier shardingstrategieën hebben de volgende voordelen en overwegingen:

  • De zoekstrategie biedt meer controle over de configuratie van shards. Virtuele shards verminderen de impact van herverdeling omdat u nieuwe fysieke partities kunt toevoegen om de werkbelasting te verdelen. U kunt de toewijzing tussen een virtuele shard en de fysieke partities wijzigen zonder dat dit van invloed is op de toepassingscode. Door shardlocaties op te zoeken, wordt overhead toegevoegd.

  • De bereikstrategie is eenvoudig te implementeren en werkt goed met bereikquery's. Bereikqueries kunnen meerdere gegevens ophalen uit één shard in één bewerking. Gegevensbeheer is eenvoudiger. U kunt bijvoorbeeld updates per tijdzone plannen op basis van lokale belastingspatronen wanneer gebruikers in dezelfde regio een shard delen. De belasting wordt met deze strategie echter niet gelijkmatig verdeeld over de fragmenten. Herverdeling is moeilijk en kan ongelijkmatige belasting niet oplossen wanneer de meeste activiteit zich concentreert op aangrenzende shard keys.

  • De hashstrategie biedt een betere kans op een gelijkmatige verdeling van gegevens en belasting. U kunt aanvragen rechtstreeks routeren met behulp van de hash-functie zonder een kaart te onderhouden. Door de hash te berekenen, wordt enige overhead toegevoegd. Herverdeling is moeilijk zonder consistente hashing.

  • De geografische strategie voldoet aan vereisten voor gegevenslocatie en soevereiniteit die andere strategieën niet inherent aanpakken. Het vermindert lees- en schrijflatentie wanneer gebruikers toegang hebben tot gegevens in hun regio. Geografische sharding kan echter aanzienlijke data- en laadonevenwichtigheid veroorzaken wanneer gebruikerspopulaties niet evenwichtig over regio's zijn verdeeld. Query's die regio's bestrijken, zoals wereldwijde rapportage, moeten gegevens ophalen uit alle geografische shards en hebben te maken met een hogere latentie. Combineer geografische sharding met een andere strategie binnen elke regio wanneer u zowel naleving als zelfs verdeling van belasting nodig hebt.

De meeste shardingsystemen implementeren een van deze benaderingen, maar u moet ook rekening houden met de zakelijke vereisten van uw toepassing en de bijbehorende patronen voor gegevensgebruik. Bijvoorbeeld in een toepassing met meerdere tenants:

  • U kunt gegevens sharden op basis van de workload. Gegevens van zeer dynamische tenants scheiden in afzonderlijke shards om de toegangssnelheid tot gegevens voor andere tenants te verbeteren.

  • U kunt gegevens fragmenteren op basis van gebruikerslocatie. Haal tenantgegevens in een specifieke geografische regio offline voor back-up en onderhoud tijdens de daluren van die regio, terwijl tenantgegevens in andere regio's online blijven tijdens hun kantooruren.

  • Wijs hoogwaardige tenants hun eigen toegewezen, licht geladen shards toe. Tenants met een lagere waarde kunnen dichter verpakte shards delen.

  • Sla gegevens op voor tenants die sterke gegevensisolatie en privacy nodig hebben op afzonderlijke servers.

Operaties voor schaal en gegevensverplaatsing voor elke strategie

Elke shardingstrategie biedt verschillende mogelijkheden en complexiteitsniveaus voor het beheren van inschalen, uitschalen, gegevensverplaatsing en statusonderhoud.

  • Met de opzoekstrategie kunt u bewerkingen voor schalen en gegevensverplaatsing op gebruikersniveau online of offline uitvoeren. Gegevens verplaatsen:

    1. Bepaalde of alle gebruikersactiviteiten onderbreken, meestal tijdens dalperioden.

    2. Verplaats de gegevens naar de nieuwe virtuele partitie of fysieke shard.

    3. Werk de toewijzingen bij.

    4. Alle caches die deze gegevens bevatten, ongeldig maken of vernieuwen.

    5. Gebruikersactiviteit hervatten.

    U kunt deze bewerking vaak centraal beheren. De opzoekstrategie vereist dat de status zeer cachebaar is en replicavriendelijk is.

  • De bereikstrategie beperkt schaal- en gegevensverplaatsingsbewerkingen omdat u gegevens moet splitsen en samenvoegen tussen shards, meestal terwijl een deel of alle gegevensopslag offline is. Wanneer u gegevens verplaatst om shards te herverdelen, elimineert u mogelijk geen ongelijke belasting als de meeste activiteit zich richt op sleutels van aangrenzende shards of data-identificatoren binnen hetzelfde bereik. Voor de bereikstrategie is mogelijk ook status vereist om bereiken toe te wijzen aan fysieke partities.

  • De hashstrategie maakt schaal- en gegevensverplaatsingsbewerkingen ingewikkeld. De partitiesleutels zijn hashes van de shard-sleutels of gegevensidentificaties. Met een standaardhashfunctie, zoals hash(key) mod Nhet toevoegen of verwijderen van een shard, worden de meeste sleutels opnieuw toegewezen en wordt grootschalige gegevensmigratie geactiveerd. Consistente hashing vermindert deze impact door de hash-ruimte zodanig te rangschikken dat slechts een klein deel van de sleutels wordt verplaatst wanneer het aantal shards verandert. De hashstrategie vereist geen onderhoud van een afzonderlijke toewijzingsstatus.

  • De geografische strategie koppelt schaalbewerkingen rechtstreeks aan het inrichten van regionale infrastructuur. Als u capaciteit toevoegt in een bepaalde regio, wordt de belasting in een andere regio niet verlicht. Wettelijke vereisten die geografische sharding verplicht stellen, kunnen ook de verplaatsing van gegevens over geografische grenzen beperken. In elke regio gebruikt het schalen de secundaire strategie waarmee gegevens over de shards van die regio worden verdeeld.

Problemen en overwegingen

Houd rekening met de volgende punten wanneer u besluit hoe u dit patroon implementeert:

  • Gebruik sharding die complementair is aan andere vormen van partitionering, zoals verticale partitionering en functionele partitionering. Een enkele shard kan bijvoorbeeld verticaal gepartitioneerde entiteiten bevatten en u kunt een functionele partitie implementeren als meerdere shards. Zie Horizontale, verticale en functionele gegevenspartitionering voor meer informatie.

  • Houd shards evenwichtig zodat ze allemaal een vergelijkbaar I/O-volume (input/output) kunnen verwerken. In de loop van de tijd ontstaat gegevensscheeftrekking wanneer records worden ingevoegd en verwijderd, wat leidt tot hotspots. Plan om periodiek opnieuw te verdelen.

    Herbalanceren verplaatst gegevens tussen shards en veroorzaakt vaak downtime of verminderde doorvoer. Gebruik virtuele partities om minder vaak opnieuw te verdelen. Wijs veel logische partities toe aan minder fysieke shards. Wanneer een shard overbelast is, herdistribueert u de virtuele partities naar nieuwe fysieke shards zonder dat u de hele gegevensset opnieuw hoeft te maken. Azure Cosmos DB gebruikt deze methode om het partitieschema los te koppelen van de fysieke infrastructuur.

    Geef de voorkeur aan veel kleine shards boven enkele grote shards. Kleinere shards migreren sneller, verdelen de belasting gelijkmatiger en bieden meer flexibiliteit voor herdistributie van gegevens.

  • Gebruik stabiele gegevens voor de shard-sleutel. Als de shardsleutel wordt gewijzigd, moet u mogelijk het bijbehorende gegevensitem verplaatsen tussen shards, waardoor de overhead van de updatebewerking toeneemt. Vermijd het baseren van de shard-sleutel op mogelijk vluchtige informatie. Kies kenmerken die invariant zijn of van nature een sleutel vormen.

  • Zorg ervoor dat de shardkeys uniek zijn. Gebruik bijvoorbeeld geen auto-incrementvelden als shard-sleutel. In sommige systemen kunnen automatisch opgehoogde velden niet worden gesynchroniseerd tussen shards, wat kan resulteren in items in verschillende shards die dezelfde shardsleutel hebben.

    Opmerking

    Automatisch gegenereerde waarden in andere velden die geen shardsleutels zijn, kunnen ook problemen veroorzaken. Als u bijvoorbeeld automatisch gemaakte velden gebruikt om unieke id's te genereren, kunnen twee verschillende items in verschillende shards dezelfde id krijgen.

  • Shard de gegevens ter ondersteuning van de meest uitgevoerde query's. Mogelijk kunt u geen shardsleutel ontwerpen die overeenkomt met de vereisten van elke query op basis van de gegevens. Maak indien nodig secundaire indextabellen ter ondersteuning van query's die gegevens ophalen op kenmerken die geen deel uitmaken van de shardsleutel. Zie indextabelpatroon voor meer informatie.

  • Ontwerp uw shardsleutel en gegevensmodel om de meeste bewerkingen binnen het bereik van één shard te houden. Query's die slechts toegang hebben tot één shard, zijn efficiënter dan query's die gegevens ophalen uit meerdere shards. Denormaliseer uw gegevens om gerelateerde entiteiten te bewaren die vaak samen worden opgevraagd, zoals klanten en hun orders, in dezelfde shard om het aantal afzonderlijke leesbewerkingen te verminderen.

    Query's voor meerdere shards voegen latentie, resourceverbruik en complexiteit toe. Wanneer een toepassing gegevens uit meerdere shards moet ophalen, moet u parallelle fan-outquery's gebruiken die gelijktijdig op elke shard worden uitgevoerd en de resultaten aggregeren. Zelfs bij parallelle uitvoering bepaalt de traagste shard de algehele latentie.

    Aanbeveling

    Als een entiteit in een shard verwijst naar een entiteit in een andere shard, neemt u de shardsleutel voor de tweede entiteit op als onderdeel van het schema voor de eerste entiteit. Deze aanpak kan de prestaties verbeteren van query's die verwijzen naar gerelateerde gegevens in shards.

  • Herzie uw shardsleutel of of sharding geschikt is voor uw behoeften als uw workload een sterke transactionele integriteit over de grenzen van shards heen vereist. Cross-shard-transacties zijn een uitdaging. Gedistribueerde coördinatieprotocollen, zoals doorvoer in twee fasen, latentie toevoegen, foutmodi introduceren en doorvoer verminderen. De meeste shard-systemen vermijden gedistribueerde transacties en gebruiken in plaats daarvan uiteindelijke consistentie. In dit model wordt elke shard onafhankelijk bijgewerkt en verwerkt de toepassing tijdelijke inconsistenties.

  • Zorg ervoor dat de resources die beschikbaar zijn voor elk shard-opslagknooppunt de schaalbaarheidsvereisten kunnen verwerken in termen van gegevensgrootte en doorvoer. Zie Strategieën voor gegevenspartitionering voor meer informatie.

  • Overweeg om de referentiegegevens naar alle shards te repliceren. Als een query op een shard ook verwijst naar statische of trage gegevens, voegt u deze gegevens toe aan de shard. De toepassing kan vervolgens alle gegevens voor de query ophalen zonder een retour naar een afzonderlijk gegevensarchief te maken.

    Opmerking

    Als referentiegegevens in meerdere shards worden gewijzigd, moet het systeem deze wijzigingen synchroniseren voor alle shards. Een zekere mate van inconsistentie kan optreden terwijl deze synchronisatie wordt uitgevoerd. Ontwerp uw toepassingen om deze inconsistentie te verdragen.

  • Gesharde systemen vermenigvuldigen de operationele belasting. Plan voor deze zorgen.

    • Monitoring: U moet metrische gegevens en logboeken aggregeren over alle shards om een volledige weergave van de systeemstatus te krijgen.

    • Back-up en herstel: U moet onafhankelijk van elke shard een back-up maken en herstelprocedures ontwerpen om consistentie tussen shards te behouden. Een herstel op een bepaald moment van één shard kan inconsistenties met andere shards veroorzaken.

    • Schemawijzigingen: U moet DDL-wijzigingen (Data Definition Language) coördineren voor elke shard.

    U kunt deze taken implementeren met behulp van scripts of andere automatiseringsoplossingen.

  • U kunt shards geoloceren om hun data in de buurt van de toepassingsexemplaren te plaatsen die deze gebruiken. Deze aanpak kan de prestaties verbeteren, maar vereist extra planning voor bewerkingen die toegang moeten hebben tot meerdere shards op verschillende locaties.

Wanneer gebruikt u dit patroon?

Aanbeveling

Voordat u een aangepaste sharding-laag ontwerpt, bepaalt u welke sharding-verantwoordelijkheden uw gegevensplatform al verwerkt. Sommige services beheren sharding volledig. Azure Cosmos DB distribueert bijvoorbeeld gegevens over fysieke partities, verwerkt splitsingen en routeert query's zonder tussenkomst van de toepassing. Andere services beheren sharding gedeeltelijk. Azure SQL Database biedt bijvoorbeeld hulpprogramma's voor elastische databases voor shard-toewijzingsbeheer en gegevensafhankelijke routering, maar u ontwerpt de shardsleutel en beheert splitsbewerkingen. Gebruik het Sharding-patroon wanneer u de shardinglogica zelf bouwt en gebruikt.

Gebruik dit patroon wanneer:

  • Het totale gegevensvolume overschrijdt de opslagcapaciteit van één database-exemplaar en er is geen optie voor verticaal schalen.

  • De transactiedoorvoer of de gelijktijdigheid van queries overschrijdt wat één enkele instantie kan ondersteunen, en alleen leesreplica's lossen het knelpunt niet op omdat de schrijfbelasting ook hoog is.

    Opmerking

    Sharding verbetert de prestaties en schaalbaarheid van een systeem en kan ook de beschikbaarheid verbeteren. Een fout in de ene partitie verhindert niet noodzakelijkerwijs dat een toepassing toegang krijgt tot gegevens in andere partities. En een operator kan onderhoud of herstel van één partitie uitvoeren zonder dat alle gegevens niet beschikbaar zijn. Zie richtlijnen voor gegevenspartitionering voor meer informatie.

  • Wettelijke of nalevingsvereisten verplichten dat specifieke gegevenssubsets zich in specifieke geografische jurisdicties bevinden en dat er geen implementatie van één regio aan alle vereisten kan voldoen.

  • Afzonderlijke tenants of klantsegmenten vereisen fysieke gegevensisolatie om beveiligings-, prestatie- of contractuele redenen.

    In dergelijke scenario's wordt het sharding-patroon soms toegepast buiten traditionele gegevensarchieven. Een DNS-zonebeheersysteem kan bijvoorbeeld worden opgedeeld naar team, omgeving of regio om de impact van DNS-wijzigingen te verminderen en duidelijke eigenaarsgrenzen vast te stellen. In die context is de primaire motivatie operationele segmentatie in plaats van schaalbaarheid. Zie Sharding private DNS-zones voor meer informatie.

Sharding introduceert aanzienlijke en permanente complexiteit in uw gegevensarchitectuur. Deze complexiteit is van invloed op ontwikkeling, bewerkingen, testen, queryontwerp en herstel van fouten voor de levensduur van het systeem.

Dit patroon is mogelijk niet geschikt wanneer:

  • Uw gegevensvolume en doorvoercapaciteit passen binnen één database-exemplaar, zelfs met de verwachte groeiverwachting. Verticaal schalen behoudt de eenvoud van query's en transactionele integriteit.

  • Uw knelpunt is een leesvolume, geen schrijfvolume of opslagcapaciteit. Leesreplica's en cachelagen kunnen het leesverkeer ontlasten zonder de cross-shard query-complexiteit die sharding met zich meebrengt.

  • Uw database-engine ondersteunt partitionering op tabelniveau die voldoet aan uw prestatiebehoeften. Partitionering binnen één exemplaar vereist geen meerdere servers of routeringslogica.

  • Voor uw dominante querypatronen zijn joins tussen entiteiten, multientiteitstransacties of aggregaties met volledige gegevenssets vereist. Sharding maakt deze bewerkingen kostbaar, en de overhead van fan-outquery's en gedistribueerde coördinatie kan de schaalvoordelen tenietdoen.

Werklastontwerp

Evalueer hoe u het Sharding-patroon gebruikt in het ontwerp van een workload om de doelstellingen en principes te verhelpen die worden behandeld in de pijlers van het Azure Well-Architected Framework. De volgende tabel bevat richtlijnen over hoe dit patroon de doelstellingen van elke pijler ondersteunt.

Pilaar Hoe dit patroon ondersteuning biedt voor pijlerdoelen
betrouwbaarheid ontwerpbeslissingen helpen uw workload tolerant te worden defect te raken en ervoor te zorgen dat deze herstelt naar een volledig functionerende status nadat er een storing is opgetreden. Gegevens en verwerking worden geïsoleerd voor de shard, zodat een storing in één shard geïsoleerd blijft voor die shard.

- Gegevenspartitionering
- RE:07 Zelfbehoud
Kostenoptimalisatie is gericht op het ondersteunen en verbeteren van het rendement van uw workload op investeringen. Een systeem dat shards implementeert, profiteert vaak van het gebruik van meerdere exemplaren van goedkopere reken- of opslagresources in plaats van één duurdere resource. In veel gevallen kan deze configuratie u geld besparen.

- CO:07 Componentkosten
Prestatie-efficiëntie helpt uw workload efficiënt te voldoen aan de vereisten door middel van optimalisaties in schalen, gegevens en code. Wanneer u sharding gebruikt in uw schaalstrategie, worden gegevens en verwerking geïsoleerd voor elke shard, zodat aanvragen alleen concurreren voor resources binnen de toegewezen shard. U kunt ook sharding gebruiken om te optimaliseren op basis van geografie.

- PE:05 Schalen en partitioneren
- PE:08 Gegevensprestaties

Als dit patroon compromissen binnen een pijler introduceert, moet u deze tegen de doelstellingen van de andere pijlers overwegen.

Voorbeeld

Overweeg een website die een uitgebreide verzameling informatie over gepubliceerde boeken wereldwijd weergeeft. Het aantal mogelijke boeken dat in deze workload wordt gecatalogusd en de typische query- en gebruikspatronen overschrijden wat een individuele relationele database kan verwerken. De workloadarchitect besluit de gegevens over meerdere database-instanties te verdelen met behulp van de statische ISBN van de boeken als verdeelsleutel. In het bijzonder gebruikt de architect het controlecijfer (0 - 10) van het ISBN, dat 11 mogelijke logische shards biedt met redelijk evenwichtige gegevensdistributie.

Om te beginnen plaatst de architect de 11 logische shards in drie fysieke shards-databases. In deze benadering voor virtuele partities worden veel logische partities toegewezen aan minder fysieke knooppunten. De architect gebruikt de lookup shardingaanpak en slaat de sleutel-naar-server-toewijzing op in een shard-toewijzingsdatabase.

Diagram met een shard-SQL Database-architectuur voor een boekcatalogustoepassing.

Azure App Service heeft het label Boekcataloguswebsite. Het maakt verbinding met meerdere SQL Database-exemplaren en een Azure AI Search-exemplaar. Een van de databases is gelabeld als de ShardMap-database. Het bevat een voorbeeldtabel die een deel van de toewijzingstabel weerspiegelt, dat verderop in dit artikel wordt vermeld. De tabel bevat drie exemplaren van sharddatabases: bookdbshard0, bookdbshard1 en bookdbshard2. De andere databases bevatten identieke voorbeelden van tabellen eronder. De tabellen bevatten Boeken, Library of Congress-catalogus en een aanduiding van meer tabellen. AI Search wordt gebruikt voor facetnavigatie en sitezoekopdrachten. Een beheerde identiteit wordt geassocieerd met de App Service.

Shardmapping opzoeken

De shard-toewijzingsdatabase bevat de volgende shardtoewijzingstabel en -gegevens.

SELECT ShardKey, DatabaseServer
FROM BookDataShardMap
| ShardKey | DatabaseServer |
|----------|----------------|
|        0 | bookdbshard0   |
|        1 | bookdbshard0   |
|        2 | bookdbshard0   |
|        3 | bookdbshard1   |
|        4 | bookdbshard1   |
|        5 | bookdbshard1   |
|        6 | bookdbshard2   |
|        7 | bookdbshard2   |
|        8 | bookdbshard2   |
|        9 | bookdbshard0   |
|       10 | bookdbshard1   |

Voorbeeld van websitecode: toegang tot één shard

De website is niet op de hoogte van het aantal fysieke sharddatabases (drie in dit geval) of de logica waarmee een shardsleutel wordt toegewezen aan een database-exemplaar. Het weet alleen dat het controlecijfer van het ISBN van een boek de shardsleutel is. De website heeft alleen-leestoegang tot de shard map-database en lees-/schrijftoegang tot alle sharddatabases. In dit voorbeeld gebruikt de website de door het systeem beheerde identiteit van de Azure App Service-host voor autorisatie, waardoor geheimen buiten de verbindingsreeksen blijven.

De website is geconfigureerd met de volgende verbindingsreeksen in een appsettings.json bestand, zoals in dit voorbeeld wordt weergegeven, of via App Service-app-instellingen.

{
  ...
  "ConnectionStrings": {
    "ShardMapDb": "Data Source=tcp:<database-server-name>.database.windows.net,1433;Initial Catalog=ShardMap;Authentication=Active Directory Default;App=Book Site v1.5a",
    "BookDbFragment": "Data Source=tcp:SHARD.database.windows.net,1433;Initial Catalog=Books;Authentication=Active Directory Default;App=Book Site v1.5a"
  },
  ...
}

De volgende code laat zien hoe de website een bijwerkquery uitvoert op de database-shardpool van de workload.

...

// All data for this book is stored in a shard based on the book's ISBN check digit,
// which is converted to an integer 0 - 10 (special value 'X' becomes 10).
int isbnCheckDigit = book.Isbn.CheckDigitAsInt;

// Establish a pooled connection to the database shard for this specific book.
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: isbnCheckDigit, cancellationToken))
{
  // Update the book's Library of Congress catalog information.
  SqlCommand cmd = sqlConn.CreateCommand();
  cmd.CommandText = @"UPDATE LibraryOfCongressCatalog
                         SET ControlNumber = @lccn,
                             ...
                             Classification = @lcc
                       WHERE BookID = @bookId";

  cmd.Parameters.AddWithValue("@lccn", book.LibraryOfCongress.Lccn);
  ...
  cmd.Parameters.AddWithValue("@lcc", book.LibraryOfCongress.Lcc);
  cmd.Parameters.AddWithValue("@bookId", book.Id);

  await cmd.ExecuteNonQueryAsync(cancellationToken);
}

...

Als in de vorige voorbeeldcode book.Isbn978-8-1130-1024-6 was, moet dit isbnCheckDigit6 zijn. De OpenShardConnectionForKeyAsync(6) aanroep wordt doorgaans geïmplementeerd met behulp van een cache-aside-benadering. Als shard-gegevens in de cache voor shardsleutel 6 niet beschikbaar zijn, wordt met de methode een query uitgevoerd op de shard map database die is geïdentificeerd door de ShardMapDb connection string. De methode haalt de waarde bookdbshard2 op uit de toepassingscache of de sharddatabase en vervangt deze SHARD in de BookDbFragment verbindingsreeks. De methode brengt vervolgens een gepoolde verbinding tot stand met bookdbshard2.database.windows.net, opent deze en retourneert deze aan de aanroepende code. De code werkt vervolgens de bestaande record op dat database-exemplaar bij.

Voorbeeld van websitecode: meerdere shardtoegang

In het zeldzame geval dat de website een directe cross-shard-zoekopdracht vereist, voert de toepassing een parallelle fan-out zoekopdracht uit over alle shards.

...

// Retrieve all shard keys.
var shardKeys = shardedDatabaseConnections.GetAllShardKeys();

// Run the query in a fan-out style against each shard in the shard list.
Parallel.ForEachAsync(shardKeys, async (shardKey, cancellationToken) =>
{
  using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: shardKey, cancellationToken))
  {
    SqlCommand cmd = sqlConn.CreateCommand();
    cmd.CommandText = @"SELECT ...
                          FROM ...
                         WHERE ...";

    SqlDataReader reader = await cmd.ExecuteReaderAsync(cancellationToken);

    while (await reader.ReadAsync(cancellationToken))
    {
      // Collect the results into a thread-safe data structure.
    }

    reader.Close();
  }
});

...

Als alternatief voor cross-shard query's kan deze workload een extern beheerde index in Azure AI Search gebruiken voor site-zoekopdrachten of gefacetteerde navigatie.

Shard-exemplaren toevoegen

Het workloadteam weet dat als de gegevenscatalogus of het gelijktijdige gebruik aanzienlijk toeneemt, er mogelijk meer dan drie database-exemplaren nodig zijn. Het workloadteam verwacht niet dynamisch databaseservers toe te voegen en ze accepteren downtime van workloads wanneer een nieuwe shard online komt. Als u een nieuw shard-exemplaar online wilt brengen, moeten ze gegevens van bestaande shards naar de nieuwe shard verplaatsen en de shard-toewijzingstabel bijwerken. Met deze vrij statische benadering kan de workload zijn toewijzing van de shard-sleuteldatabase in de websitecode cachen.

De logica van de shardsleutel in dit voorbeeld heeft een bovengrens van 11 fysieke shards. Als het workloadteam via belastingschatting bepaalt dat ze meer dan 11 database-exemplaren nodig hebben, moeten ze een ingrijpende wijziging aanbrengen in de shard key-logica. Deze wijziging omvat een zorgvuldige planning van codewijzigingen en gegevensmigratie naar de nieuwe sleutellogica.

SDK-functionaliteit

In plaats van aangepaste code te schrijven voor shardbeheer en queryroutering naar SQL Database-exemplaren, evalueert u de clientbibliotheek voor elastische databases. Deze bibliotheek ondersteunt shardtoewijzingsbeheer, gegevensafhankelijke queryroutering en cross-shard-query's in zowel C# als Java.

Volgende stap

  • Consistentieniveaus in Azure Cosmos DB: het distribueren van gegevens over shards introduceert compromissen voor consistentie. In dit artikel wordt het spectrum van consistentiemodellen beschreven, van sterk tot uiteindelijk en hun gevolgen voor beschikbaarheid en latentie.
  • Horizontale, verticale en functionele gegevenspartitionering: in dit artikel worden andere strategieën beschreven voor het partitioneren van gegevens in de cloud om de schaalbaarheid te verbeteren, conflicten te verminderen en prestaties te optimaliseren.
  • Indextabelpatroon: Soms kunt u niet alle query's uitsluitend door het ontwerp van de shardsleutel ondersteunen. Een toepassing kan het patroon Indextabel gebruiken om gegevens op te halen uit een groot gegevensarchief door een andere sleutel dan de shardsleutel op te geven.
  • Gerealiseerde weergavepatroon: Als u de prestaties van sommige querybewerkingen wilt behouden, kunt u gerealiseerde weergaven maken die gegevens aggregeren en samenvatten, met name als u die gegevens over shards distribueert.