CQRS : séparer les commandes et les requêtes pour de meilleures performances

CQRS : séparer les commandes et les requêtes pour de meilleures performances
Qu’est-ce que la séparation des responsabilités commande-requête (CQRS) ?
La séparation des responsabilités commande-requête (CQRS) est un patron de conception qui sépare les actions qui modifient les données (commandes) de celles qui récupèrent les données (requêtes). Au lieu d’utiliser le même modèle pour les deux, CQRS les divise en deux chemins distincts. En séparant les commandes et les requêtes, les systèmes peuvent gérer chaque tâche plus efficacement, ce qui se traduit par de meilleures performances, un code plus clair et une mise à l’échelle plus facile à mesure que votre application se développe.
Concepts clés de CQRS
Commande
Une commande est une action qui modifie les données dans le système, comme une opération d’écriture dans la base de données. Elle représente une demande d’exécution d’une tâche spécifique, comme créer, mettre à jour ou supprimer quelque chose. Les commandes ne renvoient pas de données ; elles indiquent au système de « faire quelque chose ».
Exemple : lorsque les utilisateurs mettent à jour les informations de leur profil, une commande comme “UpdateUserProfile” est envoyée pour modifier leur nom, leur e-mail ou d’autres détails du système.
Requête
Une requête est une demande de récupération de données sans les modifier, c’est-à-dire l’opération de lecture dans la base de données. Les requêtes sont utilisées pour obtenir des informations, comme rechercher ou afficher des données. Contrairement aux commandes, les requêtes ne font que renvoyer des données et ne modifient rien.
Exemple : lorsqu’un utilisateur souhaite consulter les détails de son profil, une requête comme “GetUserProfile” récupère les informations pertinentes depuis le système.
Comment fonctionne CQRS ?
Une analogie concrète pour comprendre le fonctionnement de CQRS consiste à l’imaginer comme des voies séparées pour les voitures et les camions sur une autoroute. Les camions transportent des charges lourdes (commandes), tandis que les voitures se déplacent rapidement et sans à-coups (requêtes). En les maintenant sur leurs propres voies, la circulation est plus fluide, et les deux tâches sont effectuées plus efficacement.
CQRS fonctionne en séparant clairement le traitement des commandes (modifications de données) et des requêtes (récupération de données). Lorsqu’une commande est émise, comme l’insertion ou la mise à jour de données, elle suit un chemin dédié conçu pour traiter les changements. Le système traite ces commandes avec précision, déclenchant souvent une logique métier ou des événements associés. Les requêtes, en revanche, sont orientées vers un chemin différent, optimisé pour des lectures de données rapides et efficaces.
Il est important de noter que, dans CQRS, séparer les commandes et les requêtes ne signifie pas nécessairement que vous devez utiliser des bases de données différentes pour chacune. L’objectif est de séparer les comportements et les responsabilités, ce qui peut être fait au sein de la même base de données ou sur plusieurs bases de données si nécessaire.
Figure- CQRS High-Level Architecture.png
Figure : architecture de haut niveau de CQRS
Exemple : un système d’inscription d’utilisateurs
Lorsqu’un utilisateur s’inscrit, une commande appelée RegisterUserCommand est déclenchée. Cette commande crée le nouvel utilisateur, valide ses informations et l’ajoute à la base de données. En arrière-plan, un événement comme `UserRegisteredEvent` est stocké afin d’enregistrer ce changement.
Plus tard, lorsqu’une autre partie du système (ou l’utilisateur) doit consulter les détails de l’utilisateur, une requête appelée GetUserProfileQuery est utilisée. La requête récupère les données du profil de l’utilisateur depuis la base de données sans effectuer de modifications.
CQRS et Event Sourcing
Event Sourcing est une technique souvent utilisée avec CQRS. Dans les systèmes traditionnels, lorsque les données changent (par exemple lorsqu’un utilisateur met à jour son profil), nous enregistrons uniquement l’état final des données. Par exemple, si un utilisateur modifie son adresse e-mail, nous ne stockons que le nouvel e-mail dans la base de données, et l’ancien e-mail est perdu.
Avec Event Sourcing, au lieu d’enregistrer uniquement l’état final, nous stockons chaque changement comme un événement distinct. Ainsi, dans le cas d’une mise à jour de profil utilisateur, nous stockons des événements comme « Utilisateur créé », « E-mail mis à jour » ou « Photo de profil modifiée ». Chaque événement enregistre ce qui s’est passé et quand. Ces événements sont enregistrés dans une séquence, presque comme un journal historique de tout ce qui se passe dans le système.
Ces événements deviennent la source de vérité du système. Lorsqu’une commande est exécutée (par exemple, la mise à jour du profil de l’utilisateur), un nouvel événement est créé et ajouté à cette liste d’événements. Au fil du temps, tous ces événements s’accumulent pour représenter l’historique complet des changements.
Lorsque vous devez interroger ou consulter l’état actuel du système (comme récupérer le profil de l’utilisateur), le système peut rejouer ces événements dans le bon ordre afin de reconstruire l’état actuel. Par exemple, il pourrait rejouer les événements "Utilisateur créé" et "Email mis à jour" pour afficher l’email actuel et les détails du profil.
Différence entre CQRS et CQS
Bien que CQRS (Command Query Responsibility Segregation) et CQS (Command Query Separation) soient tous deux des principes de conception qui mettent l’accent sur la distinction entre commandes et requêtes, ils diffèrent légèrement sur certains aspects.
| Aspect | CQS (Command Query Separation) | CQRS (Command Query Responsibility Segregation) |
|---|---|---|
| Définition | Les méthodes sont soit des commandes (modifient les données), soit des requêtes (récupèrent des données). | Le système sépare les commandes et les requêtes en modèles ou chemins distincts. |
| Complexité | Principe simple appliqué au sein des méthodes. | Plus complexe, et implique des modèles ou des couches séparés pour les commandes et les requêtes. |
| Cas d’utilisation | Adapté aux systèmes plus simples où les commandes et les requêtes sont gérées au sein de la même structure. | Idéal pour les systèmes vastes et complexes où les lectures et les écritures peuvent être optimisées séparément. |
| Gestion des données | Le même modèle de données est utilisé à la fois pour les commandes et les requêtes. | Les commandes et les requêtes peuvent utiliser des modèles de données différents, voire des bases de données différentes. |
| Objectif | Principalement axé sur le fait que les méthodes ont une responsabilité unique. | Se concentre sur la scalabilité, les performances et la séparation des responsabilités à travers le système. |
| Scalabilité | Impact moindre sur la scalabilité du système, car les deux sont gérés dans un seul modèle. | Forte scalabilité, car les commandes et les requêtes sont gérées indépendamment. |
| Flexibilité | Flexibilité limitée, car les deux opérations sont liées dans une seule structure. | Plus grande flexibilité ; vous pouvez utiliser différentes bases de données ou différents mécanismes de stockage pour les commandes et les requêtes. |
| Event Sourcing | Généralement non utilisé. | Souvent utilisé avec l’event sourcing pour suivre tous les changements au fil du temps. |
Tableau : différence entre CQS et CQRS
Cas d’utilisation de CQRS
Voici quelques scénarios courants où CQRS est utile :
Charges de lecture/écriture élevées
Dans les scénarios où il existe un déséquilibre important entre le nombre d’opérations de lecture et d’écriture, CQRS est idéal. Par exemple, une plateforme d’e-commerce peut avoir un grand nombre d’utilisateurs qui consultent les informations sur les produits (lectures), mais moins d’utilisateurs qui mettent à jour leur panier ou effectuent des achats (écritures). CQRS permet au système de faire évoluer le côté requêtes indépendamment afin de gérer le volume élevé de demandes de lecture sans affecter les opérations d’écriture.
Logique métier complexe
Lors de la gestion de règles métier complexes qui s’appliquent uniquement aux modifications de données (commandes), CQRS aide en isolant cette complexité. Par exemple, le côté commande peut appliquer des règles strictes de validation et de traitement dans un système financier où les transactions sont fortement réglementées. En revanche, le côté requête reste simple et axé sur la récupération des soldes de comptes ou des historiques de transactions.
Event Sourcing et pistes d’audit
Dans les systèmes où il est nécessaire de conserver une piste d’audit complète de chaque changement, CQRS s’associe bien avec l’event sourcing. Par exemple, dans une application de santé, chaque modification du dossier médical d’un patient peut être stockée comme un événement, ce qui permet au système de suivre facilement qui a effectué les changements et quand, tandis que les requêtes peuvent accéder rapidement à l’état actuel du dossier.
Analytique en temps réel
Pour les applications nécessitant une analytique en temps réel, comme les plateformes de médias sociaux, CQRS peut gérer les mises à jour constantes des données utilisateur (par exemple, les mentions J’aime, les partages) tout en traitant les requêtes pour obtenir des informations en temps réel (par exemple, les sujets tendance). Le côté requête peut être optimisé pour la rapidité sans être affecté par les mises à jour en cours du côté commande.
Architectures de microservices
Dans les systèmes basés sur des microservices, CQRS fournit différents services pour gérer les commandes et les requêtes indépendamment. Par exemple, dans une entreprise de logistique, un service peut gérer le traitement des commandes (commandes), tandis qu’un autre s’occupe du suivi et des rapports (requêtes), améliorant ainsi la flexibilité et la maintenabilité du système.
Outils et frameworks prenant en charge CQRS
Plusieurs outils et frameworks facilitent la mise en œuvre de CQRS. Voici un bref aperçu de quelques options populaires :
Axon Framework (Java) est un framework complet qui prend en charge CQRS et l’event sourcing. Il fournit des composants intégrés pour gérer les commandes, les requêtes et les événements, ce qui en fait un choix populaire pour les applications Java complexes.
MediatR est une autre bibliothèque légère pour les applications .NET qui simplifie la séparation des commandes et des requêtes. Elle aide à acheminer les demandes de manière propre et organisée, ce qui est parfait pour CQRS dans les systèmes de petite à moyenne taille.
Laravel Command Bus fait partie du framework Laravel. Les développeurs utilisent cet outil pour définir séparément les commandes et les requêtes. C’est une excellente option pour les applications basées sur PHP qui cherchent à mettre en œuvre CQRS.
EventStore est une base de données spécialisée conçue pour l’event sourcing, souvent associée à CQRS. Elle stocke des événements plutôt que simplement des données, permettant de rejouer facilement des événements passés afin de reconstruire l’état du système.
NServiceBus est un framework de messagerie qui fonctionne bien avec CQRS en gérant les commandes, les événements et les messages dans des systèmes distribués. Il est idéal pour les architectures de microservices qui utilisent CQRS.
Avantages de CQRS
Amélioration de l’évolutivité et des performances
En séparant les commandes et les requêtes, CQRS peut faire évoluer chaque partie indépendamment. Par exemple, si votre application gère beaucoup plus d’opérations de lecture (requêtes) que d’opérations d’écriture (commandes), vous pouvez faire évoluer le côté requête sans affecter le côté commande, améliorant ainsi les performances globales.
Organisation du code plus claire
CQRS favorise une séparation nette des responsabilités. Les commandes s’occupent d’apporter des changements, et les requêtes gèrent la récupération des données. Cela rend le code plus facile à comprendre et à maintenir, car chaque partie du système a une responsabilité claire.
Meilleure gestion des règles métier complexes
Avec CQRS, les règles métier complexes liées à la mise à jour des données peuvent être gérées du côté commande, tandis que des requêtes plus simples et efficaces peuvent être utilisées pour lire les données. Cette division aide à gérer une logique complexe sans surcharger le système ni rendre le code trop compliqué.
Flexibilité dans le choix des bases de données pour la lecture par rapport à l’écriture des données
CQRS vous offre la possibilité d’utiliser différentes bases de données pour les commandes et les requêtes. Par exemple, vous pourriez utiliser une base de données NoSQL hautement optimisée pour des lectures rapides (requêtes) et une base de données relationnelle lors des écritures (commandes). Cette flexibilité vous permet de choisir les meilleurs outils pour chaque tâche.
Défis et considérations liés à CQRS
Complexité accrue
Avec CQRS, vous devez gérer deux modèles distincts : l’un pour traiter les commandes (écritures) et l’autre pour traiter les requêtes (lectures). Cela ajoute de la complexité à la base de code, car vous devez maintenir et mettre à jour les deux modèles, ce qui augmente l’effort nécessaire pour développer et maintenir le système.
Défis de synchronisation
Maintenir la synchronisation entre les côtés commande et requête peut être délicat. Lorsque des données sont écrites via une commande, il peut s’écouler un certain temps avant que les changements ne soient reflétés côté requête, ce qui entraîne des retards potentiels. La gestion de cette synchronisation est importante pour garantir l’exactitude des données dans l’ensemble du système.
Décider quand CQRS est excessif
CQRS n’est pas nécessaire pour les applications CRUD (Create, Read, Update, Delete) simples. Dans les systèmes dont les exigences en matière de données sont simples, la complexité supplémentaire de CQRS peut ne pas en valoir la peine. CQRS convient mieux aux systèmes complexes avec un volume élevé de lectures et d’écritures ou une logique métier complexe.
Coût
La mise en œuvre de CQRS nécessite souvent une infrastructure supplémentaire, comme la maintenance de bases de données distinctes pour les commandes et les requêtes. Cela peut augmenter les coûts matériels et de services cloud, en particulier lors de la mise à l’échelle des deux côtés. Le besoin de plusieurs technologies pour gérer ces tâches peut faire grimper les dépenses.
Comment CQRS joue un rôle dans les bases de données vectorielles et le Big Data
Dans les bases de données vectorielles comme Milvus, CQRS offre une manière structurée de gérer différents types d’opérations :
Commandes : elles impliquent des tâches comme l’insertion ou la mise à jour de grands volumes de vecteurs (par exemple, des vector embeddings générés par des modèles d’apprentissage automatique). Dans Milvus, les commandes mettraient à jour l’état de la base de données.
Requêtes : ces opérations récupèrent des vecteurs, comme la recherche d’éléments similaires dans un grand jeu de données à l’aide de la recherche de similarité. Les requêtes Milvus peuvent renvoyer des vecteurs de haute dimension qui correspondent à des critères spécifiques, et elles sont souvent utilisées dans l’analyse en temps réel ou dans des applications d’IA comme les systèmes de recommandation et la génération augmentée par récupération (RAG).
Exemple : gérer les requêtes d’analyse en temps réel par rapport à l’insertion/la mise à jour de vecteurs
Supposons que vous exécutiez un système de recommandation alimenté par l’IA sur Zilliz Cloud (la version managée de Milvus). Lorsque de nouvelles données utilisateur ou de nouveaux vecteurs de produits sont générés, le système émet des commandes pour mettre à jour la base de données vectorielle avec de nouveaux embeddings. Ces commandes garantissent que les derniers vecteurs sont insérés ou mis à jour dans Milvus.
Dans le même temps, des analyses en temps réel sont effectuées à l’aide de requêtes pour récupérer les vecteurs les plus similaires pour les recommandations. Le côté requête est optimisé pour trouver rapidement les données pertinentes sans être impacté par les insertions constantes de vecteurs côté commande.
Conclusion
CQRS fournit un moyen puissant de gérer les systèmes complexes en séparant les commandes (changements de données) et les requêtes (récupération de données). Cette séparation améliore l’évolutivité, les performances et la clarté du code, en particulier dans les applications à grande échelle avec une logique métier complexe. Bien que CQRS ajoute une certaine complexité, il offre des avantages significatifs lorsqu’il est utilisé dans les bons scénarios, comme les systèmes gérant l’analyse en temps réel, des charges de lecture/écriture élevées ou l’event sourcing. Cependant, pour les applications plus simples, la complexité supplémentaire peut ne pas être nécessaire. En conclusion, CQRS est un outil précieux pour améliorer l’efficacité et la flexibilité des systèmes lorsqu’il est appliqué de manière appropriée.
FAQ de CQRS
- Quel est le principal avantage de l’utilisation de CQRS ?
CQRS sépare les responsabilités de mise à jour des données (commandes) et de récupération des données (requêtes), ce qui améliore l’évolutivité, les performances et la clarté du code du système. Chaque côté peut être optimisé indépendamment, ce qui le rend utile pour les systèmes à fort volume ou complexes.
- Quand dois-je éviter d’utiliser CQRS ?
CQRS peut ajouter une complexité inutile pour les applications CRUD simples où il n’est pas nécessaire de traiter distinctement les lectures et les écritures. Si votre application n’a pas d’exigences de performance importantes ni de logique métier complexe, CQRS peut être excessif.
- Dois-je utiliser des bases de données séparées pour les commandes et les requêtes dans CQRS ?
Non, l’utilisation de bases de données séparées pour les commandes et les requêtes n’est pas obligatoire. Bien que vous puissiez utiliser différentes bases de données pour CQRS, l’essentiel est de séparer le comportement et la responsabilité dans le code. Vous pouvez toujours utiliser une seule base de données si cela convient aux besoins de votre application.
- Comment CQRS fonctionne-t-il avec l’event sourcing ?
Dans l’event sourcing, chaque modification du système est stockée sous forme d’événement. CQRS complète cela en traitant les commandes qui génèrent des événements et en utilisant des requêtes pour reconstruire l’état du système en rejouant ces événements. Ainsi, un historique complet des modifications est conservé, ce qui facilite l’audit ou le débogage.
- CQRS peut-il améliorer les performances des applications d’analyse en temps réel ?
Oui, CQRS est utile pour l’analyse en temps réel. Il permet au système de traiter les mises à jour continues (commandes) séparément des requêtes de données en temps réel, en optimisant chacune selon son objectif et en empêchant l’une de ralentir l’autre.
- Quels sont les défis liés à la mise en œuvre de CQRS ?
Les principaux défis incluent une complexité accrue, la gestion de la synchronisation entre les modèles de commande et de requête, la gestion des problèmes de cohérence éventuelle, ainsi que des coûts d’infrastructure potentiellement plus élevés en raison du maintien de chemins ou de bases de données séparés.
Ressources connexes
Que sont les bases de données vectorielles et comment fonctionnent-elles ?
Bases de données relationnelles vs bases de données vectorielles
Exploiter les bases de données vectorielles pour une personnalisation e-commerce de niveau supérieur
Le guide 2024 : principaux cas d’utilisation de la recherche vectorielle
- Qu’est-ce que la séparation des responsabilités commande-requête (CQRS) ?
- Concepts clés de CQRS
- Comment fonctionne CQRS ?
- CQRS et Event Sourcing
- Différence entre CQRS et CQS
- Cas d’utilisation de CQRS
- Outils et frameworks prenant en charge CQRS
- Avantages de CQRS
- Défis et considérations liés à CQRS
- Comment CQRS joue un rôle dans les bases de données vectorielles et le Big Data
- Conclusion
- FAQ de CQRS
- Ressources connexes
Contenu
Commencez gratuitement, évoluez facilement
Essayez la base de données vectorielle entièrement managée conçue pour vos applications GenAI.
Essayer Zilliz Cloud gratuitement

