
Il existe une architecture éprouvée que j'ai vue à plusieurs reprises pour prendre en charge vos services et applications Web :
- PostgreSQL pour le stockage de données
- Redis pour coordonner les files d'attente de tâches en arrière-plan (et certaines opérations atomiques limitées)
Redis est fantastique, mais et si je vous disais que ses cas d'utilisation les plus courants pour cette pile peuvent en fait être réalisés en utilisant uniquement PostgreSQL ?
Scénario 1 : file d'attente des tâches
L'utilisation la plus courante de Redis que j'ai vue consiste peut-être à coordonner la soumission de travaux de votre service Web au pool de travailleurs en arrière-plan. L'idée est que vous souhaitiez enregistrer le désir de faire une sorte de travail en arrière-plan (peut-être avec une entrée) et vous assurer qu'un seul de vos nombreux travailleurs en arrière-plan l'exécutera. Redis aide à cela car il fournit un riche ensemble d'opérations atomiques pour ses structures de données.
Mais depuis la sortie de la version 9.5, PostgreSQL dispose d'une fonction SKIP
LOCKED pour l'instruction SELECT… FOR… ( documentation ici ). Lorsque cette option est spécifiée, PostgreSQL ignorera simplement toutes les lignes nécessitant une attente de libération du verrou.
Regardons cet exemple du point de vue d'un travailleur d'arrière-plan :
BEGIN;
WITH job AS (
SELECT
id
FROM
jobs
WHERE
status = 'pending'
LIMIT 1
FOR UPDATE SKIP LOCKED
)
UPDATE
jobs
SET
status = 'running'
WHERE
jobs.id = job.id
RETURNING
jobs.*;
COMMIT;
Lorsque FOR UPDATE SKIP LOCKED est spécifié, le verrouillage au niveau de la ligne est implicitement défini sur toutes les lignes renvoyées par SELECT. De plus, puisque vous avez spécifié SKIP LOCKED, cette instruction ne sera pas bloquée pour une autre transaction. S'il y a un autre travail prêt à être traité, il sera retourné. Il n'y a aucun risque que plusieurs processus de travail exécutant cette commande reçoivent la même ligne en raison d'un blocage au niveau de la ligne.
Le plus gros inconvénient de cette méthode est que si vous avez un grand nombre de travailleurs essayant d'exécuter cette file d'attente et qu'un grand nombre de tâches les fournit, ils peuvent passer un certain temps à sauter entre les tâches et à essayer d'acquérir un verrou. En pratique, la plupart des applications sur lesquelles j'ai travaillé ont moins d'une douzaine de travailleurs de fond, et il est peu probable que les coûts soient importants.
Scénario 2 : Blocs d'application
Imaginons que vous ayez une routine de synchronisation avec un service tiers et que vous n'en ayez besoin que d'une seule instance, fonctionnant pour un utilisateur donné dans tous les processus serveur. Une autre application Redis courante que j'ai vue est le verrouillage distribué.
PostgreSQL peut également y parvenir en utilisant des verrous de recommandation (verrous consultatifs). les verrous consultatifs vous permettent d'utiliser le même mécanisme de verrouillage que PostgreSQL utilise en interne, pour vos propres objectifs définis par l'application.
Scénario 3 : Pub/Sub
J'ai laissé l'exemple le plus cool pour la fin : envoyer des événements à vos clients actifs. Par exemple, supposons que vous deviez informer un utilisateur qu'il a un nouveau message disponible pour lecture. Ou peut-être souhaitez-vous transférer des données au client lorsqu'elles seront disponibles. Généralement, les websockets sont la couche de transport pour ces événements, tandis que Redis sert de moteur Pub/Sub.
Cependant, à partir de la version 9, PostgreSQL fournit également cette fonctionnalité avec les opérateurs LISTEN et NOTIFY... Tout client PostgreSQL peut s'abonner (LISTEN) à un canal de message spécifique, qui n'est qu'une chaîne arbitraire. Lorsqu'un autre client envoie un message NOTIFY sur ce canal, tous les autres clients abonnés seront notifiés. En option, vous pouvez joindre un petit message.
Si vous utilisez Rails et ActionCable, l'utilisation de PostgreSQL est même prise en charge par défaut.
Tirer pleinement parti de PostgreSQL
Redis occupe fondamentalement un créneau différent de PostgreSQL et excelle dans ce que PostgreSQL ne cherche pas. Les exemples incluent la mise en cache des données avec TTL et le stockage et le traitement des données éphémères.
Cependant, PostgreSQL a beaucoup plus de puissance que ce à quoi vous pourriez vous attendre lorsque vous l'abordez simplement en termes d'une autre base de données SQL ou d'une entité mystérieuse qui vit derrière votre ORM.
Il y a de fortes chances que les choses pour lesquelles vous utilisez Redis se révèlent également bonnes pour PostgreSQL. Cela pourrait valoir la peine d'abandonner Redis et d'économiser sur les coûts opérationnels et la complexité du développement en s'appuyant sur plusieurs services de données.