Comment regarder Cassandra dans les yeux sans perdre de données, de stabilité et de confiance dans NoSQL

Comment regarder Cassandra dans les yeux sans perdre de données, de stabilité et de confiance dans NoSQL

On dit que tout dans la vie vaut la peine d’être essayé au moins une fois. Et si vous avez l'habitude de travailler avec des SGBD relationnels, cela vaut la peine de vous familiariser avec NoSQL dans la pratique, tout d'abord, au moins pour le développement général. Aujourd'hui, en raison du développement rapide de cette technologie, il existe de nombreuses opinions contradictoires et des débats houleux sur ce sujet, ce qui suscite particulièrement l'intérêt.
Si vous approfondissez l’essence de tous ces différends, vous constaterez qu’ils résultent d’une mauvaise approche. Ceux qui utilisent les bases de données NoSQL exactement là où elles sont nécessaires sont satisfaits et bénéficient de tous les avantages de cette solution. Et les expérimentateurs qui considèrent cette technologie comme une panacée là où elle n’est pas du tout applicable sont déçus, ayant perdu les atouts des bases de données relationnelles sans en tirer des avantages significatifs.

Je vais vous parler de notre expérience dans la mise en œuvre d'une solution basée sur le SGBD Cassandra : à quoi nous avons dû faire face, comment nous sommes sortis de situations difficiles, si nous avons pu bénéficier de l'utilisation de NoSQL et où nous avons dû investir des efforts/des fonds supplémentaires .
La tâche initiale consiste à créer un système qui enregistre les appels dans une sorte de stockage.

Le principe de fonctionnement du système est le suivant. L'entrée inclut des fichiers avec une structure spécifique qui décrit la structure de l'appel. L'application s'assure ensuite que cette structure est stockée dans les colonnes appropriées. A l'avenir, les appels enregistrés permettront d'afficher des informations sur la consommation de trafic des abonnés (facturations, appels, historique des soldes).

Comment regarder Cassandra dans les yeux sans perdre de données, de stabilité et de confiance dans NoSQL

La raison pour laquelle ils ont choisi Cassandra est très claire : elle écrit comme une mitrailleuse, est facilement évolutive et tolérante aux pannes.

Voilà donc ce que l'expérience nous a apporté

Oui, un nœud défaillant n’est pas une tragédie. C'est l'essence de la tolérance aux pannes de Cassandra. Mais un nœud peut être vivant et en même temps commencer à souffrir de performances. Il s'est avéré que cela affecte immédiatement les performances de l'ensemble du cluster.

Cassandra ne vous protégera pas là où Oracle vous a sauvé avec ses contraintes. Et si l'auteur de la candidature ne l'a pas compris à l'avance, alors le double arrivé pour Cassandra n'est pas pire que l'original. Une fois arrivé, nous le mettrons dedans.

IB n'a pas vraiment aimé la Cassandra gratuite prête à l'emploi : Il n'y a pas de journalisation des actions des utilisateurs, pas de différenciation des droits. Les informations sur les appels sont considérées comme des données personnelles, ce qui signifie que toutes les tentatives de demande/modification de quelque manière que ce soit doivent être enregistrées avec la possibilité d'un audit ultérieur. Vous devez également être conscient de la nécessité de séparer les droits à différents niveaux pour les différents utilisateurs. Un simple ingénieur d'exploitation et un super administrateur qui peut librement supprimer l'intégralité de l'espace de clés ont des rôles, des responsabilités et des compétences différents. 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 TOUT niveau de cohérence.

Nous n'avons pas tenu compte du fait que les appels nécessitent à la fois des analyses sérieuses et un échantillonnage périodique 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 les données sont initialement entrées incorrectement dans notre boucle), Cassandra n'est pas notre amie ici. Cassandra est comme une tirelire : c'est pratique d'y mettre des choses, mais on ne peut pas y compter.

Nous avons rencontré un problème lors du transfert des données vers les zones de test (5 nœuds dans le test contre 20 dans le bal). Dans ce cas, le dump ne peut pas être utilisé.

Le problème de la mise à jour du schéma de données d'une application écrivant sur Cassandra. Un retour en arrière engendrera de nombreuses pierres tombales, qui peuvent entraîner des pertes de productivité de manière imprévisible.. Cassandra est optimisée pour l'enregistrement et ne réfléchit pas beaucoup avant d'écrire. Toute opération contenant des données existantes est également un enregistrement. Autrement dit, en supprimant ce qui est inutile, nous produirons simplement encore plus de documents, et seuls certains d'entre eux seront marqués de pierres tombales.

Délais d'expiration lors de l'insertion. Cassandra est magnifique dans l'enregistrement, mais parfois, le flux entrant peut la dérouter considérablement. Cela se produit lorsque l'application commence à parcourir plusieurs enregistrements qui ne peuvent pas être insérés pour une raison quelconque. Et nous aurons besoin d'un véritable administrateur de base de données qui surveillera gc.log, les journaux système et de débogage pour les requêtes lentes, les métriques de compactage en attente.

Plusieurs centres de données dans un cluster. Où lire et où écrire ?
Peut-être divisé en lecture et écriture ? Et si oui, devrait-il y avoir un DC plus proche de l’application pour l’écriture ou la lecture ? Et ne nous retrouverons-nous pas avec un véritable cerveau divisé si nous choisissons le mauvais niveau de cohérence ? Il y a beaucoup de questions, beaucoup de paramètres inconnus, des possibilités avec lesquelles on a vraiment envie de bricoler.

Comment nous avons décidé

Pour empêcher le nœud de couler, SWAP a été désactivé. Et maintenant, s'il y a un manque de mémoire, le nœud doit s'arrêter et ne pas créer de grandes pauses gc.

Nous ne nous appuyons donc plus sur la logique de la base de données. Les développeurs d'applications se recyclent et commencent à prendre activement des précautions dans leur propre code. Séparation claire et idéale du stockage et du traitement des données.

Nous avons acheté le support de DataStax. Le développement de Cassandra en boîte a déjà cessé (le dernier commit remonte à février 2018). Parallèlement, Datastax propose un excellent service et un grand nombre de solutions modifiées et adaptées aux solutions IP existantes.

Je tiens également à noter que Cassandra n'est pas très pratique pour les requêtes de sélection. Bien entendu, CQL constitue un grand pas en avant pour les utilisateurs (par rapport à Trift). Mais si vous avez des départements entiers habitués à des connexions aussi pratiques, à un filtrage gratuit par n'importe quel champ et à des capacités d'optimisation des requêtes, et que ces départements s'efforcent de résoudre les plaintes et les accidents, alors la solution sur Cassandra leur semble hostile et stupide. Et nous avons commencé à décider comment nos collègues devaient réaliser des échantillons.

Nous avons envisagé deux options : dans la première option, nous écrivons les appels non seulement en C*, mais également dans la base de données Oracle archivée. Seulement, contrairement au C*, cette base de données stocke uniquement les appels du mois en cours (profondeur de stockage des appels suffisante pour les dossiers de recharge). Ici, nous avons immédiatement vu le problème suivant : si nous écrivons de manière synchrone, alors nous perdons tous les avantages du C* associés à une insertion rapide ; si nous écrivons de manière asynchrone, il n'y a aucune garantie que tous les appels nécessaires parviennent à Oracle. Il y avait un plus, mais un gros : pour le fonctionnement, le même développeur PL/SQL familier reste, c'est-à-dire que nous implémentons pratiquement le modèle « Façade ». Une option alternative. Nous implémentons un mécanisme qui décharge les appels de C*, extrait certaines données pour les enrichir des tables correspondantes dans Oracle, joint les échantillons résultants et nous donne le résultat, que nous utilisons ensuite d'une manière ou d'une autre (restaurer, répéter, analyser, admirer). Inconvénients : le processus est assez multi-étapes, et de plus, il n'y a pas d'interface pour les employés d'exploitation.

