Perché Redis per la coda?
Ho l'impressione che Redis possa diventare un buon candidato per l'implementazione di un sistema di accodamento. Fino a questo punto abbiamo utilizzato il nostro database MySQL con polling o RabbitMQ. Con RabbitMQ abbiamo avuto molti problemi: le librerie client sono molto povere e buggy e vorremmo non investire troppe ore degli sviluppatori per risolverle, alcuni problemi con la console di gestione del server, ecc. E, per il momento essendo almeno, non stiamo afferrando per millisecondi o spingendo seriamente le prestazioni, quindi fino a quando un sistema ha un'architettura che supporta una coda in modo intelligente, probabilmente siamo in buona forma.
Va bene, questo è lo sfondo. Fondamentalmente ho un modello di coda molto classico e semplice: diversi produttori che producono lavoro e molti consumatori consumano lavoro, e sia i produttori che i consumatori devono essere in grado di scalare in modo intelligente. Si scopre che un ingenuo PUBSUB
non funziona, dal momento che non voglio che tutti gli abbonati consumino lavoro, voglio solo che un abbonato riceva il lavoro. A prima vista, mi sembra che BRPOPLPUSH
sia un design intelligente.
Possiamo usare BRPOPLPUSH?
La progettazione di base BRPOPLPUSH
è che hai una coda di lavoro e una coda di avanzamento. Quando un consumatore riceve lavoro, inserisce atomicamente l'elemento nella coda di avanzamento e quando completa il lavoro, lo LREM
è. Questo impedisce il blackholing del lavoro se i clienti muoiono e rende il monitoraggio abbastanza semplice - per esempio possiamo dire se c'è un problema che fa sì che i consumatori impieghino molto tempo a svolgere attività, oltre a dire se c'è un grande volume di attività.
Assicura
- il lavoro viene consegnato esattamente a un consumatore
- il lavoro finisce in una coda di avanzamento, quindi non può blackhole se un consumatore
Gli svantaggi
- Mi sembra piuttosto strano che il miglior design che ho trovato non utilizzi in realtà
PUBSUB
poiché questo sembra essere ciò su cui si concentrano la maggior parte dei post del blog sulla messa in coda su Redis. Quindi sento che mi manca qualcosa di ovvio. L'unico modo in cui vedo di usarePUBSUB
due volte senza consumare compiti è semplicemente di inviare una notifica che il lavoro è arrivato, che i consumatori possono quindi non bloccareRPOPLPUSH
. - È impossibile richiedere più di un elemento di lavoro alla volta, il che sembra essere un problema di prestazioni. Non enorme per la nostra situazione, ma piuttosto dice chiaramente che questa operazione non è stata progettata per un alto rendimento o questa situazione
- In breve: mi sto perdendo qualcosa di stupido?
Aggiungendo anche il tag node.js, perché è la lingua con cui mi occupo principalmente. Node può offrire alcune semplificazioni nell'implementazione, data la sua natura a thread singolo e non bloccante, ma inoltre sto usando la libreria node-redis e le soluzioni dovrebbero o possono essere sensibili anche ai suoi punti di forza e di debolezza.