Panoramica dell'architettura di Pub/Sub

Pub/Sub è un servizio di messaggistica asincrono progettato per essere altamente affidabile e scalabile. Il servizio è basato su un componente fondamentale dell'infrastruttura Google a cui molti prodotti Google fanno affidamento da oltre un decennio. I prodotti Google, tra cui Google 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

Un servizio di messaggistica come Pub/Sub può essere valutato 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 diverse proprietà di un sistema, quindi le sezioni seguenti descrivono come vengono definite 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 editori

  • Numero di abbonamenti

  • Numero di iscritti

  • Numero di messaggi

  • Dimensione dei messaggi

  • Percentuale 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 all'efficacia con cui viene gestito con diversi tipi di problemi, fallendo con grazia in un modo impercettibile 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 delle prestazioni di un sistema basata sul tempo. 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 spiega la progettazione di Pub/Sub per mostrare come raggiunge la sua scalabilità e bassa latenza mantenendo la disponibilità. Il sistema è progettato per essere scalabile orizzontalmente, ossia un aumento delle di argomenti, sottoscrizioni o messaggi può essere gestito aumentando di istanze di server in esecuzione.

I server Pub/Sub vengono eseguiti in tutte le regioni di Google Cloud in tutto il mondo. Questo consente al servizio di offrire un accesso rapido e globale ai dati, gli utenti controllano dove 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. Vengono archiviati tutti i singoli messaggi all'interno di una singola regione. Tuttavia, un argomento potrebbe contenere 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 editori e sottoscrittori sono collegati ai loro inoltro assegnati, non hanno bisogno di alcuna informazione dai router (purché questi ultimi 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 quando esegue questa assegnazione: (a) uniformità del carico (ovvero, idealmente ogni utente di inoltro deve avere lo stesso carico di lavoro); e (b) la stabilità delle assegnazioni (vale a dire, idealmente, una modifica del carico o una modifica nel gruppo di inoltro disponibili cambia il numero minimo di incarichi esistenti). Il router utilizza una variante di hashing coerente sviluppata da Google Research per raggiungere 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 forwarding e si connette a uno o più di essi. 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 la durata di un messaggio, dal momento in cui viene ricevuto dal servizio fino a quando non è più presente nel servizio. Seguiamo i passaggi per l'elaborazione di un messaggio. Ai fini di questa sezione, presupponiamo che all'argomento in cui è pubblicato il messaggio sia associato almeno una sottoscrizione. In generale, un messaggio prevede i seguenti passaggi:

  1. Un publisher invia un messaggio.

  2. Il messaggio è scritto nello spazio di archiviazione.

  3. Pub/Sub invia una conferma al publisher di aver ricevuto il messaggio e ne garantisce la consegna a tutte le sottoscrizioni allegate.

  4. Nel momento in cui si scrive il messaggio nello spazio di archiviazione, Pub/Sub lo consegna ai sottoscrittori.

  5. I sottoscrittori inviano una conferma a Pub/Sub di aver elaborato il 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'utente che ha effettuato l'inoltro conferma la ricezione del messaggio al publisher, dopodiché Pub/Sub garantisce che il messaggio verrà consegnato a tutte le sottoscrizioni collegate. Un processo in background scrive regolarmente tutti i messaggi che non si trovano in tutti i cluster N nei cluster in cui mancano i messaggi.

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

La persona che esegue l'inoltro della pubblicazione ha un elenco di tutte le sottoscrizioni collegate a un argomento. È responsabile della conservazione sia dei messaggi pubblicati che dei metadati, descrivendo quali messaggi sono stati confermati da ciascuna sottoscrizione. L'insieme di messaggi ricevuti e archiviati da un utente che esegue l'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. Editori diversi per lo stesso argomento possono anche inviare messaggi a utenti che hanno inoltrato la pubblicazione diversi. 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 agli utenti che effettuano l'inoltro di sottoscrizione, gli inoltri attraverso i quali i messaggi passano ai sottoscrittori dai publisher. Nel caso di un sottoscrittore di tipo pull, "connessione" implica l'invio di una richiesta di pull. Nel caso di un sottoscrittore push, "connessione" implica la registrazione dell'endpoint push in Pub/Sub. Una volta creata una sottoscrizione, è garantito che tutti i messaggi pubblicati da quel momento in poi verranno recapitati in quella sottoscrizione, una garanzia del punto di sincronizzazione.

Ogni utente che esegue l'inoltro della sottoscrizione deve richiedere messaggi ai server di inoltro che dispongono di origini di messaggi pubblicate per l'argomento. Come per i publisher, i sottoscrittori possono connettersi a più di un utente che effettua l'inoltro di sottoscrizione 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 alla velocità effettiva dei messaggi consegnati ai sottoscrittori, Pub/Sub regola dinamicamente il numero di forwarding della sottoscrizione tramite i quali i sottoscrittori ricevono i messaggi per un determinato argomento man mano che la velocità effettiva cambia.

Un utente che esegue l'inoltro della sottoscrizione invia richieste a uno o più server di inoltro 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 un numero elevato di publisher, sottoscrittori, utenti che hanno effettuato l'inoltro e utenti che effettuano l'inoltro della sottoscrizione. I publisher possono pubblicare per più utenti 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 gestione di un sistema come Pub/Sub è avere la possibilità di 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. Le attività di test e gestione temporanea non contengono traffico di clienti. contengono solo i nostri test e il nostro monitoraggio continui che ci aiutano a individuare eventuali problemi con le release. Questi ambienti ricevono 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. Per il primo potrebbero essere attivate funzionalità a cui gli sviluppatori stanno attualmente lavorando e che ne pianificano il rilascio 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 delle unità e di integrazione abbiano superato il test.

  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 nella versione canary non vengono rilevati problemi, esegui progressivamente il rilascio dei server a una fase di produzione maggiore nell'arco di diversi giorni, fino a quando non vengono rilasciati ovunque.

Poiché Pub/Sub è progettato per essere resiliente agli errori, ad esempio attraverso la separazione tra piano di controllo e piano dati, le implementazioni delle nuove versioni dei server avvengono senza problemi per i clienti e non dovrebbero avere alcun impatto sulle prestazioni che vedono.

Monitoraggio

Il segreto per mantenere Pub/Sub in esecuzione è eseguire rilevare e limitare i problemi prima che diventino visibili agli utenti finali. A questo scopo, è necessario monitorare il sistema in modo approfondito. Il team SRE (Site Reliability Engineering) gestisce una serie degli indicatori del livello del servizio (SLI), metriche ben definite che descrivono il comportamento del sistema. Le metriche possono includere "quantità di tempo necessaria per creare una sottoscrizione richiesta di completamento" o "percentuale di errori generati dalle richieste di pubblicazione". Queste metriche vengono misurate in vari modi. Alcuni sono strettamente interni ai nostri server di inoltro 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. Si tratta di chiamati prober. I prober esistono sia per il piano dati che per dal 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 prober che crea una nuova sottoscrizione, un messaggio e vede quanto tempo è stato necessario per creare la sottoscrizione ricevere il messaggio. Se i probatori stabiliscono che uno qualsiasi dei le metriche misurate non sono quelle previste, gli SRE ricevono avvisi.

Le metriche per i nostri server e i probe sono riassunte in diverse le dashboard, il primo posto che gli SRE esaminano ogni volta che diagnosticano potenziali problemi. Queste pagine consentono di accedere rapidamente alle statistiche e ai grafici dell'intero servizio. Possono anche essere suddivisi per argomento, data center o singola attività.

Le metriche più interessanti per gli utenti del servizio vengono mostrate tramite Google Cloud Monitoring.

Controlli

Abbiamo a disposizione diversi controlli per ottimizzare le prestazioni di Pub/Sub. Alcuni di questi controlli sono progettati per aiutare in caso di interruzioni dei data center o delle macchine. Possiamo applicare vincoli di routing su alcuni o tutti gli argomenti, ovvero regole che specificano insiemi di client che possono e/o non possono connettersi a gruppi di inoltro. 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à ottimizzabile è il controllo del flusso. Questa funzionalità ci consente di massimizzare la velocità effettiva evitando di sovraccaricare il servizio. Il controllo del flusso è un tipo di formato di traffico per cui picchi improvvisi di carico possono essere attenuati nel tempo 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 "eccezionale" significa essere consegnati al cliente, ma non ancora confermati. 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 considerando 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 lo spostamento dei messaggi tra publisher e sottoscrittori.
inoltro Un server nel piano dati.
accesso globale ai dati I client sottoscrittori e publisher Pub/Sub 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 carico maggiore mediante l'aumento del numero di istanze dei componenti del servizio.
messaggio I dati che si spostano 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 server di inoltro e l'insieme di ID dei messaggi confermati da tutte le sottoscrizioni allegate.
servizio di pubblicazione/sottoscrizione (Pub/Sub) Un servizio di messaggistica in cui i mittenti dei messaggi sono 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 server di inoltro 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 in base a una sottoscrizione specificata.
abbonamento Un'entità denominata che rappresenta un interesse a ricevere tutti i messaggi relativi a 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.