- Se eliminó RabbitMQ y se reemplazó por una cola en PostgresDB usando SQL
- El cambio tomó alrededor de medio día y el código fuente se redujo en 580 líneas
- Mucho más importante aún, la estabilidad y la resiliencia mejoraron de forma considerable
- No se trata de hablar de problemas de sistemas de colas como RabbitMQ, sino de un esfuerzo por mantener las cosas simples
- Prequel, que escribió este artículo, es un producto que ayuda a empresas B2B SaaS a sincronizar con las bases de datos de sus clientes mediante pipelines de datos a gran escala
- Estaba compuesto por RabbitMQ + AQMP + Helm + un wrapper en GoLang; funcionó bien por un tiempo, pero empezaron a aparecer problemas
- La entrega de mensajes se retrasaba demasiado y eso provocaba que los mensajes se cancelaran
- Mientras el consumer hacía prefetch de mensajes, se daba la situación de que retenía el siguiente mensaje hasta completar el actual
- Si este prefetch se ponía en 0, pasaba a ser infinito, por lo que no era posible desactivar el prefetch
- El problema surgía porque las tareas que recibían y procesaban mensajes normalmente eran trabajos de larga duración (transferencia de datos)
- Entendieron exactamente qué estaba pasando, pero no había una forma de corregirlo de inmediato. Como el problema afectaba a clientes en producción, no era posible esperar
- Así que hicieron que funcionara en Postgres usando una sola tabla simple para leer y escribir
- Usando Row-Level Lock de lectura/escritura, garantizan que solo un consumer lea el trabajo
- Es absurdamente simple, pero está funcionando a la perfección
- Ventaja adicional: el estado de la aplicación ya no está dividido entre RabbitMQ y Postgres, sino integrado en un solo lugar
6 comentarios
Yo también implementé directamente una cola en mysql con
row level lock, y ha estado funcionando bien en producción durante años.Lo que quería era, simplemente, ofrecer una funcionalidad similar a una cola para varios workers, pudiendo además guardar junto con el payload los estados dentro de la cola: en espera / en progreso / fallido (si se completa, se elimina).
Viendo en el texto que hicieron el cambio de rabbitmq a la base de datos en poco tiempo, me da la impresión de que simplemente no necesitaban la versatilidad general, ni las múltiples funciones y opciones de configuración que ofrece un servicio de colas especializado aparte.
Parece que surgieron problemas por el desfase entre el envío manual del ACK y la transacción de la base de datos,
y es curioso que lo resolvieran no con ingeniería sino quitando RabbitMQ.
RabbitMQ no tendría la culpa...
https://news.ycombinator.com/item?id=35526846
Hay muchas opiniones en los comentarios.
Parece que también existe algo como esto, que funciona de forma similar: https://github.com/pjongy/jasyncq
Parece que podría existir la posibilidad de que se haga
selectal mismo tiempo; me da curiosidad cómo resolvieron eso.Parece que dice
row level lock.