Présentation de LISTEN/NOTIFY
Postgres LISTEN/NOTIFY est un outil puissant pour les notifications à faible latence et la mise en cache durable. Cependant, il a une réputation de ne pas être scalable en raison de son utilisation d'un verrou global. Dans cet article, nous allons montrer comment nous avons optimisé LISTEN/NOTIFY pour atteindre 60 000 écritures par seconde sur un seul serveur Postgres avec une latence à l'échelle des millisecondes.
Fonctionnement de LISTEN/NOTIFY
Le fonctionnement de base de Postgres-backed streams est simple : créer une table de flux où chaque chunk de flux (par exemple, un jeton de réponse LLM) est une nouvelle ligne, puis écrire dans les flux en insérant dans la table. La partie difficile est la lecture du flux car vous ne savez pas quand le prochain chunk arrivera. Une solution est le polling : avoir chaque lecteur interroger la fin du flux pour de nouveaux chunks. Cependant, le polling ne s'échelonne pas bien.
Optimisation de LISTEN/NOTIFY
Pour rendre LISTEN/NOTIFY-backed streams plus rapides, nous devons contourner ce goulet d'étranglement. L'observation clé est que pour les flux, et pour de nombreuses applications de LISTEN/NOTIFY, les notifications ne sont pas une source de vérité. Au lieu de cela, elles ne font que pinguer un lecteur pour vérifier une table de base de données (la véritable source de vérité) pour de nouvelles données. Par conséquent, les notifications n'ont pas besoin d'être globalement ordonnées ou parfaitement durables, nous pouvons donc optimiser NOTIFY en mettant en tampon les notifications en mémoire et en les vidant périodiquement dans une transaction par lots, réduisant ainsi considérablement les conflits sur le verrou global.
Résultats des tests
En testant cette solution optimisée, nous constatons une amélioration massive des performances : en présence de lecteurs concurrents, nous pouvons effectuer jusqu'à 60 000 écritures de flux par seconde (20 fois plus qu'auparavant) tout en obtenant une latence de 15-100 ms. À la charge maximale, le processeur Postgres est fully utilisé, montrant que la base de données est réellement saturée au lieu d'être bloquée par les conflits.
github.com/dbos-inc/dbos-postgres-benchmark