Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Extrait du film « Notre univers secret : La vie cachée de la cellule »

L'activité d'investissement est l'un des domaines les plus complexes du monde bancaire, car il s'agit non seulement de prêts, d'emprunts et de dépôts, mais aussi de titres, de devises, de matières premières, de produits dérivés et de toutes sortes de complexités sous forme de produits structurés.

Récemment, nous avons constaté une augmentation des connaissances financières de la population. De plus en plus de personnes s'impliquent dans le trading sur les marchés de valeurs mobilières. Les comptes de placement individuels sont apparus il n'y a pas si longtemps. Ils vous permettent de négocier sur les marchés des valeurs mobilières et soit de bénéficier de déductions fiscales, soit d'éviter de payer des impôts. Et tous les clients qui font appel à nous souhaitent gérer leur portefeuille et consulter des reporting en temps réel. De plus, ce portefeuille est le plus souvent multiproduit, c'est-à-dire que les personnes sont clients de différents secteurs d'activité.

En outre, les besoins des régulateurs, russes et étrangers, augmentent.

Pour répondre aux besoins actuels et jeter les bases des futures mises à niveau, nous avons développé un cœur de métier d’investissement basé sur Tarantool.

Quelques statistiques. L'activité d'investissement d'Alfa-Bank fournit des services de courtage aux personnes physiques et morales pour offrir la possibilité de négocier sur divers marchés de valeurs mobilières, des services de dépôt pour le stockage de titres, des services de gestion fiduciaire pour les personnes physiques à capital privé et important, des services d'émission de titres pour d'autres sociétés. . Les activités d'investissement d'Alfa-Bank comprennent plus de 3 300 cotations par seconde, téléchargées à partir de diverses plateformes de trading. Au cours d'une journée de travail, plus de 5 XNUMX transactions sont conclues sur les marchés pour le compte de la banque ou de ses clients. Jusqu'à XNUMX XNUMX exécutions d'ordres par seconde ont lieu sur des plateformes externes et internes. Dans le même temps, tous les clients, internes et externes, souhaitent connaître leurs positions en temps réel.

Préhistoire

Dès le début des années 2000, nos domaines d'activité d'investissement se sont développés de manière indépendante : opérations boursières, services de courtage, négoce de devises, négoce de gré à gré de valeurs mobilières et de divers produits dérivés. Du coup, nous sommes tombés dans le piège des puits fonctionnels. Ce que c'est? Chaque secteur d’activité dispose de ses propres systèmes qui dupliquent les fonctions de chacun. Chaque système possède son propre modèle de données, bien qu'ils fonctionnent avec les mêmes concepts : transactions, instruments, contreparties, cotations, etc. Et à mesure que chaque système évoluait indépendamment, un zoo diversifié de technologies a émergé.

En outre, la base de code des systèmes est déjà assez obsolète, car certains produits sont nés au milieu des années 1990. Et dans certains domaines, cela a ralenti le processus de développement et il y a eu des problèmes de performances.

Exigences pour une nouvelle solution

Les entreprises ont compris que la transformation technologique est vitale pour poursuivre leur développement. On nous a confié des tâches :

  1. Collectez toutes les données commerciales dans un stockage unique et rapide et dans un modèle de données unique.
  2. Nous ne devons ni perdre ni modifier ces informations.
  3. Il est nécessaire de versionner les données, car à tout moment le régulateur peut demander des statistiques pour les années précédentes.
  4. Nous ne devons pas simplement introduire de nouveaux SGBD à la mode, mais créer une plate-forme permettant de résoudre les problèmes des entreprises.

De plus, nos architectes fixent leurs propres conditions :

  1. La nouvelle solution doit être de classe entreprise, c'est-à-dire qu'elle doit déjà être testée dans certaines grandes entreprises.
  2. Le mode de fonctionnement de la solution doit être critique pour la mission. Cela signifie que nous devons être présents simultanément dans plusieurs centres de données et survivre sereinement à la panne d'un centre de données.
  3. Le système doit être évolutif horizontalement. Le fait est que tous nos systèmes actuels ne sont évolutifs que verticalement et que nous atteignons déjà le plafond en raison de la faible croissance de la puissance matérielle. Par conséquent, le moment est venu où nous avons besoin d’un système évolutif horizontalement pour survivre.
  4. Entre autres choses, on nous a dit que la solution devait être bon marché.

