
Ils disent que dans la vie, tout vaut la peine d'être essayé au moins une fois. Et si vous avez l'habitude de travailler avec des SGBD relationnels, vous familiariser avec NoSQL en vaut la peine, tout d'abord, au moins pour le développement général. Maintenant, en raison du développement rapide de cette technologie, il y a beaucoup d'opinions contradictoires et de débats houleux sur ce sujet, ce qui alimente particulièrement l'intérêt.
Si vous explorez l'essence de tous ces différends, vous pouvez voir qu'ils surviennent en raison d'une mauvaise approche. Ceux qui utilisent les bases de données NoSQL exactement là où ils sont nécessaires sont satisfaits et tirent tous ses avantages de cette solution. Et les expérimentateurs qui s'appuient sur cette technologie comme panacée où elle n'est pas du tout applicable, sont déçus de perdre les atouts des bases de données relationnelles sans en retirer des bénéfices significatifs.
Je vais vous parler de notre expérience dans la mise en œuvre d'une solution basée sur le SGBD Cassandra: ce à quoi nous avons dû faire face, comment nous sommes sortis de situations difficiles, avons-nous réussi à tirer parti de l'utilisation de NoSQL et où avons-nous dû investir des efforts / de l'argent supplémentaires.
La tâche initiale consiste à créer un système qui enregistre les appels vers un certain stockage.
Le principe du système est le suivant. Des fichiers avec une certaine structure décrivant la structure de l'appel arrivent à l'entrée. Ensuite, l'application s'assure que cette structure est enregistrée dans les colonnes appropriées. À l'avenir, les appels enregistrés sont utilisés pour afficher des informations sur la consommation de trafic des abonnés (frais, appels, historique des soldes).

