2 points par GN⁺ 2024-01-11 | 1 commentaires | Partager sur WhatsApp
  • La source de la complexité du backend ne vient pas tant des défauts d’un produit particulier que du fait que la structure conceptuelle maintenue depuis longtemps par les bases de données continue de contraindre la conception des applications
  • Les bases de données fonctionnent comme un état global mutable et imposent aux développeurs de gérer un modèle de données figé, un schéma limité, ainsi que la tension entre normalisation et dénormalisation
  • L’alternative proposée consiste à combiner event sourcing et vues matérialisées afin de séparer les données sources et les vues d’index, et de traiter les index comme des structures de données durables plutôt que comme un modèle de données
  • Rama de Red Planet Labs réunit sur une seule plateforme la collecte, le traitement, l’indexation, les requêtes, ainsi que le déploiement et la supervision, via les depots, les ETL, les PStates et les query topologies
  • Dans un cas de réimplémentation de Mastodon à l’échelle de Twitter, Rama aurait permis une implémentation en 10k lignes de code et 9 homme-mois, contre 1M de lignes et environ 200 homme-années pour le produit grand public comparable de Twitter

Le point de départ de la complexité des bases de données

  • Le problème ne porte pas sur l’API d’un produit de base de données précis, ses difficultés d’exploitation ou ses limitations arbitraires, mais sur la structure conceptuelle collective qui perdure encore aujourd’hui
  • C’est lorsqu’une meilleure approche apparaît que les problèmes de l’ancienne deviennent évidents, et l’alternative proposée ici est la combinaison de event sourcing et des vues matérialisées

Les bases de données comme état global mutable

  • Les programmeurs apprennent à minimiser l’usage des variables globales, mais une base de données est elle aussi, fondamentalement, un état global mutable
  • Une base de données est, sous certains aspects, encore plus difficile à manipuler qu’une variable globale ordinaire
    • les interactions sont réparties entre plusieurs systèmes, ce qui rend l’état difficile à raisonner
    • l’état est durable, donc corriger un bug ne répare pas automatiquement les données corrompues
    • il peut être difficile d’identifier précisément l’étendue de la corruption ou de la corriger parfaitement
    • revenir à une sauvegarde ou fusionner une partie d’une sauvegarde n’est pas une solution optimale
  • Avec l’event sourcing et les vues matérialisées, on peut recalculer les vues à partir du journal source, ce qui ouvre la possibilité de corriger un état d’index corrompu

Les limites d’un modèle de données figé

  • Les bases de données sont conçues autour de modèles de données tels que key/value, document, relationnel, orienté colonnes ou graphe
  • Comme un seul modèle de données supporte difficilement tous les cas d’usage, les entreprises utilisent souvent plusieurs bases de données à la fois
  • Une abstraction d’index plus générale n’est pas un modèle de données, mais une structure de données
    • Key/value : map
    • Document : map of maps
    • Relationnel : map of maps, les index secondaires étant des maps supplémentaires
    • Orienté colonnes : map of sorted maps
  • Les structures de données durables sont stockées sur disque, peuvent devenir très volumineuses et permettent aussi de représenter des structures imbriquées
  • Si l’on définit les index comme des combinaisons de structures de données, on peut produire non seulement les modèles de données existants, mais aussi des formes d’index bien plus variées
  • Si l’on peut adapter la forme du stockage au modèle de domaine, au lieu de tordre le modèle de l’application pour l’ajuster à la base de données, la complexité fondamentale diminue

La tension entre normalisation et dénormalisation

  • Les utilisateurs de bases relationnelles finissent inévitablement par devoir choisir entre normalisation et dénormalisation
  • Un stockage normalisé crée une source de vérité claire et réduit les risques d’incohérence, mais l’augmentation des jointures peut accroître le coût des requêtes
  • Lorsque les mêmes informations sont stockées de plusieurs façons pour des raisons de performance, un bug peut créer des incohérences de données
  • L’architecture des SGBDR fusionne dans le même datastore la source de vérité et le stockage d’index destiné à accélérer les requêtes
  • La solution consiste à séparer explicitement ces deux rôles
    • un sous-système représente la source de vérité
    • un autre sous-système matérialise autant de stockages d’index que souhaité à partir de cette source
    • si ce second système peut recalculer les index à partir des données sources, il peut corriger les incohérences

