Gepartitioneerde wachtrijen en onderwerpen

Azure Service Bus maakt gebruik van meerdere berichtenbrokers om berichten en meerdere berichtenarchieven te verwerken om berichten op te slaan. Een conventionele wachtrij of onderwerp wordt verwerkt door één berichtenbroker en opgeslagen in één berichtenarchief. Met Service Bus-partities kunnen wachtrijen en onderwerpen, of berichtenentiteiten, worden gepartitioneerd in meerdere berichtenbrokers en berichtenarchieven. Partitionering betekent dat de totale doorvoer van een gepartitioneerde entiteit niet langer wordt beperkt door de prestaties van één berichtenbroker of berichtenarchief. Bovendien geeft een tijdelijke onderbreking van een berichtenarchief geen gepartitioneerde wachtrij of onderwerp niet beschikbaar. Gepartitioneerde wachtrijen en onderwerpen kunnen alle geavanceerde Service Bus-functies bevatten, zoals ondersteuning voor transacties en sessies.

Notitie

Er zijn enkele verschillen tussen de Basic/Standard- en Premium-SKU als het gaat om partitionering.

  • Partitionering is beschikbaar bij het maken van entiteiten voor alle wachtrijen en onderwerpen in Basic- of Standard-SKU's. Een naamruimte kan zowel gepartitioneerde als niet-gepartitioneerde entiteiten bevatten.
  • Partitionering is beschikbaar bij het maken van naamruimten voor de Premium Messaging-SKU en alle wachtrijen en onderwerpen in die naamruimte worden gepartitioneerd. Alle eerder gemigreerde gepartitioneerde entiteiten in Premium-naamruimten blijven werken zoals verwacht.
  • Wanneer partitionering is ingeschakeld in de Basic- of Standard-SKU's, maken we altijd 16 partities.
  • Wanneer partitionering is ingeschakeld in de Premium-SKU, wordt de hoeveelheid partities opgegeven tijdens het maken van de naamruimte.

Het is niet mogelijk om de partitioneringsoptie voor een bestaande naamruimte, wachtrij of onderwerp te wijzigen; u kunt de optie alleen instellen wanneer u de entiteit maakt.

Uitleg

Elke gepartitioneerde wachtrij of elk onderwerp bestaat uit meerdere partities. Elke partitie wordt opgeslagen in een ander berichtenarchief en verwerkt door een andere berichtenbroker. Wanneer een bericht wordt verzonden naar een gepartitioneerde wachtrij of onderwerp, wijst Service Bus het bericht toe aan een van de partities. De selectie wordt willekeurig uitgevoerd door Service Bus of met behulp van een partitiesleutel die de afzender kan opgeven.

Wanneer een client een bericht wil ontvangen van een gepartitioneerde wachtrij of van een abonnement op een gepartitioneerd onderwerp, voert Service Bus een query uit op alle partities voor berichten en retourneert vervolgens het eerste bericht dat wordt verkregen van een van de berichtenarchieven naar de ontvanger. Service Bus slaat de andere berichten in de cache op en retourneert deze wanneer er meer aanvragen worden ontvangen. Een ontvangende client is niet op de hoogte van de partitionering; het clientgerichte gedrag van een gepartitioneerde wachtrij of onderwerp (bijvoorbeeld lezen, voltooien, uitstellen, deadletter, prefetching) is identiek aan het gedrag van een reguliere entiteit.

De korte bewerking voor een niet-gepartitioneerde entiteit retourneert altijd het oudste bericht, maar niet op een gepartitioneerde entiteit. In plaats daarvan wordt het oudste bericht geretourneerd in een van de partities waarvan de berichtbroker het eerst heeft gereageerd. Er is geen garantie dat het geretourneerde bericht de oudste is voor alle partities.

Er zijn geen extra kosten verbonden wanneer u een bericht verzendt naar of een bericht ontvangt van, een gepartitioneerde wachtrij of onderwerp.

Notitie

De weergavebewerking retourneert het oudste bericht van de partitie op basis van het volgnummer. Voor gepartitioneerde entiteiten wordt het volgnummer uitgegeven ten opzichte van de partitie. Zie Berichtvolgorde en tijdstempels voor meer informatie.