Nous avons suivi le parcours standard : nous avons formulé les besoins et contacté le service achats. De là, nous avons reçu une liste d’entreprises qui, en général, sont prêtes à le faire pour nous. Nous avons parlé du problème à tout le monde et avons reçu une évaluation des solutions de six d'entre eux.

À la banque, nous ne croyons personne sur parole, nous aimons tout tester nous-mêmes. Par conséquent, une condition obligatoire de notre appel d’offres était de réussir les tests de charge. Nous avons formulé des tâches de test de charge, et trois entreprises sur six ont déjà accepté de mettre en œuvre à leurs frais un prototype de solution basé sur des technologies en mémoire afin de le tester.

Je ne vous dirai pas comment nous avons tout testé et combien de temps cela a pris, je vais juste résumer : les meilleures performances dans les tests de charge ont été montrées par un prototype de solution basé sur Tarantool de l'équipe de développement du groupe Mail.ru. Nous avons signé un accord et commencé le développement. Il y avait quatre personnes du groupe Mail.ru et d'Alfa-Bank trois développeurs, trois analystes système, un architecte de solution, un propriétaire de produit et un Scrum master.

Ensuite, je vais vous raconter comment notre système s'est développé, comment il a évolué, ce que nous avons fait et pourquoi exactement cela.

Développement

La première question que nous nous sommes posée était de savoir comment obtenir les données de nos systèmes actuels. Nous avons décidé que HTTP nous convenait parfaitement, car tous les systèmes actuels communiquent entre eux en envoyant XML ou JSON via HTTP.

Nous utilisons le serveur HTTP intégré à Tarantool car nous n'avons pas besoin de mettre fin aux sessions SSL et ses performances nous suffisent.

Comme je l'ai déjà dit, tous nos systèmes vivent dans des modèles de données différents, et en entrée, nous devons amener l'objet au modèle que nous décrivons nous-mêmes. Il fallait un langage permettant de transformer les données. Nous avons choisi l'impératif Lua. Nous exécutons tout le code de conversion de données dans un bac à sable - c'est un endroit sûr au-delà duquel le code en cours d'exécution ne va pas. Pour ce faire, nous chargeons simplement le code requis, créant ainsi un environnement avec des fonctions qui ne peuvent rien bloquer ou supprimer.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Après la conversion, la conformité des données avec le modèle que nous créons doit être vérifiée. Nous avons longuement discuté de ce que devrait être le modèle et du langage à utiliser pour le décrire. Nous avons choisi Apache Avro car le langage est simple et il bénéficie du support de Tarantool. Les nouvelles versions du modèle et du code personnalisé peuvent être mises en service plusieurs fois par jour, même sous charge ou sans, à tout moment de la journée, et s'adapter très rapidement aux changements.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Après vérification, les données doivent être sauvegardées. Nous faisons cela en utilisant vshard (nous avons des répliques géo-dispersées de fragments).

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
De plus, la spécificité est telle que la plupart des systèmes qui nous envoient des données ne se soucient pas de savoir si nous les avons reçues ou non. C'est pourquoi nous avons mis en place une file d'attente de réparation dès le début. Ce que c'est? Si, pour une raison quelconque, un objet ne subit pas de transformation ou de vérification des données, nous confirmons toujours la réception, mais enregistrons en même temps l'objet dans la file d'attente de réparation. Il est cohérent et situé dans l’entrepôt de données principal de l’entreprise. Nous avons immédiatement écrit une interface d'administrateur pour celui-ci, diverses métriques et alertes. De ce fait, nous ne perdons pas de données. Même si quelque chose a changé dans la source, si le modèle de données a changé, nous le détecterons immédiatement et pourrons nous adapter.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Vous devez maintenant apprendre à récupérer les données enregistrées. Nous avons soigneusement analysé nos systèmes et constaté que la pile classique de Java et Oracle contient nécessairement une sorte d'ORM qui convertit les données relationnelles en objets. Alors pourquoi ne pas donner immédiatement des objets aux systèmes sous la forme d'un graphe ? Nous avons donc adopté avec plaisir GraphQL, qui répondait à tous nos besoins. Il vous permet de recevoir des données sous forme de graphiques et d'extraire uniquement ce dont vous avez besoin pour le moment. Vous pouvez même versionner l’API avec beaucoup de flexibilité.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Presque immédiatement, nous avons réalisé que les données que nous extrayions n’étaient pas suffisantes. Nous avons créé des fonctions qui peuvent être liées aux objets du modèle – essentiellement des champs calculés. Autrement dit, nous attachons une certaine fonction au champ, qui, par exemple, calcule le prix moyen du devis. Et le consommateur externe qui demande les données ne sait même pas qu'il s'agit d'un champ calculé.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Implémentation d'un système d'authentification.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Nous avons alors remarqué que plusieurs rôles se sont cristallisés dans notre décision. Un rôle est une sorte d’agrégateur de fonctions. En règle générale, les rôles ont différents profils d'utilisation de l'équipement :

  • T-Connect : gère les connexions entrantes, processeur limité, faible consommation de mémoire, sans état.
  • IB-Core : transforme les données qu'il reçoit via le protocole Tarantool, c'est-à-dire qu'il fonctionne avec des tables. Il ne stocke pas non plus l’état et est évolutif.
  • Stockage : stocke uniquement les données, n’utilise aucune logique. Ce rôle implémente les interfaces les plus simples. Évolutif grâce à vshard.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Autrement dit, en utilisant des rôles, nous avons découplé les différentes parties du cluster les unes des autres, qui peuvent être mises à l'échelle indépendamment les unes des autres.