Pourquoi Kassandra a été choisie est tout à fait compréhensible - elle écrit comme une mitrailleuse, facilement évolutive et tolérante aux pannes.
Alors, voici ce que l'expérience nous a donné
Oui, le nœud écrasé n'est pas une tragédie. C'est l'essence même de la tolérance aux fautes de Cassandra. Mais le nœud peut être actif et en même temps commencer à s'affaisser sur les performances . Il s'est avéré que cela affecte immédiatement les performances de l'ensemble du cluster.
Cassandra ne couvre pas où Oracle a enregistré avec ses constantes . Et si l'auteur de la demande n'a pas compris cela à l'avance, la prise de vol de Cassandra n'est pas pire que l'original. Une fois qu'il est venu, nous l'insérerons.
La Kassandra gratuite «prête à l'emploi» n'aimait pas beaucoup la sécurité de l'information: il n'y a pas de journalisation des actions des utilisateurs, ni de différenciation des droits . Les informations sur les appels concernent des données personnelles, ce qui signifie que toutes les tentatives de demande / modification de quelque manière que ce soit devraient être enregistrées avec la possibilité d'un audit ultérieur. En outre, vous devez être conscient de la nécessité de séparer les droits à différents niveaux pour différents utilisateurs. Un simple ingénieur d'exploitation et un super administrateur qui peuvent supprimer librement l'intégralité de l'espace de touches sont différents rôles, différentes responsabilités, compétences. Sans une telle différenciation des droits d'accès, la valeur et l'intégrité des données seront immédiatement remises en question plus rapidement qu'avec n'importe quel niveau de cohérence.
Nous n'avons pas tenu compte du fait que les appels nécessitent des analyses sérieuses, ainsi que des échantillons périodiques pour diverses conditions. Étant donné que les enregistrements sélectionnés sont ensuite censés être supprimés et réécrits (dans le cadre de la tâche, nous devons prendre en charge le processus de mise à jour des données lorsque la boucle de données est initialement entrée incorrectement), Kassandra n'est pas notre ami ici. Cassandra, comme une tirelire, est pratique à y mettre, mais vous ne pourrez pas y compter.
Face au problème du transfert des données vers les zones de test (5 nœuds dans le test contre 20 dans le bal). Dans ce cas, un vidage ne peut pas être utilisé.
Le problème de la mise à jour du schéma de données d'une application écrivant à Kassandra. Le retour en arrière donnera lieu à un grand nombre de pierres tombales, ce qui, de manière imprévisible, peut réduire notre productivité . Cassandra est optimisée pour l'enregistrement, et avant l'enregistrement, ne pense pas beaucoup. Toute opération contenant des données existantes est également un enregistrement. Autrement dit, après avoir supprimé l'excédent, nous générons simplement encore plus d'enregistrements, et seule une partie d'entre eux sera marquée de pierres tombales.
Délais d'attente sur insert. Cassandra est belle dans l'enregistrement, mais parfois le flux entrant peut être très déroutant pour elle . Cela se produit lorsque l'application commence à encercler plusieurs enregistrements qui ne peuvent pas être insérés pour une raison quelconque. Et nous aurons besoin d'un véritable DBA, qui suivra gc.log, les journaux système et de débogage pour les requêtes lentes, les mesures de compactage en attente.
Plusieurs centres de données dans un cluster. Où lire et où écrire?
Peut-être divisé en lecture et en écriture? Et si oui, devrait-il y avoir un DC pour écrire ou lire plus près de l'application? Et n'obtiendrons-nous pas un vrai cerveau divisé si nous choisissons le niveau de cohérence incorrectement? Beaucoup de questions, beaucoup de paramètres inexplorés, des fonctionnalités que je veux vraiment tordre.
Comment avons-nous décidé
Que le nœud n'a pas gaspillé, désactivé SWAP . Et maintenant, avec un manque de mémoire, le nœud doit s'allonger et ne pas produire de grandes pauses gc.
Donc, nous n'espérons plus de logique dans la base de données. Les développeurs d'applications réapprennent et commencent à sécuriser activement leur propre code. Séparation parfaite et parfaite du stockage et du traitement des données.
Nous avons acheté le support de DataStax. Le Kassandra en boîte a déjà cessé de se développer (le dernier commit en février 2018). Dans le même temps, Datastax offre un excellent service et un grand nombre de solutions CI modifiées et adaptées aux solutions existantes.
Je tiens également à noter que Kassandra n'est pas très pratique pour interroger des échantillons. Bien sûr, CQL est un grand pas vers les utilisateurs (par rapport à Trift). Mais si vous avez des départements entiers, habitués à de telles jointures pratiques, un filtrage gratuit par n'importe quel champ et des options d'optimisation des requêtes, et que ces départements travaillent pour fermer les réclamations et les accidents, alors la décision sur Kassandra lui semble ennemie et stupide. Et nous avons commencé à aborder la question de savoir comment nos collègues peuvent faire des échantillons.
Nous avons considéré deux options: dans la première, nous écrivons les appels non seulement en C *, mais aussi dans la base de données d'archives Oracle. Seul, contrairement à C *, les appels sont stockés dans cette base de données uniquement pour le mois en cours (profondeur de stockage des appels suffisante pour les cas de recertification). Ici, nous avons immédiatement vu le problème suivant: si vous écrivez de manière synchrone, nous perdons tous les avantages de C * associés à l'insertion rapide, si de manière asynchrone, il n'y a aucune garantie que tous les appels nécessaires atteignent généralement Oracle. Il y avait un plus, mais grand: pour l'exploitation, le même développeur PL / SQL familier reste, c'est-à-dire que nous implémentons pratiquement le modèle «Facade». Une option alternative. Nous implémentons un mécanisme qui décharge les appels de C *, extrait des données à enrichir des tables correspondantes dans Oracle, joint les échantillons reçus et nous donne le résultat, que nous utilisons ensuite d'une manière ou d'une autre (annule, répète, analyse, admire). Inconvénients: le processus est assez multi-étapes, et en plus, il n'y a pas d'interface pour le personnel d'exploitation.
En conséquence, nous avons toujours opté pour la deuxième option. Apache Spark a été utilisé pour des échantillons provenant de différentes boîtes. L'essence du mécanisme se résumait au code Java qui, en utilisant les clés spécifiées (abonné, clés de temps d'appel), extrait les données de C *, ainsi que les données nécessaires pour l'enrichissement de toute autre base de données. Il les rejoint ensuite dans sa mémoire et affiche le résultat dans le tableau résultant. Un museau en toile a été tiré sur l'étincelle et il s'est avéré être tout à fait utilisable.

