How Coralogix cut processing times from 30 seconds to 86 milliseconds with a PostgreSQL to ScyllaDB migration. La vitesse est importante pour Coralogix utilise un pipeline d'analyse de streaming en temps réel, offrant des capacités de surveillance, de visualisation et d'alerte sans nécessiter d'indexation. Coralogie L'un des principaux différentiateurs de Coralogix est un moteur de requête distribué pour des requêtes rapides sur les données cartographiées provenant des archives d'un client dans un stockage distant. format. Il a été initialement conçu comme un moteur de requête sans état au-dessus du stockage d'objet sous-jacent, mais la lecture des métadonnées Parquet lors de l'exécution de la requête a introduit un succès de latence inacceptable. parquet Ainsi, l’équipe a essayé une nouvelle mise en œuvre – cette fois, avec ScyllaDB au lieu de PostgreSQL. Spoiler: Cela a fonctionné. Ils ont obtenu des gains de performance impressionnants – réduisant le temps de traitement des requêtes de 30 secondes à 86 millisecondes. Et leurs ingénieurs Dan Harris (Ingénieur Logiciel Principal) et Sebastian Vercruysse (Ingénieur Logiciel Senior) ont pris la scène au Sommet ScyllaDB pour expliquer comment ils l’ont fait. Rejoignez-nous au ScyllaDB Summit 24 pour en savoir plus sur la façon dont les équipes font face à leurs défis de base de données les plus difficiles. Disney, Discord, Expedia, Supercell, Paramount et bien d'autres sont à l'ordre du jour. ScyllaDB Summit 2024 est maintenant un enveloppe! Update: Metastore Motivation et exigences Avant d’entrer dans les détails de la mise en œuvre des métastores, prenons un pas en arrière et examinons d’abord le raisonnement de la construction d’une métastore. "Nous avons initialement conçu cette plate-forme comme un moteur de requête sans état sur le stockage d'objet sous-jacent, mais nous avons rapidement réalisé que le coût de la lecture des métadonnées Parquet lors de l'exécution de la requête représente un grand pourcentage du temps de la requête", explique Dan Harris. Ils ont envisagé une solution qui : Stocker les métadonnées de Parquet dans un format décomposé pour une grande évolutivité et un débit élevé Utilisez des filtres bloom pour identifier efficacement les fichiers à numériser pour chaque requête Utiliser les journaux de commissions transactionnelles pour ajouter, mettre à jour et remplacer les données existantes dans le stockage d'objet sous-jacent Les exigences clés incluaient une faible latence, une évolutivité en termes de capacité de lecture/écriture et une évolutivité du stockage sous-jacent. Génère 2 000 fichiers Parquet par heure (50 000 par jour), pour un total de 15 TB par jour, ce qui se traduit par 20 GB de métadonnées Parquet seulement . a single customer Pour une seule journée Un seul client Pour une seule journée La mise en œuvre initiale de PostgreSQL "Nous avons commencé la mise en œuvre initiale sur Postgres, comprenant à l'époque qu'un moteur non distribué ne suffirait pas à long terme", a reconnu Dan. Cette mise en œuvre originale stockait des informations clés telles que "blocs", représentant un groupe de lignes et un fichier Parquet. Block url: s3://cgx-production-c4c-archive-data/cx/parquet/v1/team_id=555585/… …dt=2022-12-02/hr=10/0246f9e9-f0da-4723-9b64-a12346095d25.parquet Row group: 0, 1, 2 … Min timestamp Max timestamp Number of rows Total size … Pour optimiser la lecture, ils ont utilisé des filtres de fleur pour une découpe de données efficace. Dan a détaillé, « En fin de compte, nous voulons soutenir quelque chose comme une recherche de texte complet. En principe, lorsque nous ingérons ces fichiers dans notre système, nous pouvons construire un filtre de fleur pour tous les jetons distincts que nous trouvons dans le fichier. Ensuite, sur la base d'une requête particulière, nous pouvons utiliser ces filtres de fleur pour découper les données que nous avons besoin de numériser. » Ils ont stocké les filtres de fleur dans une configuration de blocs-split, les brisant en blocs de 32 octets pour une récupération efficace. Ils sont stockés de manière indépendante afin que le système n'ait pas à lire l'ensemble En outre, ils ont stocké des métadonnées de colonne pour chaque fichier Parquet. Block URL Row Group Column Name Column metadata (blob) Dan a expliqué : « Les fichiers que nous écrivons sont assez larges, parfois jusqu'à 20 000 colonnes. Donc, en lisant seulement les métadonnées dont nous avons besoin, nous pouvons vraiment réduire la quantité d'IO requise sur une requête donnée. » Implémentation de ScyllaDB Ensuite, regardons la mise en œuvre de ScyllaDB telle que décrite par le coéquipier de Dan, Sebastian Vercruysse. Modélisation de blocs de données La modélisation de bloc a dû être révisée pour la nouvelle mise en œuvre. Voici un exemple d'URL de bloc: s3://cgx-production-c4c-archive-data/cx/parquet/v1/team_id=555585/… …dt=2022-12-02/hr=10/0246f9e9-f0da-4723-9b64-a12346095d25.parquet La partie audacieuse est la boîte de haut niveau du client; à l'intérieur de la boîte, les articles sont divisés par heure. Mais certains clients ont beaucoup plus de fichiers Parquet que d'autres clients, et ils voulaient garder les choses équilibrées Cela identifie uniquement un bloc donné, mais il serait difficile de répertorier tous les blocs pour un jour donné parce que le timestamp n'est pas dans la clé ((Table url, heure))? Cela fonctionne parce que si vous avez 24 heures pour demander, vous pouvez demander assez facilement ((Table url, heure), bloc url, groupe de rang)? C'est ce qu'ils ont sélectionné.En ajoutant le bloc url et le groupe de rang comme clusters, ils peuvent facilement récupérer un bloc spécifique dans une heure, ce qui simplifie également le processus de mise à jour ou de suppression des blocs et des groupes de rang. Bloom Filter Chunking et modélisation des données Le prochain défi: comment vérifier que certains bits sont configurés, étant donné que ScyllaDB n’offre pas de fonctionnalités hors de la boîte pour cela. L’équipe a décidé de lire les filtres de floraison et de les traiter dans l’application. Cependant, rappelez-vous qu’ils traitent jusqu’à 50 000 blocs par jour par client, chaque bloc contenant 262 KB pour la partie du filtre de floraison. C’est un total de 12 GB – trop pour revenir dans l’application pour une requête. Mais ils n’avaient pas besoin de lire le filtre de floraison entier à chaque fois; ils n’en avaient besoin que des parties, en fonction des jetons impliqués lors de l’exécution de la requête. Pour les modèles de données, une option était d'utiliser en tant que clé primaire. Cela générerait 8192 morceaux de 32 bytes par filtre de floraison, ce qui entraînerait une distribution uniforme d'environ 262 KB par partition. Avec chaque filtre de floraison dans la même partition, il serait facile d'insérer et de supprimer des données avec une seule requête de lot. Mais il y a une prise qui affecte l'efficacité de lecture: vous devriez connaître l'ID du bloc avant de pouvoir lire le filtre de floraison. En outre, l'approche impliquerait l'accès à un nombre considérable de partitions; les blocs 50K signifient des partitions 50K. Et comme Sebastian a noté, "Même avec quelque chose de rapide comme ScyllaDB, il est toujours difficile d'atteindre le processus de sous ((block_url, row_group), index de chunk) Une autre option (celle sur laquelle ils ont finalement décidé): Notez que c'est la même clé de partition que la clé de blocs, avec un index ajouté à la clé de partition qui représente le nth token requis par le moteur de requête.Avec cette approche, la numérisation de 5 tokens couvrant une fenêtre de 24 heures donne lieu à 120 partitions - une amélioration impressionnante par rapport à l'option précédente de modélisation des données. (URL de table, heure, index de pièce), URL de bloc, groupe de lignes) En outre, cette approche n’exige plus l’ID de bloc avant de lire le filtre de floraison – permettant des lectures plus rapides. Bien sûr, il y a toujours des compromis. Ici, en raison de l’approche du filtre de floraison bloqué, ils doivent diviser un seul filtre de floraison en 8192 partitions uniques. Cela finit par affecter la vitesse d’ingestion par rapport à l’approche de partitionnement précédente qui permettait d’ingérer tous les morceaux de filtre de floraison à la fois. Cependant, la capacité de lire rapidement un bloc donné dans une heure est plus importante pour eux que les écrits rapides – ils ont donc décidé que ce compromis en valait la peine. Modélisation des données Pas étonnant, le passage de SQL à NoSQL impliquait une bonne quantité de redémarrage de modélisation de données, y compris quelques essais et erreurs. Par exemple, Sebastian a partagé, « Un jour, j’ai découvert que nous avions gâché les timestamps min et max – et je me suis demandé comment je allais le corriger. Je pensais que je pourrais peut-être renommer les colonnes et puis en faire fonctionner. Mais, ici, vous ne pouvez pas renommer une colonne si elle fait partie d’une cluster key. Je pensais que je pourrais certainement ajouter de nouvelles colonnes et exécuter une requête UPDATE pour mettre à jour toutes les lignes. En fin de compte, ils ont décidé de trancher la table et de recommencer contre l'écriture du code de migration.Leur meilleur conseil sur ce front est de le faire correctement la première fois. 🙂 Performance gagnante Malgré les travaux de modélisation de données nécessaires, la migration s'est bien payée. Chaque nœud gère actuellement 4 à 5 TB. Ils traitent actuellement environ 10K écrits par seconde avec une latence P99 constamment inférieure à un milliseconde. La liste des blocs donne lieu à environ 2000 fichiers de parquet en une heure ; avec leurs filtres à fleurs, ils sont traités en moins de 20 millisecondes. Pour les fichiers de 50K, c’est moins de 500 millisecondes. Mais, pour les fichiers 50K Parquet, 500 millisecondes est bon pour leurs besoins. Dans le traitement des métadonnées de colonne, le P50 est assez bon, mais il y a une latence de queue élevée. Sebastian a expliqué: «Le problème est que si nous avons des fichiers Parquet 50K, nos exécutants les récupèrent tous en parallèle. Création de scyllaDB Notamment, Coralogix est passé de la première découverte de ScyllaDB à la production avec des téraoctets de données en seulement 2 mois (et c'était une migration SQL à NoSQL nécessitant un travail de modélisation de données, pas une migration beaucoup plus simple Cassandra ou DynamoDB). La mise en œuvre a été écrite en Rust au-dessus de Et ils ont trouvé , à et Étant donné que l’offre à leurs propres clients d’une alternative à faible coût à l’observation est importante pour Coralogix, l’équipe de Coralogix s’est réjouie de la performance favorable des prix de leur infrastructure ScyllaDB : un cluster à 3 nœuds avec : ScyllaDB Rust chauffeur Opérateur ScyllaDB pour Kubernetes Surveillance de ScyllaDB Gestionnaire ScyllaDB 8 VCPU 32 Go de mémoire Armée / Gravitone Volumes EBS (gp3) avec bande passante de 500 Mbps et 12k IOPS L’utilisation d’ARM réduit les coûts, et la décision d’utiliser les volumes EBS (gp3) s’est finalement réduite à la disponibilité, la flexibilité et les performances de prix. Ils ont admis : « C’est une décision controversée – mais nous essayons de le faire fonctionner et nous verrons combien de temps nous pouvons gérer. » Les leçons apprises Les grandes leçons que nous avons apprises ici... La plus grande différence de travailler avec ScyllaDB versus travailler avec Postgres est que vous devez réfléchir assez soigneusement à votre partitionnement et vos tailles de partition. Keep an eye on partition sizes: Vous devez également réfléchir attentivement aux modèles de lecture/écriture.Votre charge de travail est-elle lourde en lecture?Vous avez un bon mélange de lectures et d'écriture?Ou est-elle principalement lourde en écriture?Les charges de travail de Coralogix sont assez lourdes en écriture parce qu'elles ingèrent constamment des données, mais elles doivent donner la priorité aux lectures parce que la latence de lecture est la plus importante pour leur entreprise. Think about read/write patterns: L'équipe admet qu'ils ont été avertis de ne pas utiliser EBS: "Nous n'avons pas écouté, mais nous devrions probablement.Si vous envisagez d'utiliser ScyllaDB, il serait probablement une bonne idée de regarder les instances qui ont des SSD locaux au lieu d'essayer d'utiliser des volumes EBS." Avoid EBS: Plans d’avenir : WebAssembly UDFs avec Rust À l’avenir, ils veulent trouver le milieu entre l’écriture de morceaux suffisamment grands et la lecture de données inutiles.Ils divisent les morceaux en ~ 8000 lignes et croient qu’ils peuvent les diviser davantage en 1000 lignes, ce qui pourrait accélérer leurs inserts. Leur objectif ultime est de télécharger encore plus de travail sur ScyllaDB en profitant de Avec leur code Rust existant, l'intégration des UDF éliminerait la nécessité d'envoyer des données de retour à l'application, offrant ainsi la flexibilité pour les ajustements et les améliorations potentielles. Fonctions définies par l'utilisateur (UDF) avec WebAssembly Sebastian partage : « Nous avons déjà tout écrit en Rust. Il serait vraiment agréable si nous pouvions commencer à utiliser les UDFs afin que nous n’ayons pas à renvoyer quoi que ce soit dans l’application. Regardez la conversation technique complète Vous pouvez regarder la conversation technique complète et skim à travers le pont dans notre bibliothèque de discussion technique. À propos de Cynthia Dunlop Cynthia est directrice générale de la stratégie de contenu chez ScyllaDB. Elle écrit sur le développement de logiciels et l'ingénierie de la qualité depuis plus de 20 ans.