Cómo Postgres LISTEN/NOTIFY logran una escalabilidad efectiva en bases de datos

Cómo Postgres LISTEN/NOTIFY logran una escalabilidad efectiva en bases de datos

El uso de la funcionalidad LISTEN/NOTIFY en PostgreSQL ha generado controversia en la comunidad tecnológica, debido a críticas que señalan su escasa capacidad de escalabilidad. Sin embargo, esta herramienta representa una opción poderosa para quienes buscan implementar notificaciones duraderas de baja latencia en sus bases de datos. Recientemente, se han realizado avances significativos que permiten optimizar su rendimiento, desafiando la percepción negativa que rodea a esta funcionalidad.

Streaming de Baja Latencia con LISTEN/NOTIFY

El diseño básico de los flujos respaldados por PostgreSQL es sencillo: se establece una tabla de flujos donde cada fragmento, como podría ser un token de respuesta de un modelo de lenguaje, se registra como una nueva fila. Sin embargo, el desafío radica en la lectura de estos flujos, ya que no se puede predecir cuándo llegará el siguiente fragmento. Una estrategia común es el polling, donde cada lector consulta periódicamente el final del flujo en busca de nuevos datos. No obstante, esta práctica no es eficiente: intervalos de polling demasiado amplios aumentan la latencia, mientras que intervalos demasiado cortos sobrecargan la base de datos.

La solución más eficiente es la funcionalidad LISTEN/NOTIFY, que permite que los lectores se bloqueen en espera de una notificación de un escritor cuando un nuevo fragmento es publicado. Esto evita la sobrecarga que genera el polling y asegura que los lectores se activen en el momento en que llega un nuevo dato.

El Problema de la Exclusividad en El Lock de NOTIFY

La implementación inicial de LISTEN/NOTIFY para estos flujos mostraba un rendimiento adecuado en términos de latencia, pero resultaba limitada, alcanzando solo 2,9K escrituras por segundo. Este rendimiento subóptimo se atribuye a un mutex global que PostgreSQL utiliza durante la ejecución de NOTIFY. Esta exclusividad de acceso es crucial, ya que PostgreSQL necesita garantizar que las notificaciones se envían en el orden correcto de transacciones. Sin embargo, esto resulta en un cuello de botella que impide un mayor rendimiento.

Optimizando LISTEN/NOTIFY

Una manera de afrontar esta limitación es adaptando cómo se gestionan las notificaciones. En varias aplicaciones, las notificaciones actúan como un simple «ping» para que los lectores consulten la tabla de base de datos que contiene la información real. Por lo tanto, no es necesario que estas notificaciones se gestionen de forma estrictamente ordenada o durable. Al implementar un sistema de buffer en memoria, donde las notificaciones se agrupan y luego se envían en transacciones por lotes, se logra disminuir significativamente la contención del lock global.

Esta modificación permite que las escrituras individuales se procesen rápidamente, aprovechando las optimizaciones de PostgreSQL, como el group commit. Este enfoque novedoso ha llevado el rendimiento de las escrituras simultáneas en flujos de hasta 60K operaciones por segundo, multiplicando el rendimiento anterior por veinte, y manteniendo latencias de entre 15 y 100 milisegundos. El uso completo de CPU indica que el sistema ya no está limitado por un problema de contención.

Con estos avances, LISTEN/NOTIFY se presenta como una opción viable y eficiente para el desarrollo de aplicaciones que requieran notificaciones en tiempo real, desafiando así las impresiones previas respecto a su escalabilidad. Los desarrolladores que busquen implementar sistemas de ejecución duraderos y escalables en PostgreSQL ahora cuentan con herramientas y métodos que mejoran drásticamente la eficiencia de sus aplicaciones.