Gebruik van partitiesleutels

Wanneer een bericht in een gepartitioneerde wachtrij of onderwerp wordt geplaatst, controleert Service Bus op de aanwezigheid van een partitiesleutel. Als er een wordt gevonden, wordt de partitie geselecteerd op basis van die sleutel. Als er geen partitiesleutel wordt gevonden, wordt de partitie geselecteerd op basis van een intern algoritme.

Een partitiesleutel gebruiken

Voor sommige scenario's, zoals sessies of transacties, moeten berichten in een specifieke partitie worden opgeslagen. Voor al deze scenario's is het gebruik van een partitiesleutel vereist. Alle berichten die dezelfde partitiesleutel gebruiken, worden toegewezen aan dezelfde partitie. Als de partitie tijdelijk niet beschikbaar is, retourneert Service Bus een fout.

Afhankelijk van het scenario worden verschillende berichteigenschappen gebruikt als partitiesleutel:

SessionId: Als voor een bericht de eigenschap sessie-id is ingesteld, gebruikt Service Bus deze als partitiesleutel. Op deze manier worden alle berichten die deel uitmaken van dezelfde sessie verwerkt door dezelfde berichtenbroker. Met sessies kan Service Bus de volgorde van berichten en de consistentie van sessiestatussen garanderen.

PartitionKey: Als voor een bericht de eigenschap partitiesleutel is ingesteld, maar niet de eigenschap sessie-id is ingesteld, gebruikt Service Bus de eigenschapswaarde van de partitiesleutel als partitiesleutel. Als voor het bericht zowel de sessie-id als de eigenschappen van de partitiesleutel zijn ingesteld, moeten beide eigenschappen identiek zijn. Als de eigenschap partitiesleutel is ingesteld op een andere waarde dan de eigenschap sessie-id, retourneert Service Bus een ongeldige bewerkingsuitzondering. De eigenschap partitiesleutel moet worden gebruikt als een afzender niet-oversessiebewuste transactionele berichten verzendt. De partitiesleutel zorgt ervoor dat alle berichten die binnen een transactie worden verzonden, worden verwerkt door dezelfde berichtenbroker.

MessageId: Als de wachtrij of het onderwerp is gemaakt met de functie voor dubbele detectie en de eigenschappen van de sessie-id of partitiesleutel niet zijn ingesteld, dient de eigenschapswaarde van de bericht-id als de partitiesleutel. (De Microsoft-clientbibliotheken wijzen automatisch een bericht-id toe als de verzendende toepassing dat niet doet.) In dit geval worden alle kopieën van hetzelfde bericht verwerkt door dezelfde berichtenbroker. Met deze id kan Service Bus dubbele berichten detecteren en elimineren. Als de functie voor duplicaatdetectie niet is ingeschakeld, beschouwt Service Bus de eigenschap bericht-id niet als partitiesleutel.

Geen partitiesleutel gebruiken

Als er geen partitiesleutel is, distribueert Service Bus berichten op round robin-wijze naar alle partities van de gepartitioneerde wachtrij of het gepartitioneerde onderwerp. Als de gekozen partitie niet beschikbaar is, wijst Service Bus het bericht toe aan een andere partitie. Op deze manier slaagt de verzendbewerking ondanks de tijdelijke onbeschikbaarheid van een berichtenarchief. U bereikt echter niet de gegarandeerde volgorde die een partitiesleutel biedt.

Zie Beschikbaarheid en consistentie in Event Hubs voor een uitgebreidere bespreking van de balans tussen beschikbaarheid (geen partitiesleutel) en consistentie (met behulp van een partitiesleutel). Met uitzondering van partitie-id die niet beschikbaar is voor gebruikers, is deze informatie evenzeer van toepassing op gepartitioneerde Service Bus-entiteiten.

Om Service Bus voldoende tijd te geven om het bericht in een andere partitie in de wachtrij te zetten, moet de time-outwaarde die is opgegeven door de client die het bericht verzendt, langer zijn dan 15 seconden. De standaardwaarde van 60 seconden wordt aanbevolen.

