Panoramica dell'architettura di Pub/Sub

Pub/Sub è un servizio di messaggistica asincrono progettato per essere altamente affidabile e scalabile. Il servizio si basa su un componente dell'infrastruttura di Google di base su cui si basano molti prodotti Google da oltre un decennio. I prodotti Google, tra cui Ads, Ricerca e Gmail, utilizzano questa infrastruttura per inviare oltre 500 milioni di messaggi al secondo, per un totale di oltre 1 TB/s di dati. Questo articolo descrive le funzionalità di progettazione salienti che consentono a Pub/Sub di fornire questo tipo di scalabilità in modo affidabile.

Valutazione delle prestazioni di un servizio di messaggistica

Le prestazioni di un servizio di messaggistica come Pub/Sub possono essere valutate in base a tre aspetti: scalabilità, disponibilità e latenza. Questi tre fattori sono spesso in contrasto tra loro e richiedono compromessi su uno per migliorare gli altri due.

I termini "scalabilità", "disponibilità" e "latenza" possono fare riferimento a proprietà diverse di un sistema, pertanto le sezioni seguenti descrivono come vengono definiti in Pub/Sub.

Scalabilità

Un servizio scalabile deve essere in grado di gestire l'aumento del carico senza un peggioramento evidente della latenza o della disponibilità. "Carica" può fare riferimento a varie dimensioni di utilizzo in Pub/Sub:

  • Numero di argomenti

  • Numero di publisher

  • Numero di abbonamenti

  • Numero di iscritti

  • Numero di messaggi

  • Dimensioni dei messaggi

  • Frequenza di messaggi (velocità effettiva) pubblicati o consumati

  • Dimensione del backlog di un determinato abbonamento

Disponibilità

In un sistema distribuito, i tipi e la gravità dei problemi possono variare notevolmente. La disponibilità di un sistema viene misurata in base alla sua capacità di gestire diversi tipi di problemi, con un passaggio in modo corretto a un altro sistema in modo invisibile agli utenti finali. Possono verificarsi errori nell'hardware (ad esempio unità del disco non funzionanti o problemi di connettività di rete), nel software e a causa del carico. Un errore dovuto al carico potrebbe verificarsi quando un improvviso aumento del traffico nel servizio (o in altri componenti software in esecuzione sullo stesso hardware o in dipendenze software) determina una scarsità di risorse. La disponibilità può peggiorare anche a causa di un errore umano, che comporta errori nella creazione o nel deployment di software o configurazioni.

Latenza

La latenza è una misura basata sul tempo delle prestazioni di un sistema. In genere un servizio vuole ridurre al minimo la latenza quando possibile. Per Pub/Sub, le due metriche di latenza più importanti sono:

  1. Il tempo necessario per confermare un messaggio pubblicato.

  2. Il tempo necessario per consegnare un messaggio pubblicato a un sottoscrittore.

Architettura di base di Pub/Sub

Questa sezione illustra il design di Pub/Sub per mostrare come il servizio raggiunge la scalabilità e la bassa latenza mantenendo la disponibilità. Il sistema è progettato per essere scalabile orizzontalmente, in modo che un aumento del numero di argomenti, iscrizioni o messaggi possa essere gestito aumentando il numero di istanze dei server in esecuzione.

I server Pub/Sub vengono eseguiti in tutte le regioni di Google Cloud in tutto il mondo. In questo modo, il servizio offre un accesso rapido e globale ai dati, dando al contempo agli utenti il controllo sulla posizione in cui vengono archiviati i messaggi. Cloud Pub/Sub offre dati globali dell'editore e i client sottoscrittori non sono a conoscenza della posizione i server a cui si connettono o il modo in cui questi servizi instradano i dati.

I meccanismi di bilanciamento del carico di Pub/Sub indirizzano il traffico dei publisher il data center Google Cloud più vicino in cui è consentita l'archiviazione dei dati, come definito nella restrizione sulla località delle risorse delle sezioni IAM e Console di amministrazione. Ciò significa che i publisher in più regioni possono pubblicare a un singolo argomento con bassa latenza. Ogni singolo messaggio viene archiviato in una singola regione. Tuttavia, un argomento può avere messaggi archiviati in molte regioni. Quando un client sottoscrittore richiede i messaggi pubblicati in questo argomento, si connette al server più vicino che aggrega i dati di tutti i messaggi pubblicati per la consegna al client.