Lors de la résolution d'un problème de mise à jour des données, un test promotionnel a de nouveau examiné plusieurs solutions. À la fois le transfert via Sstloader et la possibilité de diviser le cluster dans la zone de test en deux parties, chacune entrant alternativement dans le même cluster que le promo, étant ainsi alimentée par celui-ci. Lors de la mise à jour du test, il était prévu de changer de place: la partie qui a fonctionné dans le test est effacée et entrée dans le bal de promo, et l'autre commence à travailler séparément avec les données. Cependant, en y repensant, nous avons évalué de manière plus rationnelle les données qui devraient être transférées, et nous avons réalisé que les appels eux-mêmes sont une entité incohérente pour les tests, générée rapidement si nécessaire, et c'est l'ensemble de données promo qui ne vaut pas la peine d'être transféré au test. Il y a plusieurs objets de stockage qui valent la peine d'être déplacés, mais ce sont littéralement quelques tables, et pas très lourdes. Par conséquent , Spark est à nouveau venu à notre aide en tant que solution, avec l'aide de laquelle nous avons écrit et a commencé à utiliser activement le transfert de données entre les tables des scripts de test de prom.
Notre politique de déploiement actuelle nous permet de travailler sans ristournes. Avant le bal, il y a un passage obligatoire au test, où l'erreur n'est pas si chère. En cas d'échec, vous pouvez toujours supprimer l'espace de cas et lancer l'ensemble du schéma depuis le début.
Pour assurer la disponibilité continue de Cassandra, vous avez besoin de dba et pas seulement. Tous ceux qui travaillent avec l'application doivent comprendre où et comment regarder la situation actuelle et comment diagnostiquer les problèmes en temps opportun. Pour ce faire, nous utilisons activement DataStax OpsCenter (Administration and Monitoring of Workloads), les métriques du système Cassandra Driver (nombre de timeouts pour l'écriture vers C *, nombre de timeouts pour la lecture depuis C *, latence maximale, etc.), la surveillance le travail de l'application elle-même, en collaboration avec Kassandra.
Lorsque nous avons réfléchi à la question précédente, nous avons réalisé où pouvait se situer notre principal risque. Ce sont des formulaires d'affichage de données qui produisent des données de plusieurs demandes de stockage indépendantes les unes des autres. De cette façon, nous pouvons obtenir des informations assez incohérentes. Mais ce problème serait tout aussi pertinent si nous travaillions avec un seul centre de données. Donc, la chose la plus raisonnable ici est, bien sûr, de faire la fonction batch de lecture des données sur une application tierce, ce qui garantira que les données sont reçues en une seule période de temps. Quant à la séparation de la lecture et de l'écriture en termes de performances, nous avons ici été stoppés par le risque qu'avec une certaine perte de connexion entre les DC, nous puissions obtenir deux clusters totalement incohérents.
Par conséquent, pour le moment, nous nous sommes arrêtés au niveau de cohérence pour l'enregistrement EACH_QUORUM, pour la lecture - LOCAL_QUORUM
Brèves impressions et conclusions
Afin d'évaluer la solution qui en résulte du point de vue du soutien opérationnel et des perspectives de développement, nous avons décidé de réfléchir à d'autres possibilités d'application d'un tel développement.
Si vous êtes en déplacement, scorez des données pour des programmes comme «Payez quand cela vous convient» (nous chargeons des informations dans C *, calcul à l'aide de scripts Spark), prenant en compte les revendications avec agrégation par directions, stockant les rôles et calculant les droits d'accès des utilisateurs à l'aide de la matrice des rôles.
Comme vous pouvez le voir, le répertoire est large et varié. Et si nous choisissons le camp des partisans / opposants de NoSQL, nous rejoindrons les partisans, puisque nous avons obtenu nos avantages, et exactement où nous nous attendions.
Même l'option Cassandra prête à l'emploi permet une mise à l'échelle horizontale en temps réel, résolvant sans aucun problème le problème de l'augmentation des données dans le système. Nous avons réussi à mettre dans un circuit séparé un mécanisme très chargé pour calculer les agrégats des appels, et aussi à séparer le schéma et la logique de l'application, en nous débarrassant de la vicieuse pratique d'écrire des travaux et des objets personnalisés dans la base de données elle-même. Nous avons eu la possibilité de choisir et de configurer, afin d'accélérer, sur quels contrôleurs de domaine nous allons calculer et sur quels enregistrements de données, nous nous sommes assurés pour les baisses des nœuds individuels et de l'ensemble du contrôleur de domaine.
En appliquant notre architecture à de nouveaux projets, et ayant déjà une certaine expérience, je voudrais prendre immédiatement en compte les nuances décrites ci-dessus, ne pas commettre d'erreurs, aplanir certains angles vifs, ce qui ne pouvait pas être évité au départ.
Par exemple, gardez une trace des mises à jour de Cassandra à temps , car bon nombre de problèmes que nous avons reçus étaient déjà connus et corrigés.
Ne placez pas la base de données elle-même et Spark sur les mêmes nœuds (ou divisez-les strictement par la quantité d'utilisation des ressources acceptable), car Spark peut consommer plus d'OP que prévu, et nous obtiendrons rapidement le problème numéro 1 de notre liste.
Pomper les compétences de surveillance et d'exploitation au stade des tests du projet. Dans un premier temps, prenez en compte le maximum de tous les consommateurs potentiels de notre solution , car la structure de la base de données en dépendra finalement.
Tournez le circuit résultant plusieurs fois pour une optimisation possible. Sélectionnez les champs qui peuvent être sérialisés. Comprendre quelles tables supplémentaires nous pouvons faire afin de prendre en compte le plus correctement et de manière optimale, puis renvoyer les informations requises sur demande (par exemple, en supposant que nous pouvons stocker les mêmes données dans différentes tables, en tenant compte de différentes ventilations selon différents critères, peut économiser considérablement) temps processeur pour les requêtes de lecture).
C'est une bonne idée de monter immédiatement TTL et de nettoyer les données obsolètes.
Lors du déchargement des données de Cassandra, la logique d'application doit fonctionner selon le principe FETCH, afin que toutes les lignes ne soient pas chargées en mémoire à la fois, mais sélectionnées par lots.
Avant de transférer le projet vers la solution décrite, il est conseillé de vérifier la tolérance aux pannes du système en effectuant une série de tests de collision , tels que la perte de données dans un centre de données, la restauration des données endommagées pendant une certaine période et la fermeture du réseau entre les centres de données. De tels tests vous permettront non seulement d'évaluer les avantages et les inconvénients de l'architecture proposée, mais également de donner de bonnes pratiques d'échauffement aux ingénieurs qui les conduisent, et la compétence acquise sera loin d'être superflue si les défaillances du système sont reproduites dans le bal.
Si nous travaillons avec des informations critiques (telles que les données de facturation, le calcul de la dette des abonnés), il convient également de prêter attention aux outils qui réduiront les risques qui découlent des caractéristiques du SGBD. Par exemple, utilisez l'utilitaire nœudsync (Datastax), ayant développé une stratégie optimale pour son utilisation, afin que par souci de cohérence de ne pas former une charge excessive sur Cassandra et de ne l'utiliser que pour certaines tables dans une certaine période.
Eh bien, après six mois de vie, avec Cassandra? En général, il n'y a pas de problèmes non résolus. Accidents graves et perte de données, nous n'avons pas non plus permis. Oui, j'ai dû penser à compenser certains problèmes qui n'étaient pas apparus auparavant, mais au final cela n'a pas éclipsé notre solution architecturale. Si vous voulez et n'avez pas peur d'essayer quelque chose de nouveau, et en même temps ne voulez pas être très déçu, alors préparez-vous au fait que rien ne se passe gratuitement. Vous devrez comprendre, creuser dans la documentation et collecter votre râteau individuel que dans l'ancienne solution héritée et aucune théorie ne vous dira à l'avance exactement quel râteau vous attend.