Een partitiesleutel maakt een bericht vast aan een specifieke partitie. Als het berichtenarchief met deze partitie niet beschikbaar is, retourneert Service Bus een fout. Als er geen partitiesleutel is, kan Service Bus een andere partitie kiezen en slaagt de bewerking. Daarom is het raadzaam dat u geen partitiesleutel opgeeft, tenzij deze is vereist.

Geavanceerde onderwerpen

Transacties met gepartitioneerde entiteiten gebruiken

Berichten die worden verzonden als onderdeel van een transactie moeten een partitiesleutel opgeven. De sleutel kan een van de volgende eigenschappen zijn: sessie-id, partitiesleutel of bericht-id. Alle berichten die als onderdeel van dezelfde transactie worden verzonden, moeten dezelfde partitiesleutel opgeven. Als u een bericht probeert te verzenden zonder partitiesleutel binnen een transactie, retourneert Service Bus een ongeldige bewerkingsonderzondering. Als u meerdere berichten probeert te verzenden binnen dezelfde transactie met verschillende partitiesleutels, retourneert Service Bus een ongeldige bewerkingsonderzondering. Voorbeeld:

CommittableTransaction committableTransaction = new CommittableTransaction();
using (TransactionScope ts = new TransactionScope(committableTransaction))
{
    ServiceBusMessage msg = new ServiceBusMessage("This is a message");
    msg.PartitionKey = "myPartitionKey";
    await sender.SendMessageAsync(msg); 
    ts.Complete();
}
committableTransaction.Commit();

Als een van de eigenschappen die fungeren als een partitiesleutel zijn ingesteld, maakt Service Bus het bericht vast aan een specifieke partitie. Dit gedrag treedt op of er al dan niet een transactie wordt gebruikt. Het is raadzaam om geen partitiesleutel op te geven als dit niet nodig is.

Transacties gebruiken in sessies met gepartitioneerde entiteiten

Als u een transactioneel bericht naar een sessiebewust onderwerp of een wachtrij wilt verzenden, moet voor het bericht de eigenschap sessie-id zijn ingesteld. Als de eigenschap van de partitiesleutel ook is opgegeven, moet deze identiek zijn aan de eigenschap sessie-id. Als deze verschillen, retourneert Service Bus een ongeldige bewerkingsonderzondering.

In tegenstelling tot reguliere (niet-gepartitioneerde) wachtrijen of onderwerpen, is het niet mogelijk om één transactie te gebruiken om meerdere berichten naar verschillende sessies te verzenden. Als u een poging hebt uitgevoerd, retourneert Service Bus een ongeldige bewerkingsonderzondering. Voorbeeld:

CommittableTransaction committableTransaction = new CommittableTransaction();
using (TransactionScope ts = new TransactionScope(committableTransaction))
{
    ServiceBusMessage msg = new ServiceBusMessage("This is a message");
    msg.SessionId = "mySession";
    await sender.SendMessageAsync(msg); 
    ts.Complete();
}
committableTransaction.Commit();

Automatisch doorsturen van berichten met gepartitioneerde entiteiten

Service Bus ondersteunt het automatisch doorsturen van berichten van, naar of tussen gepartitioneerde entiteiten. U kunt deze functie inschakelen bij het maken of bijwerken van wachtrijen en abonnementen. Zie Doorsturen van berichten inschakelen voor meer informatie. Als in het bericht een partitiesleutel (sessie-id, partitiesleutel of bericht-id) wordt opgegeven, wordt die partitiesleutel gebruikt voor de doelentiteit.

