Greboca  

LinuxFr.org : les journaux  -  Postgresql, un retour d'expérience

 -  Mai 2020 - 

Sommaire

Un petit peu de contexte

J'ai rejoint une grande banque asiatique, à Londres, il y a de cela 10 ans, pour travailler sur un de leurs systèmes, une grosse application financière en C++. Quelques années plus tard, les affaires n'ayant pas fonctionné comme prévu, ils décident de se débarrasser de l'équipe à laquelle j'appartenais. Heureusement, une petite institution financière européenne s'est montrée intéressée par le système et l'équipe, et plutôt que je devoir payer des indemnités de licenciement, mon ancien employeur était ravi de se débarrasser de nous à l’œil.

Ça se précise

On me charge de préparer la migration des données. Nous avons 2 bases:

  • Une base IBM DB2, qui contient surtout des données dites statiques, relatives aux produits financiers. Ça change un petit peu, mais pas tant que ça : quelques mises à jour le matin, et ça restera tel quel durant le jour.

  • Une autre base KDB, utilisée comme persistance pour une interface graphique qui affiche les ordres passés durant la journée. On parle de quelques centaines de milliers de changements durant la journée, et à la fin, on efface tout. Pour ceux qui ne connaissent pas KDB, il s'agit d'une base orientée colonnes. C'est très cher, et c'est horriblement moche : son concepteur avait une idée toute personnelle de la lisibilité du code, et a construit sa base de données autour d'un langage hyper concis, le langage q (le bien nommé). L'interface C de q (vous suivez ?) est une horreur Lovecraftienne bourrée de macros de 1 caractère. Mais tout le monde semble persuadé qu'une base SQL ne peut pas tenir les 200 000 transactions à la journée. Bon.

Mon nouvel employeur, lui, travaille avec Oracle, et n'est évidemment pas emballé de débourser une petite fortune pour ces technologies. Nous décidons donc de migrer les bases DB2 et KDB vers une base open source, et une fois arrivés de l'autre côté, de convertir depuis la base open source vers Oracle. Et on verra ce qu'il faut optimiser.

Je me lance donc tout d'abord dans la conversion de la base DB2 vers MySQL. Ouh là quelle catastrophe ! J'espère que les choses ont bien changé depuis, mais MySQL manque cruellement à l'époque de fonctionnalités plutôt basiques. J'ai beaucoup lutté avec les clés étrangères, l'indexage, la création de séquences ou les sous-requêtes.

Tournant en rond, je propose à ma hiérarchie d'utiliser Postgres, qui était plutôt plus touffu en termes de fonctionnalités, et que je connaissais mieux. En effet, ça se passe mieux, et j'ai une belle base qui fonctionne.

Pour KDB, c'est aussi facile, et, surprise (ou pas !), c'est tout aussi efficace.

Finalement, quand nous arrivons chez notre nouvel employeur, l'idée d'une base qui ne leur coûtera pas un rond en licences, pour un projet un peu risqué, leur semble une très bonne idée. Leurs DBAs sont réceptifs et prennent un consultant pendant quelques semaines histoire d'apprendre à installer et administrer une base Postgres. Nous décidons d'utiliser la réplication par envoi de journaux de transactions, afin d'avoir une base primaire dans un datacenter, une base secondaire dans l'autre datacenter, et de pouvoir utiliser la base secondaire pour effectuer des opérations en lecture seule.

Ce type de réplication fonctionne très bien, mais souffre d'un défaut: quand on dit que le secondaire de peut effectuer que des opérations en lecture seule, cela interdit la création de tables temporaires. Or, afin de lire rapidement des sous-ensemble de données, nous utilisons beaucoup une approche qui consiste à créer une table temporaire, y pousser les références des données qui nous intéresse, puis à faire une jointure de la table temporaire avec la table principale pour récupérer les lignes qui vont bien.

Or, nos analystes aimeraient bien étudier les donnés et faire tourner de grosses études qui peuvent prendre plusieurs jours, sans impacter les opérations temps réel. On finit par leur créer une base séparée dans laquelle on copie la base principale toutes les nuits, mais cela invalide les requêtes préparées au moment du rafraîchissement et cause des problèmes.

Finalement, après bien des années, nous changeons d'approche et utilisons les tableaux Postgres pour passer au sein de la procédure stockée la liste des données qui nous intéresse. On peut enfin fournir à nous analystes une autre base répliquée. Tout le monde est content !

Au fur et à mesure des années, la base grossit et devient de plus en plus temps réel, car nous l'utilisons pour la persistance de messages transmis entre les services ou avec l'extérieur. On est maintenant entre 500 et 2000 transactions par seconde. L'autre base, remplacement de KDB, fonctionne également sans accrocs. On finit même par manger un petit peu Oracle : nous recommandons Postgres pour la migration d'une gigantesque base OLAP, utilisée pour sauver tous les messages qui passent par le système (plusieurs millions par jour, quand même). C'est un peu de sport, mais la base fait maintenant plusieurs téraoctets, et reste tout à fait administrable.

