Balansera partitionsbelastning över flera instanser av ditt program

Om du vill skala ditt händelsebearbetningsprogram kan du köra flera instanser av programmet och få belastningsutjämningen sinsemellan. I de äldre och inaktuella versionerna EventProcessorHost kan du balansera belastningen mellan flera instanser av ditt program och kontrollpunktshändelser när du tar emot händelserna. I de nyare versionerna (5.0 och senare), EventProcessorClient (.NET och Java) eller EventHubConsumerClient (Python och JavaScript) kan du göra detsamma. Utvecklingsmodellen blir enklare med hjälp av händelser. Du kan prenumerera på de händelser som du är intresserad av genom att registrera en händelsehanterare. Om du använder den gamla versionen av klientbiblioteket kan du läsa följande migreringsguider: .NET, Java, Python och JavaScript.

I den här artikeln beskrivs ett exempelscenario för att använda flera instanser av klientprogram för att läsa händelser från en händelsehubb. Det ger dig också information om funktioner i händelseprocessorklienten, som gör att du kan ta emot händelser från flera partitioner samtidigt och belastningsutjämning med andra konsumenter som använder samma händelsehubb och konsumentgrupp.

Kommentar

Nyckeln till skalning för Event Hubs är idén med partitionerade konsumenter. Till skillnad från det konkurrerande konsumentmönstret möjliggör det partitionerade konsumentmönstret hög skala genom att ta bort konkurrensflaskhalsen och underlätta parallellitet från slutpunkt till slutpunkt.

Exempelscenario

Som ett exempel kan du överväga ett hemsäkerhetsföretag som övervakar 100 000 hem. Varje minut hämtar den data från olika sensorer, till exempel en rörelsedetektor, öppen sensor för dörr/fönster, glasbrytsdetektor och så vidare, installerade i varje hem. Företaget tillhandahåller en webbplats för boende att övervaka aktiviteten i sitt hem i nära realtid.

Varje sensor skickar data till en händelsehubb. Händelsehubben har konfigurerats med 16 partitioner. I den förbrukande änden behöver du en mekanism som kan läsa dessa händelser, konsolidera dem (filtrera, aggregera och så vidare) och dumpa aggregeringen till en lagringsblob, som sedan projiceras till en användarvänlig webbsida.

Konsumentprogram

När du utformar en konsument i en distribuerad miljö måste scenariot hantera följande krav:

  1. Skala: Skapa flera konsumenter, där varje konsument äger läsningen från några Event Hubs-partitioner.
  2. Belastningsutjämning: Öka eller minska konsumenterna dynamiskt. När till exempel en ny sensortyp (till exempel en kolmonoxiddetektor) läggs till i varje hem ökar antalet händelser. I så fall ökar operatorn (en människa) antalet konsumentinstanser. Sedan kan poolen med konsumenter balansera om antalet partitioner som de äger för att dela belastningen med de nyligen tillagda konsumenterna.
  3. Sömlöst återuppta vid fel: Om en konsument (konsument A) misslyckas (till exempel om den virtuella datorn som är värd för konsumenten plötsligt kraschar) kan andra konsumenter hämta de partitioner som ägs av konsument A och fortsätta. Fortsättningspunkten, som kallas för en kontrollpunkt eller förskjutning, bör också vara vid den exakta tidpunkt då konsument A misslyckades, eller något före det.
  4. Konsumera händelser: Medan de föregående tre punkterna handlar om hantering av konsumenten måste det finnas kod för att använda händelser och göra något användbart med det. Du kan till exempel aggregera den och ladda upp den till bloblagring.

Händelseprocessor eller konsumentklient

Du behöver inte skapa en egen lösning för att uppfylla dessa krav. Azure Event Hubs SDK:er tillhandahåller den här funktionen. I .NET- eller Java-SDK:er använder du en händelseprocessorklient (EventProcessorClient), och i Python- och JavaScript-SDK:er använder EventHubConsumerClientdu . I den gamla versionen av SDK var det händelseprocessorvärden (EventProcessorHost) som stödde dessa funktioner.

I de flesta produktionsscenarier rekommenderar vi att du använder händelseprocessorklienten för att läsa och bearbeta händelser. Processorklienten är avsedd att ge en robust upplevelse för bearbetning av händelser över alla partitioner i en händelsehubb på ett högpresterande och feltolerant sätt samtidigt som det ger ett sätt att kontrollera dess förlopp. Händelseprocessorklienter kan samarbeta inom ramen för en konsumentgrupp för en viss händelsehubb. Klienter hanterar automatiskt distribution och balansering av arbete när instanser blir tillgängliga eller otillgängliga för gruppen.

Partitionsägarskap

En händelseprocessorinstans äger och bearbetar vanligtvis händelser från en eller flera partitioner. Ägarskapet för partitioner fördelas jämnt mellan alla aktiva händelseprocessorinstanser som är associerade med en kombination av händelsehubbar och konsumentgrupper.

Varje händelseprocessor får en unik identifierare och anspråk på ägarskap för partitioner genom att lägga till eller uppdatera en post i ett kontrollpunktslager. Alla händelseprocessorinstanser kommunicerar med det här arkivet regelbundet för att uppdatera sitt eget bearbetningstillstånd och för att lära sig mer om andra aktiva instanser. Dessa data används sedan för att balansera belastningen mellan de aktiva processorerna. Nya instanser kan ansluta bearbetningspoolen för att skala upp. När instanser går ned, antingen på grund av fel eller för att skala ned, överförs partitionsägarskapet korrekt till andra aktiva processorer.

