Code e argomenti partizionati

Il bus di servizio di Azure usa più broker messaggi per elaborare i messaggi e più archivi di messaggistica per archiviarli. Una coda o un argomento convenzionale è gestito da un singolo broker messaggi e archiviato in un archivio di messaggistica. Le partizioni del bus di servizio consentono il partizionamento di code e argomenti, o entità di messaggistica, tra più broker messaggi e archivi di messaggistica. Il partizionamento indica che la velocità effettiva complessiva di un'entità partizionata non è più limitata dalle prestazioni di un singolo broker messaggi o archivio di messaggistica. Inoltre, un'interruzione temporanea dell'alimentazione di un archivio di messaggistica non determina la mancanza di disponibilità di una coda o di un argomento partizionato. Le code e gli argomenti partizionati possono contenere tutte le funzionalità avanzate del bus di servizio, ad esempio il supporto delle transazioni e delle sessioni.

Nota

A livello di partizionamento, esistono alcune differenze tra SKU Basic/Standard e Premium.

  • Il partizionamento è disponibile alla creazione dell'entità per tutte le code e gli argomenti in SKU di base o standard. Uno spazio dei nomi può disporre di entità partizionate e non partizionate.
  • Il partizionamento è disponibile in fase di creazione dello spazio dei nomi per lo SKU di messaggistica Premium e si partizioneranno tutte le code e gli argomenti presenti in tale spazio dei nomi. Tutte le entità partizionate precedentemente migrate negli spazi dei nomi Premium continueranno a funzionare come previsto.
  • Quando il partizionamento è abilitato negli SKU Basic o Standard, verranno sempre create 16 partizioni.
  • Quando il partizionamento è abilitato nello SKU Premium, il numero di partizioni viene specificato durante la creazione dello spazio dei nomi.

Non è possibile modificare l'opzione di partizionamento su qualsiasi spazio dei nomi,su una coda o un argomento esistente. L'opzione può essere impostata solo in fase di creazione dell'entità.

Funzionamento

Ogni coda o argomento partizionato è costituito da più partizioni. Ogni partizione viene memorizzata in un archivio di messaggistica differente e gestito da un broker messaggi diverso. Quando un messaggio viene inviato a una coda o a un argomento partizionato, il bus di servizio assegna il messaggio a una delle partizioni. La selezione viene eseguita in modo casuale dal bus di servizio o tramite una chiave di partizione che può essere specificata dal mittente.

Quando un client vuole ricevere un messaggio da una coda partizionata o da una sottoscrizione a un argomento partizionato, il bus di servizio esegue query su tutte le partizioni dei messaggi, quindi restituisce al ricevitore il primo messaggio ottenuto dagli archivi di messaggistica. Il bus di servizio memorizza nella cache gli altri messaggi e li restituisce quando riceve altre richieste. Un client destinatario non è a conoscenza del partizionamento; il comportamento verso il client di una coda o un argomento partizionato (ad esempio lettura, completamento, rinvio, non recapitabilità, prelettura) è identico a quello di un'entità normale.

L'operazione di visualizzazione in anteprima su un'entità non partizionata restituisce sempre il messaggio meno recente, ma non su un'entità partizionata. Restituisce invece il messaggio meno recente in una delle partizioni il cui broker messaggi ha risposto per primo. Non esiste alcuna garanzia che il messaggio restituito sia quello meno recente in tutte le partizioni.

I messaggi a una coda o a un argomento partizionato non presentano costi aggiuntivi, né in invio né in ricezione.

Nota

L'operazione di visualizzazione in anteprima restituisce il messaggio meno recente della partizione in base al numero di sequenza. Per le entità partizionate, il numero di sequenza viene emesso in relazione alla partizione. Per altre informazioni, vedere Sequenziazione dei messaggi e timestamp.

Uso delle chiavi di partizione

Quando un messaggio viene accodato in una coda o in un argomento partizionato, il bus di servizio controlla la presenza di una chiave di partizione. Se ne trova una, seleziona la partizione in base a tale chiave. Se invece non trova alcuna chiave di partizione, seleziona la partizione in base a un algoritmo interno.

Uso di una chiave di partizione

In alcuni scenari, ad esempio le sessioni o le transazioni, i messaggi devono essere archiviati in una partizione specifica. Tutti questi scenari richiedono l'uso di una chiave di partizione. Tutti i messaggi che usano la stessa chiave di partizione vengono assegnati alla stessa partizione. Se la partizione è temporaneamente non disponibile, il bus di servizio restituisce un errore.

In base allo scenario vengono usate come chiave di partizione proprietà dei messaggi diverse:

SessionId: se per un messaggio è impostata la proprietà ID sessione, il bus di servizio la usa come chiave di partizione. In questo modo, tutti i messaggi appartenenti alla stessa sessione vengono gestiti dallo stesso broker messaggi. Le sessioni consentono al bus di servizio di garantire l'ordinamento dei messaggi così come la coerenza degli stati della sessione.