Finalement, nous avons opté pour la deuxième option. Apache Spark a été utilisé pour échantillonner différents pots. L'essence du mécanisme a été réduite au code Java qui, à l'aide des clés spécifiées (abonné, heure de l'appel - touches de section), extrait les données de C*, ainsi que les données nécessaires à l'enrichissement de toute autre base de données. Après quoi il les rejoint dans sa mémoire et affiche le résultat dans le tableau résultant. Nous avons dessiné une face Web sur l'étincelle et cela s'est avéré tout à fait utilisable.

Comment regarder Cassandra dans les yeux sans perdre de données, de stabilité et de confiance dans NoSQL

Lors de la résolution du problème de la mise à jour des données des tests industriels, nous avons à nouveau envisagé plusieurs solutions. Les deux transferts via Sstloader et la possibilité de diviser le cluster dans la zone de test en deux parties, chacune appartenant alternativement au même cluster que celui promotionnel, étant ainsi alimentées par celui-ci. Lors de la mise à jour du test, il était prévu de les échanger : la partie qui a fonctionné dans le test est effacée et entrée en production, et l'autre commence à travailler avec les données séparément. Cependant, après y avoir réfléchi, nous avons évalué plus rationnellement les données qui méritaient d'être transférées et avons réalisé que les appels eux-mêmes constituent une entité incohérente pour les tests, générés rapidement si nécessaire, et que c'est l'ensemble de données promotionnelles qui n'a aucune valeur pour le transfert vers le test. Il existe plusieurs objets de stockage qui valent la peine d'être déplacés, mais il s'agit littéralement de quelques tables, et pas très lourdes. Par conséquent, nous comme solution, Spark est de nouveau venu à la rescousse, avec l'aide duquel nous avons écrit et commencé à utiliser activement un script pour transférer des données entre tables, prom-test.

Notre politique de déploiement actuelle nous permet de travailler sans restauration. Avant la promotion, il y a un test obligatoire, où une erreur ne coûte pas si cher. En cas d'échec, vous pouvez toujours supprimer l'espace de cas et relancer l'intégralité du schéma depuis le début.

Pour assurer une disponibilité continue de Cassandra, vous avez besoin d’un dba et pas seulement de lui. Tous ceux qui travaillent avec l'application doivent comprendre où et comment examiner la situation actuelle et comment diagnostiquer les problèmes en temps opportun. Pour ce faire, nous utilisons activement DataStax OpsCenter (Administration et surveillance des charges de travail), les métriques du système Cassandra Driver (nombre de délais d'attente pour l'écriture en C*, nombre de délais d'attente pour la lecture depuis C*, latence maximale, etc.), surveillons le fonctionnement de l'application elle-même, en collaboration avec Cassandra.

En réfléchissant à la question précédente, nous avons réalisé où pourrait résider notre principal risque. Il s'agit de formulaires d'affichage de données qui affichent les données de plusieurs requêtes indépendantes sur le stockage. De cette façon, nous pouvons obtenir des informations assez incohérentes. Mais ce problème serait tout aussi pertinent si l’on travaillait avec un seul data center. La chose la plus raisonnable ici est donc bien sûr de créer une fonction batch pour lire les 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 division entre lecture et écriture en termes de performances, nous avons été ici arrêtés par le risque qu'avec une certaine perte de connexion entre les DC, nous puissions nous retrouver avec deux clusters complètement incohérents l'un avec l'autre.

En conséquence, pour l'instant arrêté au niveau de cohérence pour l'écriture de EACH_QUORUM, pour la lecture - LOCAL_QUORUM

Brèves impressions et conclusions

Afin d'évaluer la solution résultante du point de vue du support opérationnel et des perspectives de développement ultérieur, nous avons décidé de réfléchir aux autres endroits où un tel développement pourrait être appliqué.

D'emblée, puis le scoring des données pour des programmes comme « Payez quand cela vous convient » (nous chargeons les informations en C*, calcul à l'aide de scripts Spark), comptabilisation des sinistres avec agrégation par zone, stockage des rôles et calcul des droits d'accès des utilisateurs en fonction du rôle matrice.