Pub/Sub è diviso in due parti principali: il piano dati, che gestisce lo spostamento dei messaggi tra publisher e sottoscrittori, e il piano di controllo, che gestisce l'assegnazione di publisher e sottoscrittori ai server sul piano dati. I server nel piano dati sono chiamati forwarder, mentre quelli nel piano di controllo sono denominati router. Quando i publisher e gli abbonati sono collegati ai forwarder assegnati, non hanno bisogno di alcuna informazione dai router (purché questi forwarder rimangano accessibili). Pertanto, è possibile eseguire l'upgrade del piano di controllo di Pub/Sub senza influire sui client già connessi e che inviano o ricevono messaggi.

Control plane

Il piano di controllo Pub/Sub distribuisce i client ai server di inoltro in modo da garantire scalabilità, disponibilità e bassa latenza per tutti i client. Qualsiasi inoltro è in grado di servire i client per qualsiasi argomento o sottoscrizione. Quando un client si connette a Pub/Sub, il router decide i data center a cui il client deve connettersi in base alla distanza di rete più breve, una misura della latenza sulla connessione tra due punti. All'interno di un determinato data center, il router cerca di distribuire il carico complessivo tra l'insieme di server di inoltro disponibili. Il router deve bilanciare due obiettivi diversi durante l'esecuzione di questa assegnazione: (a) uniformità del carico (ovvero, idealmente ogni forwarder è caricato allo stesso modo); e (b) stabilità delle assegnazioni (ovvero, idealmente una variazione del carico o dell'insieme di forwarder disponibili modifica il numero più piccolo di assegnazioni esistenti). Il router utilizza una variante dell'hashing coerente sviluppata da Google Research per ottenere un equilibrio regolabile tra coerenza e uniformità. Il router fornisce al client un elenco ordinato di server di inoltro a cui può prendere in considerazione la connessione. Questo elenco ordinato può cambiare in base alla disponibilità del servizio di inoltro e alla forma del carico proveniente dal client.

Un client prende questo elenco di inoltratori e si connette a uno o più di questi. Il client preferisce connettersi ai server di inoltro più consigliati dal router, ma prende in considerazione anche gli eventuali errori che si sono verificati, ad esempio potrebbe decidere di provare gli forwarding in un data center diverso se diversi tentativi verso quelli più vicini non sono andati a buon fine. Per astrarre i client Pub/Sub da questi dettagli di implementazione, esiste un proxy di servizio tra i client e gli utenti che eseguono l'ottimizzazione della connessione per conto dei client.

Piano dati - La vita di un messaggio

Il piano dati riceve i messaggi dai publisher e li invia ai client. Forse il modo migliore per comprendere il piano dati di Pub/Sub è esaminare il ciclo di vita di un messaggio, dal momento in cui viene ricevuto dal servizio a quello in cui non è più presente nel servizio. Seguiamo i passaggi per l'elaborazione di un messaggio. Ai fini di questa sezione, assumiamo che all'argomento su cui viene pubblicato il messaggio sia associata almeno una sottoscrizione. In generale, un messaggio prevede i seguenti passaggi:

  1. Un publisher invia un messaggio.

  2. Il messaggio viene scritto nello spazio di archiviazione.

  3. Pub/Sub invia al publisher una conferma di ricezione del messaggio e ne garantisce la consegna a tutte le sottoscrizioni collegate.

  4. Contemporaneamente alla scrittura del messaggio nello spazio di archiviazione, Pub/Sub lo consegna agli iscritti.

  5. Gli abbonati inviano a Pub/Sub un messaggio di conferma dell'elaborazione del messaggio.

  6. Una volta che almeno un sottoscrittore per ogni sottoscrizione ha confermato il messaggio, Pub/Sub elimina il messaggio dall'archiviazione.

Innanzitutto, un publisher invia un messaggio su un argomento a Pub/Sub. Viene criptato dal livello proxy e inviato a un server di inoltro, ovvero a cui è collegato il publisher. Per assicurare il recapito, il messaggio viene immediatamente scritto nello spazio di archiviazione. Inizialmente il server di inoltro scrive il messaggio in N cluster (dove N è un numero dispari) e considera il messaggio persistente quando è stato scritto in almeno ⌈N/2⌉ cluster. Una volta mantenuto un messaggio, l'autore dell'inoltro conferma di averlo ricevuto al publisher, dopodiché Pub/Sub garantisce che il messaggio verrà consegnato a tutte le sottoscrizioni collegate. Un processo in background scrive regolarmente i messaggi che non sono presenti in tutti i cluster N nei cluster in cui mancano.

All'interno di ogni cluster, il messaggio viene scritto su M dischi indipendenti (dove M è un numero dispari), il che richiede che i dati siano su ⌈M/2⌉ dischi prima che vengano considerati permanenti in quel cluster. In totale, qualsiasi messaggio pubblicato verrà scritto su almeno ⌈M/2⌉ dischi indipendenti in ⌈N/2⌉ cluster prima di essere considerato permanente e alla fine verrà replicato su N*M dischi.