PartitionKey: se per un messaggio è impostata la proprietà Chiave di partizione, ma non la proprietà ID sessione, il bus di servizio usa la proprietà Chiave di partizione come chiave di partizione. Se per il messaggio sono impostate entrambe le proprietà ID sessione e Chiave di partizione, queste devono avere un valore identico. Se la proprietà Chiave di partizione è impostata su un valore diverso rispetto a quello della proprietà ID sessione, il bus di servizio restituisce un'eccezione di operazione non valida. La proprietà Chiave di partizione deve essere usata se un mittente invia messaggi transazionali non sono in grado di riconoscere le sessioni. La chiave di partizione assicura che tutti i messaggi inviati all'interno di una transazione vengano gestiti dallo stesso broker di messaggistica.

MessageId: se per la coda o l'argomento è stata creata la proprietà Rilevamento di duplicati e le proprietà ID sessione o Chiave di partizione non sono impostate, la proprietà ID messaggio verrà usata come chiave di partizione. (Le librerie client di Microsoft assegnano automaticamente un ID messaggio, se questo non viene assegnato dall'applicazione mittente) In questo caso tutte le copie dello stesso messaggio vengono gestite dallo stesso broker messaggi. Questo ID consente al bus di servizio di rilevare ed eliminare i messaggi duplicati. Se la funzionalità di rilevamento duplicati non è abilitata, il bus di servizio non considera la proprietà ID messaggio come chiave di partizione.

Senza l'uso di una chiave di partizione

In assenza di una chiave di partizione, il bus di servizio distribuisce, con un'alternanza di tipo round robin, i messaggi alle partizioni della coda o dell'argomento partizionato. Se la partizione scelta non è disponibile, il bus di servizio assegna il messaggio a un’altra partizione. In questo modo, l'operazione di invio viene completata correttamente indipendentemente dalla disponibilità o meno di un archivio di messaggistica. Non si otterrà tuttavia l'ordinamento garantito fornito da una chiave di partizione.

Per un'analisi più approfondita del compromesso tra disponibilità (nessuna chiave di partizione) e coerenza (uso di una chiave di partizione), vedere Disponibilità e coerenza nell'Hub eventi. Ad eccezione dell'ID partizione non esposto agli utenti, queste informazioni si applicano ugualmente alle entità del bus di servizio partizionate.

Per concedere al bus di servizio tempo sufficiente per l'accodamento del messaggio in una partizione diversa, il valore di timeout specificato dal client che invia il messaggio deve essere maggiore di 15 secondi. È consigliabile usare il valore predefinito di 60 secondi.

Una chiave di partizione "aggiunge" un messaggio a una partizione specifica. Se l'archivio di messaggistica contenente questa partizione non è disponibile, il bus di servizio restituisce un errore. In assenza di una chiave di partizione, il bus di servizio può scegliere una partizione diversa e l'operazione verrà completata correttamente. È quindi consigliabile non specificare una chiave di partizione, a meno che non sia necessario.

Argomenti avanzati

Usare transazioni con entità partizionate

I messaggi inviati come parte di una transazione devono specificare una chiave di partizione. La chiave può essere una delle proprietà seguenti: ID sessione, chiave di partizione o ID messaggio. Tutti i messaggi che vengono inviati come parte della stessa transazione devono specificare la stessa chiave di partizione. Se si prova a inviare un messaggio senza una chiave di partizione in una transazione, il bus di servizio restituisce un'eccezione di operazione non valida. Se si prova a inviare più messaggi con chiavi di partizione diverse nella stessa transazione, il bus di servizio restituisce un'eccezione di operazione non valida. Ad esempio:

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();

Se le proprietà che fungono da chiave di partizione sono impostate, il bus di servizio aggiunge il messaggio a una partizione specifica. Questo comportamento si verifica indipendentemente dall'uso di una transazione. È consigliabile non specificare una chiave di partizione, a meno che non sia necessario.

Usare transazioni in sessioni con entità partizionate

Per inviare un messaggio transazionale a un argomento o una coda in grado di riconoscere la sessione, per il messaggio deve essere impostata la proprietà ID sessione. Se è specificata anche la proprietà Chiave di partizione, quest'ultima deve avere un valore identico a quello della proprietà ID sessione. In caso contrario, il bus di servizio restituisce un'eccezione di operazione non valida.

A differenza delle code o degli argomenti normali (non partizionati), non è possibile usare una singola transazione per inviare più messaggi a sessioni diverse. Se è stato effettuato un tentativo, il bus di servizio restituirà un'eccezione di operazione non valida, Ad esempio:

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();

Inoltro automatico dei messaggi con entità partizionate