Schémas limités et représentation du domaine

  • Les bases de données diffèrent fortement selon les types de valeurs qu’elles permettent de stocker
    • certaines n’acceptent que des blobs comme des byte arrays
    • d’autres autorisent plusieurs types, comme les entiers, les nombres à virgule flottante, les chaînes ou les dates
  • Il est rare qu’elles stockent les objets du domaine comme une représentation de première classe permettant d’interroger ou d’agréger directement les informations imbriquées qu’ils contiennent
  • Le langage d’implémentation de la base de données diffère de celui de l’application, ce qui complique l’interopérabilité, et des extensions comme l’extension protobuf pour Postgres restent lourdes et limitées
  • Les ORM font le lien entre la représentation du domaine et celle de la base, mais l’abstraction peut fuir et causer des problèmes
  • Si l’on doit indexer les données différemment de la représentation idéale du domaine, il faut écrire du code d’adaptation, et cela peut aussi limiter les requêtes exécutables efficacement

Déploiements complexes et modèle à la carte

  • Un backend complet ne se compose pas d’une seule base de données, mais nécessite généralement de nombreux outils : base de données, système de traitement, outils de supervision, ordonnanceur, etc.
  • Un backend de grande taille peut exiger l’assemblage de dizaines d’outils, et une mise à jour applicative devient alors une orchestration de migrations, de mises à jour de code et de changements d’infrastructure
  • Une mise en production exige une télémétrie suffisante, mais comme chaque outil collecte différemment ses données, les regrouper dans un tableau de bord unique constitue un travail d’ingénierie à part entière
  • Le mode de développement dominant aujourd’hui ressemble à un modèle à la carte, où l’on choisit l’outil optimal pour chaque partie de l’architecture
  • Faire fonctionner ensemble des outils conçus indépendamment est déjà un travail important, et les modèles de données figés ainsi que les schémas limités conduisent plus souvent à adapter l’application aux outils que l’inverse
  • Faute de modèle cohérent pour construire un backend, l’approche à la carte s’est imposée ; avec un modèle cohérent, les possibilités d’abstraction, d’automatisation et de réutilisation deviennent bien plus grandes

Un modèle simple pour penser le backend

  • Les fonctions principales d’un backend sont de recevoir de nouvelles données et de répondre à des questions sur ces données
  • La forme la plus générale d’une requête peut être exprimée comme l’exécution d’une fonction sur toutes les données reçues par le backend
    • query = function(all data)
  • En pratique, un dataset peut faire 10 PB et les réponses doivent parfois arriver en quelques millisecondes ; un système utilisable a donc besoin d’index
  • Le modèle avec index peut alors s’écrire ainsi
    • indexes = function(data)
    • query = function(indexes)
  • Les backends traditionnels implémentent les éléments de ce modèle à l’aide de plusieurs outils spécialisés et étroits
    • un backend fondé sur un SGBDR utilise ce SGBDR pour les données et les index, et peut ajouter une base distincte comme ElasticSearch pour l’indexation complémentaire
    • le calcul est souvent effectué dans des handlers de serveurs API ou dans des tâches d’arrière-plan basées sur des files et des workers
    • un backend à grande échelle peut combiner des outils comme Cassandra, MongoDB, Neo4j, Kafka, Hadoop, Storm ou Kafka Streams
  • La conclusion est que si un outil pouvait implémenter tous ces composants de manière intégrée et généraliste, il deviendrait possible d’éviter la complexité précédente

L’architecture de Rama et le cas Mastodon

  • Rama est une plateforme de développement backend conçue à partir de ces principes
  • Red Planet Labs a annoncé Rama le 15 août avec le slogan « the 100x development platform »
  • Comme exemple de réduction des coûts, l’entreprise présente une réimplémentation de Mastodon à l’échelle de Twitter
    • 100M de bots publient 3 500 fois par seconde
    • le fanout moyen est de 403
    • le produit grand public équivalent chez Twitter est comparé à une base de 1M de lignes de code et environ 200 homme-années
    • l’implémentation Rama aurait nécessité 10k lignes de code et 9 homme-mois
    • l’implémentation est open source et présentée comme complete, high-performance, production-ready
  • Pour atteindre cette échelle, Twitter avait construit en interne des bases spécialisées comme une social graph database et une in-memory timeline database, avec un déploiement complexe dont la seule configuration Puppet dépassait 1M de lignes
  • L’implémentation fondée sur Rama aurait résolu des problèmes comparables de performance et de scalabilité non pas en recréant une infrastructure spécialisée pour chaque sous-problème, mais en combinant les primitives de Rama
  • Les mesures de performance de l’implémentation Mastodon sont présentées comme égales ou supérieures à celles de Twitter