La persona che esegue l'inoltro della pubblicazione ha un elenco di tutte le sottoscrizioni collegate a un argomento. È responsabile della persistenza sia dei messaggi pubblicati sia dei metadati che descrivono quali messaggi sono stati confermati da ogni abbonamento. L'insieme di messaggi ricevuti e archiviati da un server di inoltro per un determinato argomento, insieme a questo monitoraggio dei messaggi confermati, viene chiamato "origine dei messaggi di pubblicazione". A seconda dei requisiti di velocità effettiva per l'argomento, un singolo publisher può inviare i propri messaggi a più utenti che hanno effettuato l'inoltro e archiviarli in più origini dei messaggi di pubblicazione. Publisher diversi per lo stesso argomento possono anche inviare messaggi a diversi utenti che effettuano la pubblicazione. Ogni messaggio viene inviato a un solo utente che ha effettuato l'inoltro. Pub/Sub regola in modo dinamico il numero di server di inoltro che ricevono messaggi per un determinato argomento man mano che la velocità effettiva cambia.

I sottoscrittori ricevono i messaggi collegandosi a inoltratori sottoscrittori, tramite i quali i messaggi vengono inoltrati ai sottoscrittori dai publisher. "Connessione" nel caso di un sottoscrittore pull significa l'emissione di una richiesta pull. "Connessione" nel caso di un sottoscrittore push significa che l'endpoint push è registrato in Pub/Sub. Una volta creata una sottoscrizione, è garantito che tutti i messaggi pubblicati dopo questo punto verranno recapitati a quella sottoscrizione, ovvero ciò che chiamiamo garanzia del punto di sincronizzazione.

Ogni mittente deve richiedere i messaggi ai mittenti di pubblicazione che hanno origini di messaggi di pubblicazione per l'argomento. Come i publisher, gli abbonati possono connettersi a più di un mittente che si è iscritto per ricevere messaggi. In questo modo, non tutti gli utenti che effettuano l'inoltro di sottoscrizione devono essere a conoscenza o ricevere messaggi da tutte le origini dei messaggi di pubblicazione per un argomento. Si tratta di una proprietà importante per cui Pub/Sub può scalare orizzontalmente. In base al throughput dei messaggi inviati ai sottoscrittori, Pub/Sub regola dinamicamente il numero di inoltratori di iscrizioni tramite i quali i sottoscrittori ricevono i messaggi per un determinato argomento man mano che il throughput cambia.

Un utente che esegue la sottoscrizione invia richieste a uno o più server di inoltro della pubblicazione che hanno origini di messaggi di pubblicazione per un argomento per richiedere i messaggi di cui ha bisogno. Il server di inoltro della pubblicazione invia i messaggi non confermati al forwarding della sottoscrizione, che li inoltra quindi a un sottoscrittore.

Una volta che un sottoscrittore elabora un messaggio, invia una conferma all'inoltro di sottoscrizione. Il mittente della sottoscrizione inoltra questa conferma al forwarding della pubblicazione, che la archivia nell'origine del messaggio di pubblicazione. Dopo che tutte le sottoscrizioni di un argomento hanno confermato un messaggio, quest'ultimo viene eliminato in modo asincrono dall'origine del messaggio di pubblicazione e dall'archiviazione.

Messaggi diversi per un singolo argomento e una singola sottoscrizione possono passare attraverso molti publisher, sottoscrittori, inoltratori di pubblicazione e inoltratori di sottoscrizione. I publisher possono pubblicare su più server di inoltro contemporaneamente e i sottoscrittori possono connettersi a più utenti di inoltro della sottoscrizione per ricevere messaggi. Pertanto, il flusso di messaggi attraverso le connessioni tra publisher, sottoscrittori e utenti di inoltro può essere complesso. Il seguente diagramma mostra la potenziale trasmissione dei messaggi per un singolo argomento e una singola sottoscrizione, in cui colori diversi indicano i diversi percorsi che i messaggi possono seguire dai publisher ai sottoscrittori:

I messaggi provenienti da diversi editori passano attraverso gli utenti che si occupano di pubblicazione e inoltro delle iscrizioni agli abbonati.

Mantenere Pub/Sub in esecuzione

Garantire che un sistema distribuito come Pub/Sub possa rimanere attivo e funzionante e servire in modo efficace tutti i clienti richiede una grande visibilità e un notevole controllo del sistema. La manutenzione del servizio è responsabilità dei nostri Site Reliability Engineer (SRE). Per Pub/Sub, questi tecnici si trovano in più località in tutto il mondo per fornire una copertura 24 ore su 24, 7 giorni su 7.

