Come implementare una coda di messaggi su Redis?

29

Perché risuonare per l'accodamento?

Ho l'impressione che Redis possa essere un buon candidato per l'implementazione di un sistema di accodamento. Fino a questo punto abbiamo utilizzato il nostro database MySQL con il polling o RabbitMQ. Con RabbitMQ abbiamo avuto molti problemi: le librerie client sono molto scarse e buggy e vorremmo non investire troppe ore di sviluppo per risolverle, alcuni problemi con la console di gestione del server, ecc. E, per il momento Almeno, non stiamo afferrando per millisecondi o seriamente spingendo le prestazioni, quindi finché un sistema ha un'architettura che supporta una coda in modo intelligente, probabilmente siamo in buona forma.

Va bene, quindi quello è lo sfondo. In sostanza, ho un modello di coda molto classico e semplice: diversi produttori che producono lavoro e diversi consumatori che consumano lavoro, e sia i produttori che i consumatori devono essere in grado di scalare in modo intelligente. Si scopre che un% ingenuo% co_de non funziona, dal momento che non voglio che gli abbonati tutti consumino lavoro, voglio solo un sottoscrittore uno per ricevere il lavoro. Al primo passaggio, mi sembra che PUBSUB sia un design intelligente.

Possiamo usare BRPOPLPUSH?

Il design di base con BRPOPLPUSH è che hai una coda di lavoro e una coda di progresso. Quando un consumatore riceve un lavoro, spinge atomicamente l'articolo nella coda di avanzamento e quando completa il lavoro, BRPOPLPUSH lo fa. Questo impedisce il blackholing del lavoro se i clienti muoiono e rende il monitoraggio abbastanza semplice: ad esempio, possiamo dire se c'è un problema che porta i consumatori a richiedere molto tempo per eseguire attività, oltre a dire se c'è un grande volume di attività.

Assicura

  • il lavoro viene consegnato esattamente a un consumatore
  • Il lavoro di
  • si conclude in una coda di progresso, quindi non può creare un buco nero se un consumatore

Gli svantaggi

  • Mi sembra piuttosto strano che il miglior design che ho trovato non utilizzi effettivamente LREM poiché questo sembra essere quello su cui si concentrano la maggior parte dei post del blog sulla messa in coda su Redis. Quindi mi sento come se mi mancasse qualcosa di ovvio. L'unico modo in cui vedo utilizzare PUBSUB senza utilizzare le attività due volte è semplicemente di inviare una notifica che il lavoro è arrivato, che i consumatori possono quindi non-blocking-ly PUBSUB .
  • È impossibile richiedere più di un elemento di lavoro alla volta, il che sembra essere un problema di prestazioni. Non è un grosso problema per la nostra situazione, ma è piuttosto ovvio che questa operazione non è stata progettata per un throughput elevato o questa situazione
  • In breve: mi manca qualcosa di stupido?

Aggiungendo anche il tag node.js, perché questa è la lingua con cui principalmente mi occupo. Il nodo può offrire alcune semplificazioni nell'implementazione, data la sua natura single-threaded e nonblocking, ma inoltre sto usando la libreria redis del nodo e le soluzioni dovrebbero o possono essere sensibili ai suoi punti di forza e di debolezza.

    
posta djechlin 12.07.2013 - 16:29
fonte

3 risposte

5

Se vuoi utilizzare Redis per una coda di messaggi in Node.js e non ti dispiace usare un modulo per questo allora puoi provare RSMQ - Redis Simple Message Queue for Node. Non era disponibile al momento della domanda, ma oggi è un'opzione valida.

Se vuoi veramente implementare la coda tu stesso come hai detto nella tua domanda, allora potresti voler leggere la fonte di RSMQ perché sono solo 20 schermate di codice che fa esattamente quello che stai chiedendo .

See:

risposta data 09.01.2017 - 15:22
fonte
22

Ho incontrato alcune difficoltà finora mi piacerebbe documentare qui.

Come gestisci la logica di riconnessione?