Le modèle de programmation de Rama

  • Les concepts de Rama correspondent directement au modèle de backend présenté plus haut
    • Depots : journaux distribués contenant des données arbitraires, correspondant à data
    • PStates : abréviation de partitioned state, correspondant aux index
    • ETLs : correspondant à function(data)
    • Queries : correspondant à function(indexes)
  • Les PStates peuvent être définis en autant d’exemplaires que nécessaire, sous forme de combinaisons arbitraires de structures de données durables
  • Les ETL et les queries s’expriment via une API de dataflow Turing-complete, avec exécution distribuée des calculs
  • Rama fournit une documentation avec tutoriel pour l’API Java, et propose aussi une API Clojure

Comment Rama réduit la complexité des bases de données

  • Les PStates de Rama jouent un rôle proche de celui d’une base de données, mais ne peuvent être écrits que depuis la topologie ETL qui possède ce PState
    • comme toutes les écritures passent par le même code ETL, il devient plus simple de raisonner sur l’état
    • les PStates fonctionnent comme des vues matérialisées au-dessus d’un journal event-sourced
    • les données des depots étant la source de vérité, les PStates peuvent être recalculés
  • Les contraintes du modèle de données sont traitées en définissant les PStates comme des structures de données
    • l’implémentation Mastodon utilise déjà 33 PStates rien que pour les profils, les statuts et les timelines
    • certains PStates couvrent 10 cas d’usage, d’autres n’en supportent qu’un seul
  • Les PStates ont des propriétés durables, partitionnées et répliquées de manière incrémentale
    • la réplication incrémentale signifie qu’en cas de panne d’une partition leader, une autre partition est prête à prendre le relais
    • ce qui est visible sur le leader actuel est garanti visible sur le leader suivant
  • Le problème normalisation/dénormalisation est traité par une séparation explicite entre depots et PStates
  • Le problème des schémas limités est atténué en utilisant directement la représentation du domaine
    • des structures de données générales comme hash map ou list
    • Protocol Buffers
    • des définitions d’objets imbriqués
    • pour les types inconnus de Rama, l’enregistrement d’un custom serializer permet de les gérer

Déploiement, intégration et supervision

  • Les applications Rama sont appelées modules, et un module peut contenir plusieurs depots, ETL, PStates et query topologies
  • Rama fournit des mécanismes intégrés pour déployer, mettre à jour et faire évoluer un module, chacun étant, selon l’entreprise, exécutable en one-liner dans le terminal
  • Rama n’est pas un outil « all or nothing » : il a été conçu pour s’intégrer facilement avec d’autres systèmes, ce qui permet une adoption progressive dans une architecture existante
  • En tant que plateforme intégrée, Rama assure aussi sa propre supervision
    • collecte des données de monitoring
    • traitement
    • indexation
    • visualisation
  • La cluster UI telemetry sert à comprendre les performances d’un module, détecter et diagnostiquer les problèmes, et décider quand monter en capacité

Apprentissage et voie d’adoption

