Partitietaakverdeling voor gebeurtenisverwerking

Partitietaakverdeling is een techniek in Azure Event Hubs die gebeurtenisverwerkingsworkloads over meerdere exemplaren van uw toepassing distribueert. De gebeurtenisprocessorclient beheert automatisch het eigendom van partities en coördineert de verdeling van werk tussen alle actieve gebruikersinstanties.

In de nieuwere SDK-versies (5.0 en hoger) EventProcessorClient (.NET en Java) of EventHubConsumerClient (Python en JavaScript) wordt taakverdeling automatisch afgehandeld. U abonneert u op de gebeurtenissen waarin u geïnteresseerd bent door een gebeurtenis-handler te registreren.

In dit artikel wordt een voorbeeldscenario beschreven voor het gebruik van meerdere exemplaren van clienttoepassingen om gebeurtenissen van een Event Hub te lezen. Ook worden belangrijke concepten uitgelegd, zoals het eigendom van partities, controlepunten en taakverdeling.

Tip

Als u een oudere versie van de clientbibliotheek gebruikt, raadpleegt u de migratiehandleidingen: .NET, Java, Python en JavaScript.

Notitie

De sleutel om te schalen voor Event Hubs is het idee van gepartitioneerde consumenten. In tegenstelling tot het patroon van concurrerende consumenten maakt het gepartitioneerde consumentenpatroon grootschalig door het knelpunt van conflicten te verwijderen en end-to-end parallellisme te vergemakkelijken.

Voorbeeldscenario

Denk bijvoorbeeld aan een thuisbeveiligingsbedrijf dat 100.000 woningen bewaakt. Elke minuut krijgt het gegevens van verschillende sensoren, zoals een bewegingsdetector, deur/raam open sensor, glasonderbrekingsdetector, enzovoort, geïnstalleerd in elk huis. Het bedrijf biedt een website voor bewoners om de activiteit van hun huis in bijna realtime te bewaken.

Elke sensor pusht gegevens naar een Event Hub. De Event Hub is geconfigureerd met 16 partities. Aan het verbruikende einde hebt u een mechanisme nodig dat deze gebeurtenissen kan lezen, samenvoegen (filteren, aggregeren, enzovoort) en de aggregaties dumpen naar een opslagblob, die vervolgens wordt geprojecteerd op een gebruiksvriendelijke webpagina.

Consumententoepassing

Wanneer u een consument ontwerpt in een gedistribueerde omgeving, moet het scenario de volgende vereisten afhandelen:

  • Schaal: Maak meerdere consumenten, waarbij elke consument eigenaar wordt van het lezen van een paar Event Hubs-partities.
  • Taakverdeling: verhoog of verminder de gebruikers dynamisch. Wanneer bijvoorbeeld een nieuw sensortype (bijvoorbeeld een koolmonoxidedetector) aan elk huis wordt toegevoegd, neemt het aantal gebeurtenissen toe. In dat geval verhoogt de operator (een mens) het aantal consumentenexemplaren. Vervolgens kan de groep consumenten het aantal partities waarvan ze eigenaar zijn, opnieuw verdelen om de belasting te delen met de zojuist toegevoegde consumenten.
  • Probleemloos hervatten bij storingen: als een consument (consument A) mislukt (bijvoorbeeld de virtuele machine die als host fungeert voor de consument), kunnen andere consumenten de partities ophalen die eigendom zijn van consument A en doorgaan. Ook moet het vervolgpunt, een controlepunt of offset genoemd, precies zijn op het punt waarop consument A is mislukt, of iets daarvoor.
  • Gebeurtenissen afhandelen: terwijl de vorige drie punten betrekking hebben op het beheer van de consument, moet er code zijn om gebeurtenissen af te handelen en nuttig te gebruiken. Bijvoorbeeld aggregeren en uploaden naar blobopslag.

Gebeurtenisprocessor of consumentenclient