Quelques remarques techniques à l'emporte-pièce

  • Postgres fournit une bibliothèque C, la libpq (la bien nommée), qui permet de transférer les données soit en mode texte, soit en mode binaire. Il existe également une bibliothèque C++, libpqxx, qui ne fonctionne qu'en mode texte. Finalement, et malgré les recommandations de se cantonner au mode texte, ce qui a marché le mieux pour nous est de construire une petite bibliothèque lourdement templatée autour de la libpq qui passe toutes les données au format binaire. C'est plus efficace, et beaucoup plus sûr, surtout avec des types plus complexes comme des types date heure et les tableaux. Certes, le format binaire est mal ou pas documenté, et il faut faire parfois du reverse engineering ou aller lire le source pour comprendre comment les tableaux sont envoyés, mais une fois que ça marche, c'est du solide.

  • Postgres est configuré par défaut pour de petites bases, et il nous a fallu pas mal de temps afin de vraiment comprendre quels paramètres changer pour obtenir la performance désirée avec nos volumétries. En particulier, nous avons clairement trop longtemps sous-dimensionné les autovacuum, qui sont les jobs de maintenance des tables. Sur de grosses bases, avec de gros serveurs avec des dizaines de CPU, des centaines de Go de RAM, et une baie de SSD derrière, il ne faut pas hésiter à rendre l'autovacuum bien plus agressif.

  • Les types tableaux de Postgres sont vraiment magiques. Ne pas en abuser, car cela casse le modèle relationnel, et l'on peut regretter plus tard de ne pas pouvoir l'indexer, mais parfois, cela permet de beaucoup se simplifier la vie.

  • Enfin, ce qui est vraiment plaisant, avec Postgres, c'est la cohérence du système, le fait que la base semble faite d'abord pour l'utilisateur:

    • Les changements de schéma sont transactionnels, pour de vrai, pour n'importe quel changement de schéma, et ça, il n'y en a pas beaucoup d'autres qui le font. Cela rend les mises à jour faciles et plaisantes: on lance le script, si on s'est trompé et qu'il s'interrompt avec une erreur, le rollback est complet, on a pas besoin de bidouiller à la main pour rattraper le coup.
    • Le type text est limité à un confortable 2Go, et marche exactement de la même manière que n'importe quel autre type. Par rapport aux autres bases qui donnent des limites ridiculement basses à leurs types texte et qui nous forcent à utiliser une structure différente genre blob ou bigtext, qui évidemment se gère différemment dans l'API C, ou ne peut pas s'indexer, ou ne peut pas faire partie de la clé primaire, ou que sais-je encore, quel bol d'air !

Quelques remarques non techniques, tout autant à l'emporte pièce

Postgres nous a donné des résultats incroyables parce que c'est une application d'une qualité rare, mais également parce que nous avons eu le soutien de notre hiérarchie et de l'équipe d'infrastructure, de vrais pros, enthousiastes à l'idée d'essayer quelque chose de nouveau, mais sans naïveté par rapport aux attentes et à l'effort à fournir : nous avons payé des consultants, nous avons pris un contrat de support chez un fournisseur tiers, les serveurs ont été correctement dimensionnés.

J'ai aussi fait attention à ne jamais forcer la main de qui que ce soit : j'ai fourni des prototypes, j'ai tenté de montrer les bons côtés de la solution open source, sans cacher les difficultés, et je ne me suis pas braqué lorsque les décisions sont allées à l'opposé de ce que je proposais. On s'est tous fait confiance, et ça s'est bien passé.

Commentaires : voir le flux atom ouvrir dans le navigateur

par small_duck

LinuxFr.org : les journaux

LinuxFr.org : Journaux

Regata OS 24 “Arctic Fox” avec KDE Plasma 6 et d'autres améliorations

 -  27 mars - 

Regata OS 24 “Arctic Fox” avec KDE Plasma 6 et d'autres améliorationsLa version 24 de Regata OS, baptisée "Arctic Fox", est une distribution basée (...)


Redis Open Source bronsonisé

 -  22 mars - 

Bonjour Nal.Désolé pour ce titre un peu putaclick. Personne n'est décédé cette fois ci.Juste Redis qui change de licence, passant de BSD3 a une (...)


PullRequest d'une application en Rust

 -  16 mars - 

Sommaire Le commencement Description du pool de stockage de BackupPC Le format des fichiers compressés Le format des fichiers d'attributs Le (...)


Jouons un peu avec linuxfr et CSS3

 -  16 mars - 

De temps en temps, j'ai besoin de me détendre, et je joue un peu avec les tech du web, entre deux déploiements.J'aime bien HTML5 et CSS, (...)


Traduction : Payer ne permet pas d'échapper aux monopoles

 -  6 mars - 

Sommaire Contexte Traduction ContexteAyant récemment découvert dans la section liens de LinuxFr le plus récent blog de C. Doctorow, le caractère (...)