Il bus di servizio supporta l'inoltro automatico dei messaggi da, a o tra entità partizionate. È possibile abilitare questa funzionalità durante la creazione o l'aggiornamento di code e sottoscrizioni. Per altre informazioni, vedere Abilitare l'inoltro dei messaggi. Se il messaggio specifica una chiave di partizione (ID sessione, Chiave di partizione o ID messaggio), tale chiave viene usata per l'entità di destinazione.

Considerazioni e indicazioni

  • Funzionalità a coerenza elevata: se un'entità usa funzionalità come le sessioni, il rilevamento dei duplicati o il controllo esplicito della chiave di partizionamento, le operazioni di messaggistica vengono indirizzate sempre a partizioni specifiche. In caso di traffico elevato in una delle partizioni o di stato non integro dell'archivio sottostante, queste operazioni hanno esito negativo e la disponibilità viene ridotta. La coerenza è complessivamente molto più elevata rispetto alle entità non partizionate. I problemi si verificano solo per un sottoinsieme del traffico, invece che per tutto il traffico. Per altre informazioni, vedere la discussione relativa a disponibilità e coerenza.
  • Gestione: le operazioni di creazione, aggiornamento ed eliminazione devono essere eseguite su tutte le partizioni dell'entità. Se una partizione non è integra, potrebbero verificarsi errori per queste operazioni. Per l'operazione Get è necessario aggregare da tutte le partizioni le informazioni quali il numero di messaggi. Se una partizione non è integra, lo stato di disponibilità dell'entità risulta limitato.
  • Scenari con volumi ridotti di messaggi: per questi scenari, in particolare se si usa il protocollo HTTP, potrebbe essere necessario eseguire più operazioni di ricezione per ottenere tutti i messaggi. Per le richieste di ricezione, il front-end esegue una ricezione su tutte le partizioni e memorizza nella cache tutte le risposte ricevute. Una richiesta di ricezione successiva sulla stessa connessione sarebbe avvantaggiata dalla memorizzazione nella cache e le latenze di ricezione sono minori. Se tuttavia sono presenti più connessioni o si usa HTTP, viene stabilita una nuova connessione per ogni richiesta. Non è quindi possibile assicurare che la richiesta venga ricevuta sullo stesso nodo. Se tutti i messaggi esistenti sono bloccati e memorizzati nella cache in un altro front-end, l'operazione di ricezione restituisce null. I messaggi raggiungeranno infine la scadenza e verranno ricevuti di nuovo. È consigliabile usare la connessione keep-alive HTTP. Quando si usa il partizionamento in scenari a basso volume, le operazioni di ricezione potrebbero richiedere più tempo del previsto. Di conseguenza, è consigliabile non usare il partizionamento in questi scenari. Eliminare le entità partizionate esistenti e ricrearle con il partizionamento disabilitato per migliorare le prestazioni.
  • Messaggi Sfoglia/Visualizza in anteprima: l'operazione di visualizzazione in anteprima non restituisce sempre il numero di messaggi richiesti. a causa di due motivi comuni. Il primo motivo consiste nel fatto che le dimensioni aggregate della raccolta di messaggi superano le dimensioni massime. Un altro motivo è che nelle code o negli argomenti partizionati una partizione potrebbe non avere messaggi sufficienti per restituire il numero richiesto di messaggi. In genere, se un'applicazione vuole visualizzare in anteprima/sfogliare un numero specifico di messaggi, deve chiamare ripetutamente l’operazione di visualizzazione in anteprima fino a ottenere tale numero di messaggi o fino a quando non siano più presenti messaggi di cui visualizzare l'anteprima. Per altre informazioni, inclusi gli esempi di codice, vedere Esplorazione dei messaggi.

Limiti delle entità partizionate

Attualmente il bus di servizio impone alle code o agli argomenti partizionati i limiti seguenti:

  • Per gli spazi dei nomi Premium partizionati, la dimensione del messaggio è limitata a 1 MB quando i messaggi vengono inviati singolarmente e le dimensioni del batch sono limitate a 1 MB quando i messaggi vengono inviati in un batch.

  • Le code e gli argomenti partizionati non supportano l'invio di messaggi che appartengono a sessioni diverse in una singola transazione.

  • Il bus di servizio attualmente consente fino a 100 code o argomenti partizionati per spazio dei nomi per lo SKU Basic e Standard. Ogni coda o argomento partizionato viene conteggiato ai fini della quota di 10.000 entità per spazio dei nomi.

Passaggi successivi

È possibile abilitare il partizionamento usando il portale di Azure, PowerShell, l'interfaccia della riga di comando, il modello di Resource Manager, .NET, Java, Python e JavaScript. Per altre informazioni, vedere Abilitare il partizionamento (Basic/Standard).

Per altre informazioni sui concetti di base relativi alla specifica di messaggistica Advanced Message Queueing Protocol (AMQP) 1.0 consultare la guida al protocollo AMQP 1.0.