Nous avons donc créé un enregistrement de flux de données transactionnels asynchrone et une file d'attente de réparation avec une interface d'administration. L'enregistrement est asynchrone d'un point de vue commercial : si nous sommes assurés d'écrire des données sur nous-mêmes, peu importe où, alors nous le confirmerons. Si cela n’est pas confirmé, quelque chose s’est mal passé et les données doivent être envoyées. Il s'agit de l'enregistrement asynchrone.

Test

Dès le début du projet, nous avons décidé d'essayer de mettre en œuvre un développement piloté par les tests. Nous écrivons des tests unitaires en Lua en utilisant le framework tarantool/tap et des tests d'intégration en Python en utilisant le framework pytest. Parallèlement, nous impliquons à la fois les développeurs et les analystes dans la rédaction des tests d'intégration.

Comment utilisons-nous le développement piloté par les tests ?

Si nous voulons une nouvelle fonctionnalité, nous essayons d’abord d’écrire un test pour celle-ci. Lorsque nous découvrons un bug, nous nous assurons d’écrire d’abord un test, puis de le corriger seulement. Au début, c'est difficile de travailler ainsi, il y a des incompréhensions de la part des salariés, voire du sabotage : « Réparons ça vite maintenant, faisons quelque chose de nouveau, puis couvrons-le de tests. Seulement, ce « plus tard » n’arrive presque jamais.

Par conséquent, vous devez d’abord vous forcer à passer des tests et demander aux autres de le faire. Croyez-moi, le développement piloté par les tests apporte des avantages même à court terme. Vous sentirez que votre vie est devenue plus facile. On estime que 99% du code est désormais couvert par les tests. Cela semble beaucoup, mais nous n'avons aucun problème : des tests sont exécutés à chaque commit.

Cependant, ce que nous aimons le plus, ce sont les tests de charge, nous les considérons comme les plus importants et les effectuons régulièrement.

Je vais vous raconter une petite histoire sur la façon dont nous avons réalisé la première étape de test de charge de l'une des premières versions. Nous avons installé le système sur l'ordinateur portable du développeur, allumé la charge et obtenu 4 XNUMX transactions par seconde. Bon résultat pour un ordinateur portable. Nous l'avons installé sur un banc de charge virtuel de quatre serveurs, plus faible qu'en production. Déployé au minimum. Nous l'exécutons et nous obtenons un résultat pire que sur un ordinateur portable dans un seul thread. Contenu choc.