U hoeft niet uw eigen oplossing te bouwen om aan deze vereisten te voldoen. De Azure Event Hubs SDK's bieden deze functionaliteit. Gebruik in .NET of Java SDK's een gebeurtenisprocessorclient (EventProcessorClient). Gebruik in Python en JavaScript SDK's EventHubConsumerClient. In de oude versie van DE SDK ondersteunde de gebeurtenisprocessorhost (EventProcessorHost) deze functies.

Gebruik voor de meeste productiescenario's de gebeurtenisprocessorclient voor het lezen en verwerken van gebeurtenissen. De processorclient biedt een robuuste ervaring voor het verwerken van gebeurtenissen in alle partities van een Event Hub op een performante en fouttolerante manier en biedt een manier om de voortgang ervan te controleren. Event Processor-clients kunnen samenwerken binnen de context van een consumentengroep voor een bepaalde Event Hub. Clients beheren automatisch de distributie en balancering van het werk wanneer exemplaren wel of niet beschikbaar zijn binnen de groep.

Partitie-eigendom

Een instantie van een gebeurtenisprocessor is doorgaans eigenaar van en verwerkt gebeurtenissen van een of meer partities. Het systeem verdeelt het eigendom van partities gelijkmatig over alle actieve gebeurtenisverwerkerinstanties die zijn gekoppeld aan een event hub en consumentengroep combinatie.

Elke gebeurtenisprocessor heeft een unieke id en claimt eigendom van partities door een record toe te voegen of bij te werken in een controleopslag. Alle exemplaren van gebeurtenisprocessor communiceren periodiek met deze opslag om hun eigen verwerkingsstatus bij te werken en om andere actieve exemplaren te identificeren. Het systeem gebruikt deze gegevens om de belasting van de actieve processors te verdelen. Nieuwe instanties kunnen zich bij de verwerkingspool aansluiten om op te schalen. Wanneer exemplaren uitvallen als gevolg van storingen of om af te schalen, draagt het systeem het partitie-eigendom soepel over naar andere actieve processors.

Partitie-eigendomsrecords in de controlepuntopslag houden de Event Hubs-naamruimte, event hub-naam, consumentengroep, gebeurtenisprocessor-id (ook wel eigenaar genoemd), partitie-id en de laatste wijzigingstijd bij.

Event Hubs-naamruimte Event hub-naam Consumentengroep Eigenaar Partitie-ID Laatst gewijzigd tijdstip
mynamespace.servicebus.windows.net myeventhub mijnconsumptiegroep 3be3f9d3-9d9e-4c50-9491-85ece8334ff6 0 2020-01-15T01:22:15
mynamespace.servicebus.windows.net myeventhub mijnconsumentengroep f5cc5176-ce96-4bb4-bbaa-a0e3a9054ecf 1 2020-01-15T01:22:17
mynamespace.servicebus.windows.net myeventhub mijnconsumentengroep 72b980e9-2efc-4ca7-ab1b-ffd7bece8472 2 2020-01-15T01:22:10
:
:
mynamespace.servicebus.windows.net myeventhub mijnconsumentengroep 844bd8fb-1f3a-4580-984d-6324f9e208af 15 2020-01-15T01:22:00

Elk gebeurtenisprocessorexemplaar verkrijgt het eigendom van een partitie en begint de partitie te verwerken vanaf het laatst bekende controlepunt. Als een processor faalt (VM wordt afgesloten), detecteren andere instanties de fout door naar de laatste wijzigingstijd te kijken. Andere instanties proberen eigendom te verkrijgen van de partities die eerder eigendom waren van de inactieve instantie. Het controlepuntopslag garandeert dat slechts één van de instanties de eigendom van een partitie kan opeisen. Op een bepaald moment is er dus maximaal één processor die gebeurtenissen van een partitie ontvangt.

Berichten ontvangen