Belangrijke overwegingen en richtlijnen

  • Functies voor hoge consistentie: als een entiteit gebruikmaakt van functies zoals sessies, dubbele detectie of expliciete controle over partitioneringssleutels, worden de berichtenbewerkingen altijd doorgestuurd naar een specifieke partitie. Als een van de partities veel verkeer ondervindt of als het onderliggende archief beschadigd is, mislukken deze bewerkingen en wordt de beschikbaarheid verminderd. Over het algemeen is de consistentie nog steeds veel hoger dan niet-gepartitioneerde entiteiten; alleen een subset verkeer ondervindt problemen, in tegenstelling tot al het verkeer. Zie deze discussie over beschikbaarheid en consistentie voor meer informatie.
  • Beheer: Bewerkingen zoals Maken, Bijwerken en Verwijderen moeten worden uitgevoerd op alle partities van de entiteit. Als een partitie beschadigd is, kan dit leiden tot fouten voor deze bewerkingen. Voor de get-bewerking moeten gegevens, zoals het aantal berichten, worden samengevoegd vanuit alle partities. Als een partitie niet in orde is, wordt de status van de beschikbaarheid van de entiteit gerapporteerd als beperkt.
  • Scenario's met weinig volumeberichten: voor dergelijke scenario's, met name wanneer u het HTTP-protocol gebruikt, moet u mogelijk meerdere ontvangstbewerkingen uitvoeren om alle berichten te verkrijgen. Voor ontvangstaanvragen voert de front-end een ontvangst uit op alle partities en slaat alle ontvangen antwoorden in de cache op. Een volgende ontvangstaanvraag voor dezelfde verbinding zou baat hebben bij deze caching en latenties zijn lager. Als u echter meerdere verbindingen hebt of HTTP gebruikt, wordt voor elke aanvraag een nieuwe verbinding tot stand gebracht. Daarom is er geen garantie dat het op hetzelfde knooppunt terechtkomt. Als alle bestaande berichten zijn vergrendeld en in de cache zijn opgeslagen in een andere front-end, retourneert de ontvangstbewerking null. Berichten verlopen uiteindelijk en u kunt ze opnieuw ontvangen. HTTP keep-alive wordt aanbevolen. Bij het gebruik van partitionering in scenario's met weinig volumes kan het langer duren voordat de ontvangstbewerkingen langer duren dan verwacht. Daarom raden we u aan om partitionering niet te gebruiken in deze scenario's. Verwijder alle bestaande gepartitioneerde entiteiten en maak deze opnieuw met partitionering uitgeschakeld om de prestaties te verbeteren.
  • Bladeren/berichten bekijken: de weergavebewerking retourneert niet altijd het aantal berichten waarnaar wordt gevraagd. Er zijn twee veelvoorkomende redenen voor dit gedrag. Een van de redenen is dat de geaggregeerde grootte van de verzameling berichten de maximale grootte overschrijdt. Een andere reden is dat een partitie in gepartitioneerde wachtrijen of onderwerpen mogelijk niet voldoende berichten heeft om het aangevraagde aantal berichten te retourneren. Als een toepassing een specifiek aantal berichten wil bekijken/doorzoeken, moet deze de weergavebewerking herhaaldelijk aanroepen totdat het aantal berichten wordt weergegeven of er geen berichten meer zijn om te bekijken. Zie Bladeren door berichten voor meer informatie, inclusief codevoorbeelden.

Beperkingen voor gepartitioneerde entiteiten

Momenteel legt Service Bus de volgende beperkingen op voor gepartitioneerde wachtrijen en onderwerpen:

  • Voor gepartitioneerde Premium-naamruimten is de berichtgrootte beperkt tot 1 MB wanneer de berichten afzonderlijk worden verzonden en de batchgrootte is beperkt tot 1 MB wanneer de berichten in een batch worden verzonden.
  • Gepartitioneerde wachtrijen en onderwerpen bieden geen ondersteuning voor het verzenden van berichten die deel uitmaken van verschillende sessies in één transactie.
  • Service Bus staat momenteel maximaal 100 gepartitioneerde wachtrijen of onderwerpen per naamruimte toe voor de Basic- en Standard-SKU. Elke gepartitioneerde wachtrij of elk onderwerp telt mee voor het quotum van 10.000 entiteiten per naamruimte.

Volgende stappen

U kunt partitionering inschakelen met behulp van Azure Portal, PowerShell, CLI, Resource Manager-sjabloon, .NET, Java, Python en JavaScript. Zie Partitionering inschakelen (Basic/Standard) voor meer informatie.

Lees meer over de belangrijkste concepten van de ADVANCED Message Queueing Protocol (AMQP) 1.0-berichtspecificatie in de PROTOCOLhandleiding amqp 1.0.