Ambienti

La prima parte della manutenzione di un sistema come Pub/Sub consiste nel poter testare il software prima che venga utilizzato dai clienti. Per rendere possibile tutto ciò, sono disponibili tre ambienti Pub/Sub: test, gestione temporanea e produzione. I test e le fasi di staging non contengono traffico dei clienti, ma solo i nostri test e il monitoraggio in esecuzione continua che aiutano a trovare eventuali problemi con le release. Questi ambienti ricevono le nuove release del software prima della produzione. La differenza tra test e gestione temporanea è che quest'ultima è una replica esatta di ciò che si trova nell'ambiente di produzione (o lo sarà a breve), inclusi la versione del software e i flag della riga di comando. Nel primo caso potrebbero essere attivate funzionalità su cui gli sviluppatori stanno lavorando e che prevedono di rilasciare in futuro.

Implementazione

La procedura per implementare e testare Pub/Sub è progettata per ridurre al minimo il potenziale impatto. Vediamo i passaggi tipici per l'implementazione di una nuova versione di Pub/Sub:

  1. Assicurati che tutti i test di unità e di integrazione siano superati.

  2. Crea una nuova versione di tutti i server.

  3. Esegui il deployment dei nuovi server negli ambienti di test e di gestione temporanea.

  4. Esegui i server nell'ambiente di test e gestione temporanea per diversi giorni.

  5. Se non esistono problemi noti, passa ai server di rilascio canary, un sottoinsieme dell'ambiente di produzione con una piccola quantità di traffico dei clienti.

  6. Se non vengono rilevati problemi nella versione canary, implementa gradualmente i server in più ambienti di produzione nell'arco di diversi giorni finché non vengono rilasciati ovunque.

Poiché Pub/Sub è progettato per essere resiliente agli errori, ad esempio tramite la separazione del piano di controllo e del piano dati, l'implementazione di nuove versioni dei server è semplice per i clienti e non dovrebbe influire sul rendimento che vedono.

Monitoraggio

La chiave per mantenere Pub/Sub in funzione è rilevare e attenuare automaticamente i problemi prima che diventino visibili agli utenti finali. A questo scopo, è necessario monitorare il sistema in modo approfondito. Il team di Site Reliability Engineering (SRE) gestisce un insieme di indicatori del livello di servizio (SLI), metriche ben definite che descrivono il comportamento del sistema. Le metriche possono includere "tempo necessario per il completamento di una richiesta CreateSubscription" o "tasso di errori generati dalle richieste di pubblicazione". Queste metriche vengono misurate in vari modi. Alcuni sono segretamente interni ai nostri forwarder e router. Ad esempio, misurare il tempo necessario per scrivere i messaggi su disco.

Tutte queste misure aiutano a definire obiettivi del livello di servizio (SLO), target specifici per gli SLI. Ad esempio, "una richiesta CreateSubscription non dovrebbe richiedere più di cinque secondi." gli SRE vengono avvisati in caso di violazioni degli SLO e devono e si occupa di ricevere avvisi entro cinque minuti.

Un accordo sul livello del servizio (SLA) elenca gli SLO che definiscono il nostro le prestazioni garantite ai nostri utenti finali e le conseguenze che li rappresentano. Puoi leggere lo SLA di Pub/Sub.

Abbiamo un gruppo di clienti che pubblicano e si abbonano in modo prevedibile. Questi sono chiamati sonde. Esistono sondaggi sia per il piano dati sia per il piano di controllo. Ognuno dei nostri probe compie azioni specifiche proprio come farebbe un cliente e misura il tempo necessario per le operazioni. Ad esempio, abbiamo un probe che crea un nuovo abbonamento, pubblica un messaggio e vede il tempo necessario per creare l'abbonamento e ricevere il messaggio. Se i probatori stabiliscono che uno qualsiasi dei le metriche misurate non sono quelle previste, gli SRE ricevono avvisi.

Le metriche relative ai nostri server e ai nostri probers sono riassunte in diverse dashboard interne, il primo posto in cui gli SRE cercano quando diagnosticano potenziali problemi. Queste pagine consentono di accedere rapidamente a statistiche e grafici dell'intero servizio. Possono anche essere suddivisi per argomento, data center o singola attività.

Le metriche più interessanti per gli utenti del servizio sono esposte tramite Google Cloud Monitoring.

Controlli