Partitionsägarposter i kontrollpunktslagret håller reda på Event Hubs-namnrymd, händelsehubbnamn, konsumentgrupp, händelseprocessoridentifierare (även kallat ägare), partitions-ID och den senaste ändrade tiden.

Event Hubs namnrymd Namn på händelsehubb Konsumentgrupp Ägare Partitions-ID Senast ändrad tid
mynamespace.servicebus.windows.net myeventhub myconsumergroup 3be3f9d3-9d9e-4c50-9491-85ece8334ff6 0 2020-01-15T01:22:15
mynamespace.servicebus.windows.net myeventhub myconsumergroup f5cc5176-ce96-4bb4-bbaa-a0e3a9054ecf 1 2020-01-15T01:22:17
mynamespace.servicebus.windows.net myeventhub myconsumergroup 72b980e9-2efc-4ca7-ab1b-ffd7bece8472 2 2020-01-15T01:22:10
:
:
mynamespace.servicebus.windows.net myeventhub myconsumergroup 844bd8fb-1f3a-4580-984d-6324f9e208af 15 2020-01-15T01:22:00

Varje händelseprocessorinstans hämtar ägarskapet för en partition och börjar bearbeta partitionen från den senast kända kontrollpunkten. Om en processor misslyckas (den virtuella datorn stängs av) identifierar andra instanser den genom att titta på den senaste ändrade tiden. Andra instanser försöker få ägarskap för de partitioner som tidigare ägdes av den inaktiva instansen. Kontrollpunktsarkivet garanterar att endast en av instanserna lyckas kräva ägarskap för en partition. Vid en viss tidpunkt finns det alltså högst en processor som tar emot händelser från en partition.

Ta emot meddelanden

När du skapar en händelseprocessor anger du funktioner som bearbetar händelser och fel. Varje anrop till funktionen som bearbetar händelser levererar en enskild händelse från en specifik partition. Det är ditt ansvar att hantera den här händelsen. Om du vill se till att konsumenten bearbetar varje meddelande minst en gång måste du skriva din egen kod med logik för återförsök. Men var försiktig med förgiftade meddelanden.

Vi rekommenderar att du gör saker relativt snabbt. Det vill: gör så lite bearbetning som möjligt. Om du behöver skriva till lagring och utföra viss routning är det bättre att använda två konsumentgrupper och ha två händelseprocessorer.

Checkpoint

Kontrollpunkter är en process där en händelseprocessor markerar eller checkar in positionen för den senast bearbetade händelsen i en partition. En kontrollpunkt markeras vanligtvis i funktionen som bearbetar händelserna och sker per partition i en konsumentgrupp.

Om en händelseprocessor kopplas från en partition kan en annan instans återuppta bearbetningen av partitionen vid den kontrollpunkt som tidigare utfördes av den senaste processorn för partitionen i den konsumentgruppen. När processorn ansluter skickas förskjutningen till händelsehubben för att ange var du ska börja läsa. På så sätt kan du använda kontrollpunkter för att både markera händelser som "slutförda" av underordnade program och för att ge återhämtning när en händelseprocessor slutar fungera. Det går att återgå till äldre data genom att ange en lägre förskjutning från den här kontrollpunktsprocessen.

När kontrollpunkten utförs för att markera en händelse som bearbetad läggs en post i kontrollpunktsarkivet till eller uppdateras med händelsens förskjutnings- och sekvensnummer. Användarna bör bestämma hur ofta kontrollpunkten ska uppdateras. Uppdatering efter varje lyckad bearbetad händelse kan få prestanda- och kostnadskonsekvenser eftersom den utlöser en skrivåtgärd till det underliggande kontrollpunktsarkivet. Kontrollpunkter för varje enskild händelse tyder också på ett mönster för köade meddelanden där en Service Bus-kö kan vara ett bättre alternativ än en händelsehubb. Tanken bakom Event Hubs är att du får "minst en gång" leverans i stor skala. Genom att göra dina underordnade system idempotent är det enkelt att återställa från fel eller omstarter som resulterar i att samma händelser tas emot flera gånger.

Följ dessa rekommendationer när du använder Azure Blob Storage som kontrollpunktslager:

  • Använd en separat container för varje konsumentgrupp. Du kan använda samma lagringskonto, men använda en container per grupp.
  • Använd inte containern för något annat och använd inte lagringskontot för något annat.
  • Lagringskontot ska finnas i samma region som det distribuerade programmet finns i. Om programmet är lokalt kan du försöka välja den region som är närmast.

På sidan Lagringskonto i Azure-portalen i avsnittet Blob Service kontrollerar du att följande inställningar är inaktiverade.

  • Hierarkisk namnrymd
  • Mjuk borttagning av blob
  • Versionshantering

Trådsäkerhet och processorinstanser

Som standard anropas funktionen som bearbetar händelser sekventiellt för en viss partition. Efterföljande händelser och anrop till den här funktionen från samma partitionskö upp bakom kulisserna när händelsepumpen fortsätter att köras i bakgrunden på andra trådar. Händelser från olika partitioner kan bearbetas samtidigt och alla delade tillstånd som nås mellan partitioner måste synkroniseras.

Nästa steg

Se följande snabbstarter: