Progettazione di un'architettura di coda dei messaggi scalabile

22

Recentemente ho iniziato a imparare le sfumature dell'architettura computerizzata scalabile e aziendale e uno dei componenti centrali è una coda di messaggistica. Per imparare di più da qualsiasi paradigma di programmazione, sto cercando di implementare la mia versione di un servizio di coda di messaggistica.

Finora, il mio progetto iniziale viene eseguito su un listener di socket threaded, ma per impedire che lo stesso messaggio venga scaricato due volte da due nodi di elaborazione separati, il registro dell'indice della coda dei messaggi viene bloccato quando viene avviata una lettura e sbloccato dopo il il registro è stato aggiornato. In quanto tale, ciò annulla la necessità che venga eseguito il threading e indica che esiste un limite per le dimensioni di un sistema scalabile basato sulla velocità di elaborazione del server su cui è in esecuzione il servizio della coda di messaggistica.

Il modo per aggirare questo sarebbe eseguire il servizio di accodamento messaggi su più server, ma questo aumenterebbe la probabilità che lo stesso messaggio venga scaricato due volte. L'unico modo per evitare che tali problemi si verifichino è includere un callback di revoca che (dopo che i server, o anche i thread su un singolo server, hanno sincronizzato le loro informazioni e rilevato tale riemissione) avrebbe comandato al nodo di elaborazione di fermarne il funzionamento lavoro corrente, e ri-interrogare la coda dei messaggi per il messaggio successivo, ma di nuovo, ci sarebbe un limite in cui la maggior parte del traffico inviato sarebbe sincronizzazioni e callback di revoca, causando un collo di bottiglia e rallentando l'elaborazione delle informazioni in modo che un molti dei nodi di elaborazione effettuerebbero operazioni nulle e perdite di tempo.

L'ultimo modo in cui posso pensare di aggirare questo problema è che ogni server di messaggi (e ogni thread su ciascun server) abbia uno specifico offset rispetto a dove si trova nella coda, ma potrebbe avere problemi in base al tipo di applicazione, in particolare se è necessario eseguire l'elaborazione in un ordine specifico.

Quindi, tutto ciò che viene detto, ci sono disegni di un'architettura di messaggi in coda che potrebbe mostrarmi come i servizi esistenti di coda di messaggi di livello enterprise evitino questi problemi?

    
posta topherg 17.05.2013 - 03:00
fonte

1 risposta

14

In breve:

Questo è un problema difficile. Non reinventare la ruota.

Esistono molte tecnologie che risolvono il livello di coda dei messaggi. Includono

  • ZeroMQ
  • RabbitMQ
  • Apache Kafka
  • Redis, con BLPOP o PUBSUB (ho chiesto come fare questo qui ).
  • Altre implementazioni AMQP oltre a RabbitMQ

Penso che sia fuori dalla mia portata discutere gli svantaggi di ciascuno, non ultimo perché non sostengo davvero l'esperienza per fare questo bene tosse non usare Rabbit tosse .

Anche se non vuoi utilizzare nessuna di queste tecnologie, leggi le loro documentazioni.

Questo ti istruirà sui modelli di progettazione che sono possibili su un sistema. Leggere la documentazione di ZeroMQ ti istruirà su molte classiche architetture di accodamento messaggi che hanno gentilmente implementato. Anche se non si utilizza ZeroMQ, la conoscenza di questi modelli consente di valutare altre tecnologie di accodamento chiedendo se è possibile implementare tale modello.

Informazioni sul modello di coda di scambio di RabbitMQ / AMQP. Il routing potrebbe venire fuori per voi - questo è supportato da Redis PUBSUB ma non ricordo di essere supportato da ZeroMQ - e il fanouts è qualcosa che il mio negozio ha usato, anche se mal implementato su un sondaggio Memcached (yuck!), Per un bel po 'di tempo .

Come sceglierne uno?

Lavoro in una startup il cui SLA è tipico di un'applicazione web - alcune interruzioni sono accettabili, a condizione che possiamo ripristinare rapidamente il servizio con una perdita di dati ridotta. Non abbiamo dovuto pensare a problemi di ridimensionamento come Twitter o Tumblr, quindi non abbiamo davvero dovuto pensare al volume del throughput. Detto questo, se stai implementando uno SLA simile al mio, ti verranno in mente queste considerazioni:

  • effettivamente le work delle librerie client? È facile mantenere una connessione in loro? (ZeroMQ, Redis: sì. RabbitMQ: no).
  • il monitoraggio e la gestione sono facili da una console del server? (Redis: sì, RabbitMQ: sì, ZeroMQ: non che io ricordi ma non l'abbiamo usato così a lungo)
  • i client supportano le code interne, quindi si verificano perdite di dati minime in interruzioni brevi? (ZeroMQ, Redis: sì. RabbitMQ: no.)

Ovviamente se lavori per, ad esempio, un trading trading ad alta frequenza, queste saranno le tue preoccupazioni minori. Sarai più propenso a mettere il tempo di sviluppo in una libreria lato client in cambio di una maggiore produttività alla fine. Ma sto scrivendo questo per avvisarti che queste tecnologie tendono a commercializzare sulla base delle loro prestazioni, non delle loro funzionalità pronte all'uso. Se sei un web-startup, sei lontano più interessato al secondo rispetto al primo e, di conseguenza, qualcosa come Redis, che è più ottimizzato per la facilità d'uso a buone prestazioni rispetto alla difficoltà di utilizzo a grandi prestazioni, è probabilmente una scelta migliore di RabbitMQ. (Davvero non mi piace RabbitMQ).

    
risposta data 12.07.2013 - 16:37
fonte

Leggi altre domande sui tag