Nous étions très tristes. Nous examinons la charge du serveur, mais il s'avère qu'ils sont inactifs.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Nous appelons les développeurs, et ils nous expliquent, à nous qui venons du monde Java, que Tarantool est monothread. Il ne peut être utilisé efficacement que par un seul cœur de processeur sous charge. Ensuite, nous avons déployé le nombre maximum possible d'instances Tarantool sur chaque serveur, activé la charge et déjà reçu 14,5 mille transactions par seconde.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Laissez-moi vous expliquer à nouveau. En raison de la division en rôles qui utilisent les ressources différemment, nos rôles chargés du traitement des connexions et de la transformation des données ne chargeaient que le processeur, et strictement proportionnel à la charge.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Dans ce cas, la mémoire n'était utilisée que pour traiter les connexions entrantes et les objets temporaires.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Au contraire, sur les serveurs de stockage, la charge du processeur a augmenté, mais beaucoup plus lentement que sur les serveurs traitant les connexions.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Et la consommation de mémoire a augmenté en proportion directe avec la quantité de données chargées.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool

Services

Pour développer notre nouveau produit spécifiquement en tant que plate-forme d'application, nous avons créé un composant permettant d'y déployer des services et des bibliothèques.

Les services ne sont pas de simples petits morceaux de code opérant sur certains champs. Il peut s'agir de structures assez volumineuses et complexes qui font partie d'un cluster, vérifient les données de référence, exécutent la logique métier et renvoient des réponses. Nous exportons également le schéma de service vers GraphQL, et le consommateur reçoit un point d'accès universel aux données, avec introspection sur l'ensemble du modèle. C'est très confortable.

Étant donné que les services contiennent beaucoup plus de fonctions, nous avons décidé qu'il devrait y avoir des bibliothèques dans lesquelles nous déplacerions le code fréquemment utilisé. Nous les avons ajoutés à l'environnement sécurisé, après avoir vérifié au préalable que cela ne casse rien pour nous. Et maintenant, nous pouvons attribuer des environnements supplémentaires aux fonctions sous forme de bibliothèques.

Nous voulions avoir une plateforme non seulement pour le stockage, mais aussi pour l'informatique. Et comme nous avions déjà un tas de répliques et de fragments, nous avons implémenté une sorte d'informatique distribuée et l'avons appelé map réduire, car il s'est avéré similaire à la réduction de carte originale.

Anciens systèmes

Tous nos systèmes existants ne peuvent pas nous appeler via HTTP et utiliser GraphQL, bien qu'ils prennent en charge le protocole. Par conséquent, nous avons créé un mécanisme permettant de répliquer les données dans ces systèmes.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Si quelque chose change pour nous, des déclencheurs uniques sont déclenchés dans le rôle de stockage et le message avec les modifications se retrouve dans la file d'attente de traitement. Il est envoyé à un système externe à l’aide d’un rôle de réplicateur distinct. Ce rôle ne stocke pas l'état.

Nouvelles améliorations

