Delen via


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 topic wordt verwerkt door één berichtenbroker en één berichtenopslag. 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 zorgt een tijdelijke onderbreking van een berichtenopslag er niet voor dat een gepartitioneerde wachtrij of onderwerp onbeschikbaar maakt. 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 u partitionering inschakelt in de Basic- of Standard-SKU's, maakt u altijd 16 partities.
  • Wanneer u partitionering inschakelt in de Premium-SKU, geeft u het aantal partities op tijdens het maken van de naamruimte.

U kunt de partitioneringsoptie voor een bestaande naamruimte, wachtrij of onderwerp niet wijzigen. U kunt de optie alleen instellen wanneer u de entiteit maakt.

Hoe het werkt

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 u een bericht naar een gepartitioneerde wachtrij of een gepartitioneerd onderwerp verzendt, wijst Service Bus het bericht toe aan een van de partities. Service Bus selecteert de partitie willekeurig of gebruikt een partitiesleutel die de afzender opgeeft.

Wanneer een client een bericht wil ontvangen van een gepartitioneerde wachtrij of van een abonnement op een gepartitioneerd onderwerp, vraagt Service Bus alle partities voor berichten op. Het retourneert het eerste bericht dat het van een van de berichtenarchieven naar de ontvanger krijgt. 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 peek-operatie bij een niet-gepartitioneerde entiteit retourneert altijd het oudste bericht, maar bij een gepartitioneerde entiteit is dat niet het geval. In plaats daarvan wordt het oudste bericht geretourneerd in een van de partities waarvan de messagebroker als eerste heeft gereageerd. Er is geen garantie dat het geretourneerde bericht het oudste is over alle partities heen.

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 is het volgnummer relatief ten opzichte van de partitie. Zie Berichtvolgorde en tijdstempels voor meer informatie.

Gebruik van partitiesleutels

Wanneer u een bericht in een gepartitioneerde wachtrij of een gepartitioneerd onderwerp in de wachtrij zet, 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. Service Bus wijst alle berichten toe die dezelfde partitiesleutel gebruiken voor 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, wordt deze door Service Bus gebruikt als partitiesleutel. Op deze manier verwerkt dezelfde berichtenbroker alle berichten die deel uitmaken van dezelfde sessie. Met behulp van sessies garandeert Service Bus de volgorde van berichten en de consistentie van sessiestatussen.

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 de 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. Gebruik de eigenschap partitiesleutel als een afzender niet-oversessiebewuste transactionele berichten verzendt. De partitiesleutel zorgt ervoor dat dezelfde berichtenbroker alle berichten verwerkt die binnen een transactie worden verzonden.

MessageId: Als u de wachtrij of het onderwerp maakt met de functie voor dubbele detectie en de eigenschappen van de sessie-id of partitiesleutel niet instelt, fungeert de eigenschapswaarde van het bericht-id als de partitiesleutel. (De Microsoft-clientbibliotheken wijzen automatisch een bericht-id toe als de verzendende toepassing dat niet doet.) In dit geval verwerkt dezelfde berichtenbroker alle kopieën van hetzelfde bericht. 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 u geen partitiesleutel opgeeft, 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. Geef daarom geen partitiesleutel op, tenzij deze is vereist.

Geavanceerde onderwerpen

Transacties met gepartitioneerde entiteiten gebruiken

Berichten die u als onderdeel van een transactie verzendt, moeten een partitiesleutel opgeven. De sleutel kan een van de volgende eigenschappen zijn: sessie-id, partitiesleutel of bericht-id. Alle berichten die u als onderdeel van dezelfde transactie verzendt, 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 u een van de eigenschappen instelt die fungeren als een partitiesleutel, maakt Service Bus het bericht vast aan een specifieke partitie. Dit gedrag treedt op, ongeacht of u een transactie gebruikt. Geef geen partitiesleutel op als dit niet nodig is.

Transacties gebruiken in sessies met gepartitioneerde entiteiten

Als u een transactioneel bericht naar een sessiebewust onderwerp of wachtrij wilt verzenden, stelt u de eigenschap sessie-id in op het bericht. Als u de eigenschap partitiesleutel opgeeft, 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, kunt u niet één transactie gebruiken om meerdere berichten naar verschillende sessies te verzenden. Als u deze bewerking probeert uit te voeren, 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 ervaart of als de onderliggende opslag onbetrouwbaar 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 van 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 ongezond is, kan dit leiden tot storingen voor deze bewerkingen. Voor de get-bewerking moeten gegevens, zoals het aantal berichten, worden samengevoegd vanuit alle partities. Als een partitie ongezond 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 antwoorden die het ontvangt in de cache op. Een volgende ontvangstaanvraag voor dezelfde verbinding profiteert van 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 deze 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 lage volumes, kunnen ontvangstbewerkingen langer duren dan verwacht. Gebruik daarom geen partitionering 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. Twee veelvoorkomende redenen verklaren 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 bepaald aantal berichten wil bekijken of doorzoeken, moet deze de weergavebewerking herhaaldelijk aanroepen totdat het aantal berichten wordt weergegeven of als 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:

  • 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-lagen. 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.

Voor meer informatie over de belangrijkste concepten van de Advanced Message Queuing Protocol (AMQP) 1.0-berichtspecificatie, raadpleegt u de HANDLEIDING voor het AMQP 1.0-protocol.