KamoCRM

Une couche de données distribuée, choisie délibérément

SQL distribué, colonnes larges, cache, stockage d'objets et vecteurs — chacun pour une raison

Cinq magasins de données différents, chacun répondant à une question à laquelle les autres répondent mal : SQL distribué pour les données transactionnelles d'entreprise, colonne large pour la télémétrie à écriture élevée, un magasin en mémoire pour les états éphémères, stockage d'objets pour les fichiers et une base de données vectorielle pour la recherche sémantique.

Chaque chiffre indique d'où il vient et quand il a été mesuré.
MesureValeurSourceMesurées
Magasins de données distincts en production5 (YugabyteDB, ScyllaDB, Redis/Valkey, MinIO, Qdrant)kubectl get statefulsets,deployments --all-namespaces
Topologie SQL distribuéeyb-master and yb-tserver as separate stateful setskubectl get statefulsets -n kamo
Fichiers de migration SQL sous contrôle de version90find . -name '*.sql' across all service repositories
Migrations du moteur de base de données de production achevées1 (CockroachDB to YugabyteDB, live data)service configuration history; port 26257 retired in favour of 5433

Quel bâtiment il nous a appris

La réponse par défaut à la question de savoir où vont les données est le dernier projet utilisé, c’est ainsi qu’une entreprise finit par exécuter des agrégations analytiques sur la base de données qui prend ses commandes de clients, ou par conserver trente gigaoctets de fichiers téléchargés dans des lignes de table. Nous avons choisi chaque magasin en fonction de la charge de travail, et nous avons migré lorsque nous nous sommes trompés — la plateforme fonctionnait auparavant sur un autre moteur SQL distribué et nous l’avons abandonné, ce qui est vraiment difficile à faire avec des données de production et vaut plus d’expérience que n’importe quelle quantité de discussions sur l’architecture.

Le SQL distribué n’est pas un remplacement instantané pour une base de données à nœud unique, et les différences entre les deux sont les plus importantes. Une transaction ne voit qu’un seul instantané pour toute sa durée de vie, même en mode validation en lecture, de sorte que la deuxième lecture d’une ligne dans une transaction n’observe pas une autre transaction en écriture validée entre les deux — le code qui était correct sur un seul nœud est silencieusement erroné ici.

Le stockage d’objets transporte chaque fichier téléchargé, avec une déduplication par contenu, et cela a sa propre leçon : un téléchargement échoué peut laisser une ligne que le système dédupliquera ultérieurement, produisant un fichier que le système croit exister et ne peut pas servir. Nous avons découvert cela en production, et nous le vérifions maintenant dans tous les systèmes que nous construisons qui dédupliquent quelque chose.

Construit avec

  • YugabyteDB
  • ScyllaDB
  • Redis
  • Valkey
  • MinIO
  • Qdrant
  • PostgreSQL wire protocol
  • Hibernate

Ce qui nous qualifie

Data engineering and migrationMoving data between systems without losing any of itCustom web applicationsThe system your business actually runs on, built properlyPlatform and DevOps engineeringKubernetes, pipelines and the deployment safety nobody notices until it is missing

Dites-nous ce que vous essayez de faire

Une courte conversation est généralement suffisante pour savoir si nous sommes les bonnes personnes, si nous ne le sommes pas, nous le dirons et vous indiquerons quelque part mieux.

Commencez une conversationJ'utilise déjà KamoCRMComment nous citons