Comme vous vous en souvenez, d'un point de vue business, nous faisions de l'enregistrement asynchrone. Mais ensuite, ils ont réalisé que cela ne suffirait pas, car il existe une classe de systèmes qui doivent recevoir immédiatement une réponse sur l'état de l'opération. Nous avons donc étendu notre GraphQL et ajouté des mutations. Ils s'intègrent organiquement dans le paradigme existant du travail avec les données. Pour nous, il s'agit d'un point unique de lecture et d'écriture pour une autre classe de systèmes.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Nous avons également réalisé que les services seuls ne nous suffiraient pas, car il y a des rapports assez lourds qui doivent être construits une fois par jour, par semaine, par mois. Cela peut prendre beaucoup de temps et les rapports peuvent même bloquer la boucle d'événements de Tarantool. Par conséquent, nous avons créé des rôles distincts : planificateur et exécuteur. Les coureurs ne stockent pas l’état. Ils exécutent des tâches lourdes que nous ne pouvons pas calculer à la volée. Et le rôle planificateur surveille le calendrier de lancement de ces tâches, qui est décrit dans la configuration. Les tâches elles-mêmes sont stockées au même endroit que les données métiers. Le moment venu, le planificateur prend la tâche, la confie à un coureur, qui la compte et enregistre le résultat.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Toutes les tâches ne doivent pas nécessairement être exécutées selon un calendrier. Certains rapports doivent être lus sur demande. Dès que cette exigence arrive, une tâche est créée dans le bac à sable et envoyée au coureur pour exécution. Après un certain temps, l'utilisateur reçoit une réponse asynchrone indiquant que tout a été calculé et que le rapport est prêt.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Au départ, nous avons adhéré au paradigme consistant à stocker toutes les données, à les versionner et non à les supprimer. Mais dans la vie, il arrive de temps en temps de devoir supprimer quelque chose, principalement des informations brutes ou intermédiaires. Sur la base de expirationd, nous avons créé un mécanisme pour nettoyer le stockage des données obsolètes.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool
Nous comprenons également que tôt ou tard, une situation viendra où il n'y aura pas assez d'espace pour stocker des données en mémoire, mais les données doivent néanmoins être stockées. À ces fins, nous réaliserons bientôt un stockage sur disque.

Comment nous avons construit le cœur de l'activité d'investissement d'Alfa-Bank basé sur Tarantool

Conclusion

Nous avons commencé par charger les données dans un modèle unique et avons passé trois mois à le développer. Nous disposions de six systèmes de fourniture de données. L'ensemble du code de transformation en un seul modèle représente environ 30 XNUMX lignes en Lua. Et l’essentiel du travail est encore à faire. Parfois, il y a un manque de motivation de la part des équipes voisines, et de nombreuses circonstances compliquent le travail. Si jamais vous êtes confronté à une tâche similaire, alors multipliez par trois, voire quatre, le temps qui vous semble normal pour sa mise en œuvre.

N'oubliez pas non plus que les problèmes existants dans les processus métier ne peuvent pas être résolus à l'aide d'un nouveau SGBD, même très productif. Ce que je veux dire? Au début de notre projet, nous avons donné l'impression aux clients que nous allons désormais apporter une nouvelle base de données rapide et que nous vivrons ! Les processus iront plus vite, tout ira bien. En fait, la technologie ne résout pas les problèmes des processus métiers, car les processus métiers sont des personnes. Et vous devez travailler avec les gens, pas avec la technologie.

Le développement piloté par les tests peut être pénible et prendre beaucoup de temps au début. Mais son effet positif sera perceptible même à court terme, lorsque vous n’aurez rien à faire pour effectuer des tests de régression.

Il est extrêmement important d’effectuer des tests de charge à toutes les étapes du développement. Plus tôt vous remarquerez un défaut dans l'architecture, plus il sera facile de le corriger, ce qui vous fera gagner beaucoup de temps à l'avenir.

Il n'y a rien de mal avec Lua. Tout le monde peut apprendre à écrire dedans : développeur Java, développeur JavaScript, développeur Python, front-end ou back-end. Même nos analystes écrivent là-dessus.

Quand nous parlons du fait que nous n'avons pas SQL, cela terrifie les gens. « Comment obtenir des données sans SQL ? Est-ce possible? Certainement. Dans un système de classes OLTP, SQL n'est pas nécessaire. Il existe une alternative sous la forme d'une sorte de langage qui vous ramène immédiatement à une vue orientée document. Par exemple, GraphQL. Et il existe une alternative sous la forme de l’informatique distribuée.

Si vous comprenez que vous devrez évoluer, concevez votre solution sur Tarantool de manière à ce qu'elle puisse s'exécuter en parallèle sur des dizaines d'instances Tarantool. Si vous ne le faites pas, ce sera difficile et douloureux plus tard, car Tarantool ne peut utiliser efficacement qu'un seul cœur de processeur.

Source: habr.com

Ajouter un commentaire