Abbiamo a disposizione diversi controlli per ottimizzare il rendimento di Pub/Sub. Alcuni di questi controlli sono progettati per aiutare in caso di interruzioni dei data center o delle macchine. Possiamo applicare limitazioni di routing su alcuni o tutti gli argomenti, ovvero regole che specificano insiemi di client che possono e/o non possono connettersi a insiemi di inoltratori. Utilizziamo vincoli di routing per svuotare il traffico da attività di inoltro individuali o interi data center che non funzionano come previsto.

Un'altra funzionalità regolabile è il controllo del flusso. Questa funzionalità ci consente di massimizzare la velocità effettiva evitando di sovraccaricare il servizio. Il controllo del flusso è una forma di saturazione del traffico che consente di appianare nel tempo i picchi improvvisi e imprevisti del carico per una maggiore stabilità del servizio. Il controllo del flusso funziona a livello di sistema oppure in base all'argomento o al sottoscrittore per limitare il numero di messaggi o il numero di byte trasferiti o in sospeso. In questo caso, "in sospeso" significa che la richiesta è stata inviata al cliente, ma non è ancora stata confermata. Sia il controllo del flusso che i vincoli di routing ci consentono di ottimizzare le prestazioni di Pub/Sub senza che i clienti debbano preoccuparsi di questi dettagli di basso livello.

Riepilogo

I vantaggi in termini di scalabilità, disponibilità e latenza di un servizio come Pub/Sub definiscono la proposta di valore per i clienti che stanno valutando di passare ai servizi cloud gestiti. Qualsiasi servizio di messaggistica asincrono deve essere creato da zero tenendo presenti queste funzionalità. Con oltre un decennio di esperienza nella consegna rapida di messaggi in modo affidabile, il team di Pub/Sub ha creato e gestisce un servizio in grado di stare al passo con le esigenze dei prodotti più importanti di Google. Ora lo stesso servizio è disponibile per tutti i clienti esterni che vogliono inviare i loro messaggi in tutto il mondo senza doversi preoccupare se il loro sistema di messaggistica è in grado di gestire 2 volte, 10 o 100 volte il carico attuale.

Glossario

Termine Descrizione
cluster Un raggruppamento logico di macchine che in genere condividono lo stesso dominio in errore (ad es. rete locale condivisa e alimentazione condivisa).
piano di controllo Il livello di Pub/Sub che gestisce l'assegnazione di publisher e sottoscrittori ai server sul piano dati.
piano dati Il livello di Pub/Sub che gestisce il trasferimento dei messaggi tra publisher e sottoscrittori.
inoltro Un server nel piano di dati.
accesso ai dati a livello globale I client Pub/Sub e publisher non sono a conoscenza la posizione dei dati. Tutto il routing e l'archiviazione sono a carico del servizio stessa, in conformità con le norme relative alle limitazioni di località.
scalabile orizzontalmente La capacità di un servizio di gestire senza problemi un maggiore carico aumentando il numero di istanze dei componenti del servizio.
messaggio I dati che passano attraverso Pub/Sub.
distanza di rete Una misura della latenza sulla connessione tra due punti.
Prober Un'attività che agisce come client ed esegue in modo prevedibile una o più azioni sui server Pub/Sub.
pubblica origine messaggio Un insieme di messaggi ricevuti e archiviati da un forwarder di pubblicazione e l'insieme di ID dei messaggi confermati da tutte le sottoscrizioni collegate.
servizio Pub/Sub (pubblica/sottoscrivi) Un servizio di messaggistica in cui i mittenti dei messaggi vengono disaccoppiati dai destinatari dei messaggi
publisher Un client di Pub/Sub che crea messaggi e li invia (pubblicali) su un argomento specifico.
router Un server nel piano di controllo.
vincoli di routing Un elenco di regole che indica quali inoltratori devono o non devono essere inviati dai router ai client come possibili endpoint a cui connettersi.
accordo sul livello del servizio (SLA) Un elenco di SLO che definiscono le garanzie di prestazioni di un sistema per i clienti e delineano le conseguenze nel caso in cui non vengano soddisfatti.
indicatore del livello del servizio (SLI) Una metrica ben definita che descrive il comportamento del sistema.
obiettivo del livello di servizio (SLO) Un target specifico per un indicatore del livello del servizio.
sottoscrittore Un client di Pub/Sub che riceve messaggi su una sottoscrizione specificata.
abbonamento Un'entità denominata che rappresenta un interesse a ricevere tutti i messaggi su un determinato argomento.
garanzia del punto di sincronizzazione Il momento in cui viene creata una sottoscrizione, in cui tutti i messaggi successivi pubblicati saranno recapitati ai sottoscrittori.
argomento Un'entità denominata che rappresenta un feed di messaggi.