Wanneer u een gebeurtenisprocessor maakt, geeft u functies op die gebeurtenissen en fouten verwerken. Elke aanroep van de functie die gebeurtenissen verwerkt, levert één gebeurtenis van een specifieke partitie. U moet deze gebeurtenis afhandelen. Als u ervoor wilt zorgen dat de consument elk bericht ten minste één keer verwerkt, schrijft u uw eigen code met logica voor opnieuw proberen. Maar wees voorzichtig met vergiftigde berichten.

Snel omgaan met gebeurtenissen. Dat wil gezegd, doe zo weinig mogelijk verwerking. Als u naar de opslag moet schrijven en wat routering moet uitvoeren, is het beter om twee consumentengroepen te gebruiken en twee gebeurtenisprocessors te hebben.

Controlepunt

Controlepunten zijn een proces waarmee een gebeurtenisprocessor de positie van de laatst verwerkte gebeurtenis binnen een partitie markeert of doorvoert. Het markeren van een controlepunt vindt meestal plaats in de functie die de gebeurtenissen verwerkt en plaatsvindt per partitie binnen een consumentengroep.

Als een event processor de verbinding met een partitie verbreekt, kan een andere instance de verwerking van de partitie hervatten op het checkpoint dat de laatste processor van die partitie in die consumentengroep dat eerder is vastgelegd. Wanneer de processor verbinding maakt, wordt de offset doorgegeven aan de Event Hub om de locatie op te geven waar vanaf gelezen moet worden. Op deze manier kunt u controlepunten gebruiken om gebeurtenissen te markeren als 'voltooid' door downstreamtoepassingen en om tolerantie te bieden wanneer een gebeurtenisprocessor uitvalt. U kunt terugkeren naar oudere gegevens door een lagere offset op te geven van dit controlepuntproces.

Wanneer het controlepunt een gebeurtenis markeert als verwerkt, wordt een vermelding in het controlepuntarchief toegevoegd of bijgewerkt met het offset- en volgnummer van de gebeurtenis. Bepaal de frequentie van het bijwerken van het controlepunt. Bijwerken na elke verwerkte gebeurtenis kan gevolgen hebben voor de prestaties en kosten, omdat er een schrijfbewerking naar het onderliggende controlepuntarchief wordt geactiveerd. Controlepunten voor elke gebeurtenis wijzen ook op een berichtenpatroon in de wachtrij waarvoor een Service Bus-wachtrij een betere optie kan zijn dan een Event Hub. Het idee achter Event Hubs is dat u 'ten minste één keer' levering krijgt op grote schaal. Door uw downstreamsystemen idempotent te maken, wordt het eenvoudig om te herstellen van fouten of opnieuw opstarten, waarbij dezelfde gebeurtenissen meerdere keren worden ontvangen.

Volg deze aanbevelingen wanneer u Azure Blob Storage als controlepuntarchief gebruikt:

  • Gebruik een afzonderlijke container voor elke consumentengroep. U kunt hetzelfde opslagaccount gebruiken, maar één container per groep gebruiken.
  • Gebruik het opslagaccount niet voor iets anders.
  • Gebruik de container niet voor iets anders.
  • Maak het opslagaccount in dezelfde regio als de geïmplementeerde toepassing. Als de toepassing on-premises is, probeert u de dichtstbijzijnde regio te kiezen.

Controleer op de pagina Opslagaccount in Azure Portal in de sectie Blob-service of de volgende instellingen zijn uitgeschakeld.

  • Hiërarchische naamruimte
  • Blob soft verwijderen
  • Versiebeheer

Threadveiligheid en processorinstanties

De functie die gebeurtenissen verwerkt, wordt standaard sequentieel aangeroepen voor een bepaalde partitie. Volgende gebeurtenissen en aanroepen naar deze functie vanuit dezelfde partitiewachtrij worden in de wachtrij geplaatst terwijl de gebeurtenispomp op de achtergrond op andere threads blijft werken. Gebeurtenissen van verschillende partities kunnen gelijktijdig worden verwerkt. U moet alle gedeelde statussen synchroniseren die worden geopend tussen partities.

Zie de volgende quickstarts: