Architecture et capacités de Tarantool Data Grid

Architecture et capacités de Tarantool Data Grid

En 2017, nous avons remporté un concours pour développer le cœur transactionnel de l'activité d'investissement d'Alfa-Bank et avons commencé à travailler (à HighLoad++ 2018 avec un rapport sur le cœur de l'activité d'investissement). effectué Vladimir Drynkin, responsable du noyau transactionnel des activités d'investissement d'Alfa Bank). Ce système était censé regrouper les données de transaction provenant de différentes sources dans différents formats, regrouper les données sous une forme unifiée, les stocker et y donner accès.

Au cours du processus de développement, le système a évolué et acquis des fonctionnalités, et à un moment donné, nous avons réalisé que nous cristallisions quelque chose de bien plus qu'un simple logiciel d'application créé pour résoudre un ensemble de tâches strictement définies : nous avons réussi système pour créer des applications distribuées avec stockage persistant. L'expérience que nous avons acquise a constitué la base d'un nouveau produit - Grille de données Tarantool (TMD).

Je souhaite parler de l'architecture TDG et des solutions auxquelles nous sommes parvenus au cours du processus de développement, vous présenter les principales fonctionnalités et montrer comment notre produit peut devenir la base pour créer des solutions complètes.

Sur le plan architectural, nous avons divisé le système en les rôles, dont chacun est chargé de résoudre un certain nombre de problèmes. Une seule instance d'application en cours d'exécution implémente un ou plusieurs types de rôles. Il peut y avoir plusieurs rôles du même type dans un cluster :

Architecture et capacités de Tarantool Data Grid

connecteur

Connector est responsable de la communication avec le monde extérieur ; sa tâche est d'accepter la demande, de l'analyser et, si cela réussit, d'envoyer les données pour traitement au processeur d'entrée. Nous prenons en charge les formats HTTP, SOAP, Kafka, FIX. L'architecture vous permet d'ajouter simplement la prise en charge de nouveaux formats, la prise en charge d'IBM MQ étant bientôt disponible. Si l'analyse de la demande échoue, le connecteur renvoie une erreur ; sinon, il répondra que la demande a été traitée avec succès, même si une erreur s'est produite lors de son traitement ultérieur. Cela a été fait spécifiquement afin de travailler avec des systèmes qui ne savent pas répéter les demandes - ou, au contraire, le font de manière trop persistante. Afin de ne pas perdre de données, une file d'attente de réparation est utilisée : l'objet y pénètre d'abord et n'en est supprimé qu'après un traitement réussi. L'administrateur peut recevoir des alertes sur les objets restant dans la file d'attente de réparation et, après avoir éliminé une erreur logicielle ou une panne matérielle, réessayer.

Processeur d'entrée

Le processeur d'entrée classe les données reçues selon leurs caractéristiques et appelle les processeurs appropriés. Les gestionnaires sont du code Lua qui s'exécute dans un bac à sable, ils ne peuvent donc pas affecter le fonctionnement du système. À ce stade, les données peuvent être réduites à la forme requise et, si nécessaire, un nombre arbitraire de tâches peut être lancée pour mettre en œuvre la logique nécessaire. Par exemple, dans le produit MDM (Master Data Management) construit sur Tarantool Data Grid, lors de l'ajout d'un nouvel utilisateur, afin de ne pas ralentir le traitement de la demande, nous lançons la création d'un golden record en tant que tâche distincte. Le bac à sable prend en charge les demandes de lecture, de modification et d'ajout de données, vous permet d'exécuter certaines fonctions sur tous les rôles de type de stockage et d'agrégation du résultat (cartographie/réduction).

Les gestionnaires peuvent être décrits dans des fichiers :

sum.lua

local x, y = unpack(...)
return x + y

Et puis, déclaré dans la configuration :

functions:
  sum: { __file: sum.lua }

Pourquoi Lua ? Lua est un langage très simple. D'après notre expérience, quelques heures après en avoir pris connaissance, les gens commencent à écrire du code qui résout leur problème. Et ce ne sont pas seulement des développeurs professionnels, mais aussi, par exemple, des analystes. De plus, grâce au compilateur jit, Lua s'exécute très rapidement.