Questo è un problema difficile e un problema particolarmente difficile nella progettazione e nell'implementazione di una coda di messaggi. I messaggi devono essere in grado di accodarsi da qualche parte quando i consumatori sono offline, quindi un pub-sub semplice non è abbastanza strong ei consumatori devono riconnettersi in uno stato di ascolto. I pop di blocco sono difficili da mantenere perché sono uno stato di ascolto non identrio . L'ascolto dovrebbe essere un'operazione idempotenziale, tuttavia quando si ha a che fare con una disconnessione rispetto a un pop di blocco, si ha il piacere di pensare molto seriamente se la disconnessione sia avvenuta subito dopo l'operazione o prima che l'operazione fallisse. Questo non è insormontabile, ma è indesiderabile.

Inoltre, l'operazione di ascolto dovrebbe essere il più semplice possibile. Idealmente dovrebbe avere queste proprietà:

  • L'ascolto è idempotente.
  • Il consumatore è sempre in ascolto e la logica di limitazione viene elaborata al di fuori del codice di logica di ascolto. RabbitMQ lo incapsula lasciando che il consumatore limiti il numero di messaggi non compressi che può avere.
    In particolare, sono andato con un design povero in cui rientrare in un pop di blocco era subordinato al successo delle operazioni precedenti, che era fragile e richiedeva molto il pensiero.

Ora sto favorendo una soluzione Redis PUBSUB + RPOPLPUSH. Questo disaccoppia la notifica del lavoro dal consumo di lavoro, che ci consente di individuare una soluzione di ascolto pulita. Il PUBSUB è responsabile solo per la notifica del lavoro. La natura atomica di RPOPLPUSH è responsabile del consumo e delega il lavoro a un solo consumatore. All'inizio questa soluzione sembrava inutilmente complicata rispetto a un pop di blocco, ma ora vedo che la complicazione non era affatto inutile; stava risolvendo un problema difficile.

Tuttavia questa soluzione non è affatto banale:

  • i consumatori dovrebbero anche verificare il lavoro su riconnettersi.
  • i consumatori potrebbero voler fare un sondaggio per nuovi lavori comunque, per ridondanza. Se il sondaggio ha effettivamente successo, dovrebbe essere emesso un avviso, poiché ciò dovrebbe avvenire solo tra il consumo sul PUBSUB e il sondaggio su un RPOPLPUSH. Pertanto molti successi di sondaggi indicano un sistema di abbonamento guasto.

Si noti che la progettazione di PUBSUB / RPOPLPUSH presenta anche problemi di ridimensionamento. Ogni consumatore riceve una notifica leggera di ogni messaggio, il che significa che questo ha un collo di bottiglia inutile. Sospetto che sia possibile utilizzare i canali per suddividere il lavoro, ma questo è probabilmente un progetto complicato per funzionare bene.

    
risposta data 15.07.2013 - 18:02
fonte
0

Quindi il motivo principale per cui scegliere di usare RabbitMQ su Redis sono gli scenari di errore e il clustering.

Questo articolo lo spiega davvero meglio, quindi ti fornirò il link:

link

Redis sentinel e più recentemente il cluster redis non sono in grado di gestire un numero di scenari di errore molto semplici che ne hanno fatto una scelta sbagliata per una coda.

RabbitMQ ha il suo insieme di problemi, tuttavia si dice che sia incredibilmente solido nella produzione ed è una buona coda di messaggi.

Ecco il post per coniglio:

link

Quando guardi al teorema CAP (consistenza, disponibilità e gestione delle partizioni) puoi scegliere solo 2 di 3. Stiamo sfruttando RMQ per il CP (coerenza e gestione delle partizioni) con il nostro carico di messaggi, se non siamo disponibili, non è la fine del mondo. Per non perdere i messaggi, utilizziamo ignora la gestione delle partizioni per non perdere i messaggi. I duplicati possono essere gestiti poiché l'origine gestisce l'UUID.

    
risposta data 14.06.2016 - 04:31
fonte

Leggi altre domande sui tag