Comme vous pouvez le constater, le répertoire est large et varié. Et si nous choisissons le camp des partisans/opposants de NoSQL, alors nous rejoindrons les partisans, puisque nous avons reçu nos avantages, et exactement là 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 de manière absolument indolore le problème de l'augmentation des données dans le système. Nous avons pu déplacer un mécanisme très chargé pour calculer les agrégats d'appels dans un circuit séparé, et également séparer le schéma et la logique de l'application, éliminant ainsi la mauvaise pratique consistant à écrire des tâches et des objets personnalisés dans la base de données elle-même. Nous avons eu la possibilité de choisir et de configurer, d'accélérer, sur quels DC nous effectuerons des calculs et sur lesquels nous enregistrerons des données, nous nous sommes assurés contre les crashs des nœuds individuels et du DC dans son ensemble.

Appliquant notre architecture à de nouveaux projets, et ayant déjà une certaine expérience, je voudrais immédiatement prendre en compte les nuances décrites ci-dessus, et éviter certaines erreurs, aplanir certains angles vifs qui ne pouvaient être évités au départ.

Par exemple, suivre les mises à jour de Cassandra en temps opportuncar bon nombre des problèmes que nous avons rencontrés étaient déjà connus et résolus.

Ne placez pas la base de données elle-même et Spark sur les mêmes nœuds (ou divisez strictement par la quantité d'utilisation de ressources autorisée), car Spark peut consommer plus d'OP que prévu, et nous obtiendrons rapidement le problème numéro 1 de notre liste.

Améliorer le suivi et les compétences opérationnelles au stade des tests du projet. Dans un premier temps, prendre en compte autant que possible tous les consommateurs potentiels de notre solution, car c'est de cela que dépendra en fin de compte la structure de la base de données.

Faites pivoter le circuit obtenu plusieurs fois pour une éventuelle optimisation. Sélectionnez les champs qui peuvent être sérialisés. Comprendre quels tableaux supplémentaires nous devons réaliser afin de les prendre en compte de la manière la plus correcte et optimale, puis fournir les informations requises sur demande (par exemple, en supposant que nous pouvons stocker les mêmes données dans des tableaux différents, en tenant compte de différentes répartitions selon différents critères, nous pouvons économiser considérablement du temps CPU pour les requêtes de lecture).

Pas mal Prévoyez immédiatement la fixation du TTL et le nettoyage des données obsolètes.

Lors du téléchargement de données depuis Cassandra La logique de l'application doit fonctionner selon le principe FETCH, de sorte que toutes les lignes ne soient pas chargées en mémoire en même temps, mais soient sélectionnées par lots.

Il est conseillé avant de transférer le projet vers la solution décrite vérifier la tolérance aux pannes du système en effectuant une série de crash tests, comme la perte de données dans un centre de données, la restauration de données endommagées sur une certaine période, la coupure de réseau entre les centres de données. De tels tests permettront non seulement d'évaluer les avantages et les inconvénients de l'architecture proposée, mais constitueront également une bonne pratique de mise en route pour les ingénieurs qui les réaliseront, et les compétences acquises seront loin d'être superflues si des pannes du système se reproduisent en production.

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 liés aux fonctionnalités du SGBD. Par exemple, utilisez l'utilitaire nodesync (Datastax), après avoir développé une stratégie optimale pour son utilisation afin par souci de cohérence, ne créez pas une charge excessive sur Cassandra et utilisez-le uniquement pour certaines tables dans une certaine période.

Qu'arrive-t-il à Cassandra après six mois de vie ? En général, il n’y a pas de problèmes non résolus. Nous n’avons également autorisé aucun accident grave ni perte de données. Oui, nous avons dû réfléchir à compenser certains problèmes qui ne s'étaient pas posés auparavant, mais au final, cela n'a pas trop gêné 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 trop déçu, préparez-vous au fait que rien n'est gratuit. Vous devrez comprendre, approfondir la documentation et assembler votre propre rake individuel plus que dans l'ancienne solution héritée, et aucune théorie ne vous dira à l'avance quel rake vous attend.

Source: habr.com

Ajouter un commentaire