Stockage

Le stockage stocke les données persistantes. Avant d'être enregistrées, les données sont validées par rapport au schéma de données. Pour décrire le circuit, nous utilisons un format étendu Apache Euro. Exemple:

{
    "name": "User",
    "type": "record",
    "logicalType": "Aggregate",
    "fields": [ 
        { "name": "id", "type": "string"}, 
        {"name": "first_name", "type": "string"}, 
        {"name": "last_name", "type": "string"} 
    ], 
    "indexes": ["id"] 
}

Sur la base de cette description, le DDL (Data Definition Language) est automatiquement généré pour le SGBD Tarantula et GraphQL schéma d'accès aux données.

La réplication asynchrone des données est prise en charge (il est prévu d'en ajouter une synchrone).

Processeur de sortie

Parfois, il est nécessaire d'informer les consommateurs externes de l'arrivée de nouvelles données ; à cet effet, il existe le rôle Processeur de sortie. Après avoir enregistré les données, elles peuvent être transmises au gestionnaire approprié (par exemple, pour les amener au formulaire requis par le consommateur) - puis transmises au connecteur pour envoi. Une file d'attente de réparation est également utilisée ici : si personne n'a accepté l'objet, l'administrateur peut réessayer plus tard.

Mise à l'échelle

Les rôles de connecteur, de processeur d'entrée et de processeur de sortie sont sans état, ce qui nous permet de faire évoluer le système horizontalement en ajoutant simplement de nouvelles instances d'application avec le type de rôle souhaité activé. Le stockage est utilisé pour la mise à l'échelle horizontale подход à organiser un cluster à l'aide de compartiments virtuels. Après l'ajout d'un nouveau serveur, certains compartiments des anciens serveurs sont déplacés vers le nouveau serveur en arrière-plan ; cela se produit de manière transparente pour les utilisateurs et n'affecte pas le fonctionnement de l'ensemble du système.

Propriétés des données

Les objets peuvent être très volumineux et contenir d’autres objets. Nous garantissons l'atomicité de l'ajout et de la mise à jour des données en stockant un objet avec toutes les dépendances dans un seul compartiment virtuel. Cela évite que l’objet soit « réparti » sur plusieurs serveurs physiques.

Le versioning est pris en charge : chaque mise à jour d'un objet crée une nouvelle version, et nous pouvons toujours prendre une tranche de temps et voir à quoi ressemblait le monde à cette époque. Pour les données qui n'ont pas besoin d'un long historique, nous pouvons limiter le nombre de versions ou même n'en stocker qu'une seule - la dernière - c'est-à-dire essentiellement désactiver le versionnage pour un certain type. Vous pouvez également limiter l'historique dans le temps : par exemple, supprimer tous les objets d'un certain type datant de plus d'un an. L'archivage est également pris en charge : nous pouvons décharger des objets plus anciens que l'heure spécifiée, libérant ainsi de l'espace dans le cluster.

Tâches

Parmi les fonctionnalités intéressantes, il convient de noter la possibilité de lancer des tâches selon un planning, à la demande de l'utilisateur, ou par programmation depuis le sandbox :

Architecture et capacités de Tarantool Data Grid

Ici, nous voyons un autre rôle - le coureur. Ce rôle est sans état et des instances d'application supplémentaires dotées de ce rôle peuvent être ajoutées au cluster si nécessaire. La responsabilité du coureur est d'accomplir les tâches. Comme mentionné, il est possible de générer de nouvelles tâches à partir du bac à sable ; ils sont enregistrés dans une file d'attente sur le stockage puis exécutés sur le coureur. Ce type de tâche est appelé Job. Nous avons également un type de tâche appelé Tâche : ce sont des tâches définies par l'utilisateur qui s'exécutent selon un calendrier (en utilisant la syntaxe cron) ou à la demande. Pour lancer et suivre ces tâches, nous disposons d’un gestionnaire de tâches pratique. Pour que cette fonctionnalité soit disponible, vous devez activer le rôle de planificateur ; ce rôle a un état, il n'évolue donc pas, ce qui n'est pas obligatoire ; en même temps, comme tous les autres rôles, il peut avoir une réplique qui commence à fonctionner si le maître refuse soudainement.

Logger

Un autre rôle est appelé enregistreur. Il collecte les journaux de tous les membres du cluster et fournit une interface pour les télécharger et les visualiser via l'interface Web.

Services

Il convient de mentionner que le système facilite la création de services. Dans le fichier de configuration, vous pouvez spécifier quelles requêtes sont envoyées à un gestionnaire écrit par l'utilisateur qui s'exécute dans le bac à sable. Dans ce gestionnaire, vous pouvez, par exemple, exécuter une sorte de requête analytique et renvoyer le résultat.

Le service est décrit dans le fichier de configuration :

services:
   sum:
      doc: "adds two numbers"
      function: sum
      return_type: int
      args:
         x: int
         y: int

L'API GraphQL est générée automatiquement et le service devient disponible pour l'appel :

query {
   sum(x: 1, y: 2) 
}

Cela appellera le gestionnaire sumqui renverra le résultat :

3

Profilage et métriques des requêtes

Pour comprendre le fonctionnement du système et les demandes de profilage, nous avons implémenté le support du protocole OpenTracing. Le système peut envoyer des informations à la demande à des outils prenant en charge ce protocole, comme Zipkin, ce qui permettra de comprendre comment la requête a été exécutée :

Architecture et capacités de Tarantool Data Grid

Naturellement, le système fournit des métriques internes qui peuvent être collectées à l'aide de Prometheus et visualisées à l'aide de Grafana.

Déployer

Tarantool Data Grid peut être déployé à partir de packages RPM ou d'une archive, à l'aide d'un utilitaire de la distribution ou d'Ansible, il existe également un support pour Kubernetes (Opérateur Tarantool Kubernetes).

L'application qui implémente la logique métier (configuration, gestionnaires) est chargée dans le cluster Tarantool Data Grid déployé sous la forme d'une archive via l'interface utilisateur ou à l'aide d'un script via l'API fournie par nos soins.

Exemples d'applications

Quelles applications peuvent être créées à l'aide de Tarantool Data Grid ? En fait, la plupart des tâches commerciales sont liées d’une manière ou d’une autre au traitement, au stockage et à l’accès aux flux de données. Par conséquent, si vous disposez de flux de données importants qui doivent être stockés et accessibles en toute sécurité, notre produit peut vous faire gagner beaucoup de temps de développement et vous concentrer sur votre logique métier.

Par exemple, nous souhaitons collecter des informations sur le marché immobilier, afin d'avoir par exemple à l'avenir des informations sur les meilleures offres. Dans ce cas, nous mettrons en évidence les tâches suivantes :

  1. Les robots qui collectent des informations à partir de sources ouvertes seront nos sources de données. Vous pouvez résoudre ce problème en utilisant des solutions toutes faites ou en écrivant du code dans n'importe quel langage.
  2. Ensuite, Tarantool Data Grid acceptera et enregistrera les données. Si le format des données provenant de différentes sources est différent, vous pouvez alors écrire du code dans Lua qui effectuera la conversion vers un format unique. Au stade du prétraitement, vous pourrez également, par exemple, filtrer les offres en double ou mettre à jour en outre les informations sur les agents travaillant sur le marché dans la base de données.
  3. Vous disposez désormais déjà d'une solution évolutive dans un cluster qui peut être rempli de données et effectuer des sélections de données. Ensuite, vous pouvez implémenter de nouvelles fonctionnalités, par exemple écrire un service qui fera une demande de données et proposera l'offre la plus avantageuse par jour - cela nécessitera quelques lignes dans le fichier de configuration et un peu de code Lua.

Quelle est la prochaine?

Notre priorité est d'améliorer la facilité de développement en utilisant Grille de données Tarantool. Par exemple, il s'agit d'un IDE prenant en charge les gestionnaires de profilage et de débogage exécutés dans un bac à sable.

Nous accordons également une grande attention aux questions de sécurité. Nous sommes actuellement en cours de certification par le FSTEC de Russie pour confirmer le haut niveau de sécurité et répondre aux exigences de certification des produits logiciels utilisés dans les systèmes d'information sur les données personnelles et les systèmes d'information gouvernementaux.

Source: habr.com

Ajouter un commentaire