1 commentaires

 
GN⁺ 2024-01-11
Commentaires Hacker News
  • « Je l’expliquerai plus tard, mais une meilleure approche est l’event sourcing et les vues matérialisées » : donc, au final, la solution serait d’augmenter la complexité ? Évidemment

    • Si c’est bien fait, cela simplifie au contraire fortement l’architecture backend. Même les applications de petite taille utilisent souvent plusieurs bases de données comme Postgres et ElasticSearch, avec une file de tâches en arrière-plan et des workers
      Notre implémentation de Mastodon à l’échelle de Twitter en est un exemple direct. Pour offrir les mêmes fonctionnalités à grande échelle, elle contient littéralement 100 fois moins de code que ce que Twitter a dû écrire, et plus de 40 % de code en moins que l’implémentation officielle de Mastodon. Ce n’est pas simplement parce qu’on l’a mieux conçue à la deuxième tentative avec les mêmes outils, mais parce qu’on l’a construite sur une abstraction fondamentalement meilleure
    • La complexité ne disparaît pas, elle se déplace ailleurs. Pour beaucoup de tâches, le compromis de cette solution peut être mauvais
      Cela dit, au-delà d’une certaine échelle, tout devient un problème de data engineering, et dans le contexte du système global, cette approche peut devenir une solution relativement simple. Le conseil « utilisez simplement mySQL/SQLite/Postgres » est excellent, jusqu’au moment où il ne l’est plus
    • Plus de complexité ? L’auteur a rendu cela très simple. Il suffit d’utiliser son produit, Rama
    • Dans toutes les entreprises où j’ai travaillé, event sourcing + vues matérialisées ont mené à une confusion extrême, davantage de bugs et des pannes plus longues. Des solutions plus simples comme MySQL ou PostGres, ou encore Redis/DynamoDB, ont toujours mieux fonctionné
      Je crois sincèrement que tout le monde s’en porterait mieux si le billet original de Martin Fowler sur l’event sourcing n’avait jamais été écrit. À mon avis, c’est une mauvaise idée dans 99 % des cas
    • Si le domaine du programme exige une complexité intrinsèque X, il faut de toute façon implémenter cette complexité. On peut soit la confier au code de quelqu’un d’autre, déjà écrit et éprouvé en production, soit tout reconstruire soi-même ; la seconde option prend beaucoup de temps et peut donner un résultat pire. Il n’y a pas de repas gratuit
  • J’ai peut-être raté quelque chose, mais l’article semble passer complètement à côté de notions comme la concurrence, l’isolation et les contraintes. Et ce « topologie de requête » n’a rien de déclaratif ; on dirait qu’on transfère à l’auteur la responsabilité du plan de requête et de l’optimisation. C’est vraiment censé être une meilleure expérience développeur ?

    • Tout cela est largement traité dans la documentation. Cet article parle de la complexité du développement backend et de la manière dont Rama la traite ; il ne vise pas à expliquer exhaustivement tous les aspects de Rama. Tout couvrir le rendrait beaucoup trop long. En creusant davantage Rama, on voit que ses propriétés et garanties sont très solides
      Et oui, l’approche de requête de Rama est de loin supérieure. Si l’on a besoin d’un planificateur de requêtes complexe, c’est souvent à cause des limites de la manière dont les données sont indexées, notamment de la tension entre normalisation et dénormalisation. Avec Rama, il est facile de matérialiser de façon robuste plusieurs vues déjà préparées dans la forme nécessaire aux requêtes
      Voici un tutoriel qui introduit en douceur les concepts de Rama : https://redplanetlabs.com/docs/~/tutorial1.html
  • À propos de l’affirmation selon laquelle « aucun modèle de données unique ne peut prendre en charge tous les cas d’usage » : en théorie, il n’existe aucun domaine ni ensemble fini de domaines qui ne puisse pas être modélisé avec précision sous forme de tuples et de relations
    En pratique, la portée d’une base de données / d’un schéma donné se limite généralement à une seule activité ou à un seul domaine de problème, mais cela ne pose pas vraiment de difficulté tant que les types ne se chevauchent pas de manière inappropriée. Avec des noms bien choisis, on peut tout à fait faire cohabiter un détaillant web et une compagnie d’assurance dans le même schéma
    Mettre absolument tout dans une seule base de données est un superpouvoir. La principale raison pour laquelle j’y tiens autant, c’est pour éviter les transactions distribuées entre plusieurs stockages de données. Si toute l’activité se déroule dans un seul système transactionnel, la sémantique devient radicalement plus simple

    • Je suis particulièrement d’accord avec l’idée que « tout mettre dans une seule base de données est un superpouvoir »
      Dès que les gens commencent réellement à utiliser les données, un gros serveur DB à 1 million de dollars revient bien moins cher qu’un empilement redondant de bases de données bon marché. Développeurs, analystes et direction y gagnent tous du temps ; peut-être à l’exception de certains DBA
    • Les grandes bases de données, ce n’est pas nouveau. Si c’était toute l’histoire, les gens auraient continué à fonctionner ainsi pendant les 40 dernières années. Or ça n’a pas toujours marché, et parfois c’était franchement terrible
      Même si, en théorie, c’était tout ce qu’il fallait, un autre problème persistant reste l’implémentation. Aujourd’hui, la plupart des développeurs comprennent mal le fonctionnement des bases de données et la manière de les utiliser, donc ils les utilisent très mal. C’est pour échapper à cette réalité qu’on a créé de nouvelles bases de données comme NoSQL, en essayant de moins réfléchir et d’écrire simplement plus de code de raccord. Là aussi, les résultats se sont révélés désastreux
      Bientôt, la tendance repartira dans l’autre sens et « une seule grosse base de données » cessera à nouveau d’être à la mode ; un autre paradigme de la « simplicité » apparaîtra. Comme à l’époque des microservices, on pourra considérer que « beaucoup de petites bases de données » est plus simple que « une seule grosse base de données ». Si l’on ne comprend pas l’histoire, on est condamné à la répéter
    • Dire qu’un cas d’usage peut être modélisé avec des tuples et des relations ne signifie pas que la base de données pourra satisfaire les exigences de performance de ce cas d’usage. Si elle ne peut pas respecter ces exigences, alors ce cas d’usage n’est pas pris en charge
      C’est comme en programmation en général : aucune structure de données, ni combinaison de structures de données, ne peut répondre à tous les cas d’usage. Parfois il faut une map, parfois une liste, un ensemble, une combinaison, ou quelque chose de complètement différent
    • Je suis d’accord avec l’idée que « tout mettre dans une seule base de données est un superpouvoir ». Dans mon entreprise précédente, c’était une configuration de microservices cargo cult, avec une DB distincte pour chaque application, et c’était devenu inutilement complexe et coûteux sans aucun bénéfice métier. Pour garnir le CV, il y avait sans doute un avantage, certes. Il ne faut pas introduire de complexité avant d’y être contraint
    • L’idée est séduisante, presque magnifique, mais en pratique ça ne fonctionne pas. Y a-t-il quelqu’un qui y soit réellement parvenu ? Si on pousse le raisonnement à l’extrême, cela revient à dire qu’il faudrait une base de données unifiée pour le monde entier et un seul système de permissions utilisateur
      Bien sûr, les structures de données sont diverses, les performances sont indispensables, et cela devient un goulot d’étranglement tellement critique que le grand public ne peut pas y toucher et que chaque changement doit être extrêmement sûr. Il y a aussi la sécurité. Que se passe-t-il si quelqu’un trouve un moyen de passer d’une section de bugs de développement à une section RH ou à une section financière réservée aux cadres ? Quiconque a déjà implémenté un système ERM généraliste sait à quel point les systèmes unifiés sont difficiles et douloureux
      Cela dit, c’est un cas extrême. Je me demande jusqu’où les gens sont allés en poursuivant cet idéal, et comment ils s’y sont pris. Je n’ai jamais vu d’entreprise fonctionner sur un seul système. Et pour la gestion des connaissances personnelles ? Est-ce que tout y entre vraiment ? N’utilise-t-on pas encore des feuilles de calcul pour les tâches rapides, et des fichiers texte pour le contenu libre ?
  • On dirait un assortiment de mots à la mode. Je travaille sur des bases de données depuis des années dans l’une des plus grandes entreprises du monde, et je n’ai jamais entendu le mot topologie
    Même s’il y a du temps à économiser ici, il sera perdu à apprendre Java et ce framework. Il n’y a aucun problème avec la base de données elle-même

    • Il existe pourtant une implémentation Mastodon prête pour la production qui offre des fonctionnalités équivalentes à l’échelle de Twitter avec 100 fois moins de code que celui écrit par Twitter ; j’ai donc du mal à être d’accord avec l’idée que ce n’est qu’un « assortiment de mots à la mode » : https://github.com/redplanetlabs/twitter-scale-mastodon
    • Pour moi, cela ressemble à un exemple de ce genre de publicité
      J’avais essayé de faire ici un tableau en texte, mais l’affichage de la page a été complètement détruit, donc je poste une capture d’écran : https://imgur.com/a/XtwSkyx
  • Comment expliquer Rama à un enfant de cinq ans ? Même la doc m’a embrouillé : https://redplanetlabs.com/docs/~/index.html
    J’aimerais qu’on évite les mots à la mode comme « changement de paradigme » ou « plateforme ». S’il faut un diagramme, je préférerais lire un texte qui l’explique plus clairement

    • C’est une plateforme de développement backend capable de gérer, à n’importe quelle échelle, les besoins d’une application en collecte, traitement, indexation et requêtes de données. Au lieu de construire un backend en mélangeant plusieurs bases de données, systèmes de traitement, files et ordonnanceurs, on peut tout faire dans une seule plateforme, Rama
      Rama s’exécute en cluster, et plusieurs applications y sont déployées sous forme de « modules ». Une télémétrie profonde et détaillée est intégrée
      Le modèle de programmation de Rama repose sur l’event sourcing et les vues matérialisées. Lorsqu’on crée une application Rama, on matérialise autant d’index que nécessaire, dans la forme voulue, en combinant plusieurs structures de données persistantes. Les index sont matérialisés via une API de flux de données distribués
      Rama est tellement différent de ce qui existe déjà que c’est à peu près l’explication de haut niveau la plus claire que je puisse donner. La meilleure ressource pour apprendre les bases est rama-demo-gallery, qui contient des exemples courts, détaillés, commentés et entièrement fonctionnels montrant comment appliquer Rama à différents cas d’usage. Tout est scalable et tolérant aux pannes : https://github.com/redplanetlabs/rama-demo-gallery
    • D’après ce que j’en comprends, c’est une architecture Kappa, donc une variante de l’event sourcing
      Il y a un journal d’événements en append-only supplémentaire appelé « Depot », sur lequel on construit des vues arbitraires appelées « P-States ». Le logiciel Rama promet des mises à jour à faible latence de ces vues. Les applications construites dessus interrogent les vues et soumettent de nouveaux événements/commandes au Depot
    • Ça ressemble à une base de données en event sourcing. En gros, au lieu d’écrire directement, on écrit des messages, et on peut construire des tables en lecture seule qui se mettent à jour en fonction de ces messages. On fait déjà ça dans certains domaines, mais c’est clairement plus complexe qu’une base de données traditionnelle
    • On dirait une nouvelle tentative de NoSQL. « Mais cette fois, c’est différent ! »
  • J’ai passé un an sur un projet consistant à construire un moteur flexible de vues matérialisées au-dessus d’un jeu de données d’événements live de 1 à 10 To, et avant de passer sur un autre projet, notre architecture conver­geait elle aussi vers l’idée de déplacer le code là où se trouve l’index
    Rama m’attire pas mal, mais pour une raison complètement irrationnelle, je ne pense pas que je l’adopterais à cause de la JVM. Je n’aime tout simplement pas Java/la JVM. J’aimerais voir cette architecture portée dans un autre environnement

  • Au travail, on sépare le modèle de lecture et le modèle d’écriture. Le modèle d’écriture, c’est-à-dire la source de vérité, est un modèle de domaine relationnel traditionnel avec ses invariants/contraintes, et je pense qu’il n’est pas difficile à appréhender pour la plupart des développeurs habitués aux ORM
    Presque toutes les commandes produisent aussi des événements, publiés dans une file partagée d’événements métier. Le modèle de lecture est construit par des workers qui consomment ces événements et fabriquent chacun des vues selon leurs besoins, qu’ils peuvent aussi reconstruire. Par exemple, le service de gestion des utilisateurs est la source de vérité, et d’autres services construisent, comme services de vue pour des interfaces complexes, leurs propres modèles de lecture/index à partir des événements du service utilisateur et d’autres services. Sans ça, il aurait fallu d’énormes jointures ou des appels d’API inter-services lents
    Techniquement, on peut rejouer les événements. On a d’ailleurs déjà rejoué les trois dernières années d’événements à cause d’un bug dans le code de la plateforme. Mais j’ai l’impression qu’on n’en a presque jamais réellement besoin. Il arrive qu’il faille reconstruire une vue à cause d’un bug, mais en général on le traite avec un script ad hoc ou un programme temporaire de type migration SQL. Je ne sais pas exactement comment appeler notre architecture, et je n’ai jamais entendu personne parler d’« event sourcing »
    Au final, c’est du vieux MySQL + RabbitMQ avec un peu de code glue. Cela dit, pour bien faire les choses, ce n’est pas si trivial à cause de la transaction outbox, des garanties de livraison au moins une fois, de la cohérence éventuelle, du maintien du bon ordre de traitement des événements, du partitionnement des données d’événements, de l’administration de la base, de la gestion des pannes des event handlers, etc. Comme c’est déjà une configuration éprouvée en production et indépendante du langage, avec des producteurs/consommateurs en PHP et en Go, je me demande ce qu’on rate sans Rama, et comment Rama résout les problèmes listés ci-dessus. Rama semble plus orienté Java

    • On dirait que vous avez conçu une excellente façon de gérer la complexité tout en restant sur un SGBDR. Rama apporte quelques éléments supplémentaires par-dessus
      Les index de Rama sont bien plus flexibles. Par exemple, il est trivial d’avoir un ensemble imbriqué contenant 100 millions d’éléments. Un exemple courant est un index de graphe social du type ID utilisateur → ensemble des IDs de followers. De la même manière, un index de séries temporelles découpé par granularité, du type entité → granularité → bucket temporel → statistiques, est simple à mettre en place
      Il n’y a aucune restriction sur les types de données stockés dans Rama. Les requêtes Rama sont très puissantes, et les requêtes distribuées en temps réel, à la demande, sur une partie ou la totalité des index sont faciles. Une télémétrie profonde et détaillée à l’échelle de l’application est aussi intégrée, sans rien à construire ni maintenir séparément
      Le déploiement est également intégré. Avec votre approche actuelle, une mise à jour applicative peut toucher plusieurs systèmes — code des workers, migrations de schéma, etc. — et devient un vrai travail d’ingénierie, surtout si vous voulez du zéro interruption. Rama intègre calcul et stockage de bout en bout, donc publier, mettre à jour et faire monter en charge une application tient en une seule ligne dans le terminal
      Rama est bien plus scalable. Voilà Rama du point de vue des fonctionnalités, mais il est difficile d’exprimer à quel point l’absence d’impedance mismatch change la donne quand on code avec ; il faut l’essayer pour s’en rendre compte. Comme Rama tourne sur la JVM, on peut l’utiliser avec n’importe quel langage JVM, et il fournit aujourd’hui des API Java et Clojure
    • Pour une commande comme « mettre à jour l’adresse client », vous exécutez du SQL puis un trigger du SGBDR envoie l’événement vers RabbitMQ, ou bien l’ORM envoie le SQL puis publie sur RabbitMQ ?
      Où et sous quel format stockez-vous les événements ?
      J’aimerais en entendre davantage
      Ce qui manque, on dirait, c’est surtout un joli nom à accoler à tout l’écosystème
  • Matérialiser les données au moment des modifications peut être avantageux lorsque le produit doit faire une seule chose très rapidement. Mais dès qu’apparaissent des transactions complexes qui doivent être mises à jour ensemble via des écritures atomiques, ou qu’on veut ajouter une nouvelle fonctionnalité nécessitant d’organiser les données autrement, cela devient problématique
    J’ai aussi trouvé très peu satisfaisante la façon désinvolte dont la partie sur la construction d’applications balaie cela d’un « il suffit d’ajouter un index ». Un index est un état global ; il a simplement été déplacé d’une couche vers le bas

    • Justement parce qu’« il a simplement été déplacé d’une couche vers le bas », il n’est plus nécessaire de le gérer directement. Il suffit d’indiquer au système ce qu’il faut indexer. Ce n’est ni de l’état ni des données, c’est du code
  • Même en lisant ce document, il n’est pas clair qui est le public visé ni quel problème on cherche à résoudre : https://redplanetlabs.com/docs/~/why-use-rama.html#gsc.tab=0
    Il serait utile de prendre un cas concret et de montrer à quel point c’est simple et efficace de le transformer avec RAMA

    • De nombreux exemples ont été publiés
      Le premier est une implémentation de Mastodon à l’échelle de Twitter, avec 100 fois moins de code que celui écrit par Twitter pour construire la même chose à grande échelle. Cela concerne uniquement le produit grand public. Il y a aussi plus de 40 % de code en moins que l’implémentation officielle de Mastodon, qui n’est pas extensible : https://github.com/redplanetlabs/twitter-scale-mastodon
      Le dépôt rama-demo-gallery contient également de nombreux exemples courts, autonomes et abondamment commentés qui appliquent Rama à des cas d’usage très différents. Cela inclut la gestion de profils utilisateurs, l’analyse de séries temporelles, ainsi que des virements bancaires atomiques et tolérants aux pannes : https://github.com/redplanetlabs/rama-demo-gallery
  • À moins d’exploiter réellement un site web avec 40 millions d’utilisateurs quotidiens, il ne semble pas possible d’affirmer que cela a été prouvé avec un « client Mastodon à l’échelle de Twitter ». Il est impossible de simuler un environnement réel, les changements de code et d’infrastructure qui l’accompagnent, de vrais utilisateurs, l’utilisation réseau, etc.