Tech.Rocks Summit 2021

D'un hack au data mesh, l'évolution du data engineering chez leboncoin

Tech.Rocks Summit 2021 · 9 décembre 2021 · 24 min · en français

Résumé

Avec 30 millions d'utilisateurs uniques par mois, leboncoin a dû faire considérablement évoluer ses pratiques data depuis son lancement en 2006 pour accompagner la croissance vertigineuse de sa plateforme. Entre galères, zombies, data engineering et data mesh, retour sur un parcours qui n'a pas été de tout repos.

Summary

With 30 million unique users a month, leboncoin has had to evolve its data practices considerably since its launch in 2006 to keep up with the dizzying growth of its platform. Between hardships, zombies, data engineering and data mesh, a look back at a journey that was anything but easy.

Thèmes : Data

Page du Tech.Rocks Summit 2021

Transcript complet

Transcription automatique, à relire : les noms propres peuvent être mal orthographiés.

Bonjour, c'est Simon, architecte chez Le Bon Coin, et on se retrouve tout de suite. J'ai le plaisir d'accueillir Simon Maurin, qui est lead architecte chez Leboncoin. Bonjour Simon. Bonjour. Alors Simon, vous allez nous expliquer comment l'architecture data évolue en fonction de la croissance d'une entreprise. Je vais essayer en tout cas. Tout un programme. Merci. Bonjour, je suis ici pour vous parler de l'évolution du data engineering chez Le Bon Coin et comment, en l'espace de 15 ans, on est passé d'un hack à une approche data mesh. Le Bon Coin, c'est un site de petites annonces qui a été créé en 2006. Qui est devenu leader sur son marché en 2010 et qui a acquis de nombreuses boîtes. C'est une boîte tech qui grossit beaucoup et dont l'organisation et l'architecture doivent évoluer sans cesse.

Moi, je m'appelle Simon Maurin, je suis leader architecte, j'ai rejoint Le Bon Coin en 2012. En tant que développeur BI, je suis ensuite passé data engineer. Avant de prendre mon poste actuel. Et donc, l'histoire que je vais vous conter, c'est aussi un petit peu la mienne. Je vous propose du coup de revenir en 2012, quand je suis rentré dans la boîte. La stack du data du bon coin, c'était ça. un script shell qui allait ficher les données dans la base de l'applicatif, qui allait greffer les logs, qui mettait tout ça tous les jours dans un petit mail, qui envoyait ça au marketing, et les gens du marketing faisaient une agrégation manuelle de tout ça dans un Excel de 143 slides. Autant vous dire que c'est une approche qui avait ses limites. Et au bout de cinq ans, tout ce système-là, c'était devenu une sorte de plat de spaghettis infâme, assez instable, très fragile et qui mettait parfois la prod d'Alfnou. Et donc, il a fallu débrancher ce monstre. Qu'est-ce qu'on a essayé de mettre à la place?

Une stack de BI, by the book, classique. On a construit une app ETL qui allait chercher les données dans les bases des logiciels de prod. Stocker la partie utile, faisait des transformations, la chargeait dans un data warehouse, et au-dessus de ça, on avait mis une solution de BI qui permettait aux gens du marketing, justement, de pouvoir fouiller dans les données de façon interactive. Ça les a satisfaits, ils ont pu commencer à... Faire des analyses plus poussées, ainsi de suite. Mais assez vite, la fête a été gâchée par le fait que cette stack ne scale pas assez. Déjà à l'époque, le Boncoin, c'était 800 000 nouvelles annonces par jour, des dizaines de millions de vues. Même en utilisant tous les outils, outils à notre disposition pour ce qu'elle est. Donc on a mis des grosses machines, on a multi-threadé, on est allé chercher des systèmes de bases de données optimisées, on a joué sur leur conf, on sautait un mur pour s'en prendre un autre.

Et donc, on est finalement arrivé à la conclusion, au bout de trois ans, qu'on avait créé un second monstre qu'il allait falloir débrancher à son tour. On a pris un petit peu de temps pour essayer de formaliser ce qu'on allait construire ensuite. Et ça a été le deuxième chapitre de notre histoire, donc toute la partie data platform. Cette data platform, avant de se lancer tête bêche dans sa réalisation, on a voulu se donner trois objectifs concrets. Le premier, dépasser les problèmes d'échelle. Le deuxième, assurer sa réutilisabilité. On ne voulait pas se contenter de faire un système de BI à l'échelle, mais on voulait vraiment créer un produit, une structure qui nous permette de faire des produits data-driven, donc d'aider le business ou de créer des produits en se servant de la donnée. Et on voulait augmenter la résilience du système pour arrêter d'être sur le pont tous les jours. Pour dépasser les problèmes d'échelle, on est passé en scaling horizontal, on est allé vers des technos de systèmes distribués, à la fois pour le stockage et à la fois pour le processing. Et on a aussi opté pour de l'élasticité, et du coup on est rentré.

Chez un cloud provider, Amazon en l'occurrence. Côté plateforme, pour assurer la réutilisabilité, des composants, mais on a décidé de les découpler. Donc on a découplé l'ingestion, de la partie stockage, de l'inventaire, de l'orchestration et des pipelines des différents systèmes finaux. Et on a opté pour un pattern de data lake, où plutôt que de stocker la donnée utile, on stocke toute la donnée qu'on peut extraire des systèmes sources pour l'avoir sous le coude et ne plus jamais les solliciter. Quant à la partie résilience du système, On a commencé par prendre un outil du marché pour faire l'orchestration plutôt que celui qu'on avait construit nous. Donc on a opté pour Airflow, qui est un soft qui avait été open sourcé cette année-là par Airbnb. C'est une admin web de gestion des workflows qui permet notamment de faire du auto-healing, de faire des opérations manuelles, d'assister, de visualiser les logs, tout ça sans avoir à se loguer sur les machines.

On a agrémenté ça aussi d'une partie monitoring via Datadog ici, où on a commencé à suivre l'état de nos infrastructures et nos chargements de façon un petit peu plus professionnelle. On a voulu s'assurer une rejouabilité totale et sans garantie d'or des paralysables. Et pour ça, on a imposé à l'ensemble de nos traitements d'être idem potent. Et on s'est satisfait d'avoir une vue dite éventuelle consistence sur l'ensemble de nos systèmes. Et donc concrètement, ce qu'on a construit, c'est ça, c'est-à-dire une stack où, si elle est de droite à gauche, les extracteurs ne sont que ça, des extracteurs qui viennent chercher la donnée RAW, la déposent sur le data lake qui est lui-même construit sur S3. On a notre système d'inventaire qui traque l'ensemble des nouvelles insertions. À côté de ça, on a un deuxième bloc logique dans lequel on a notre orchestrateur et nos ETL. L'orchestrateur, c'est Airflow, on en a déjà parlé. Notre outil d'ETL, c'est Spark, un outil de transformation.

de la donnée distribuée, et Datadog pour le monitoring. Et on top de ce second bloc, on pose les différents systèmes finaux, la BI d'une part qui est passée à l'échelle grâce à son passage sur une base distribuée qui est Redshift, et des solutions de CRM sur lesquelles on s'est intégré avec des outils qui nous ont permis de faire de l'aide à la vente, du targeting et des campagnes marketing. À partir de ce moment-là, on était assez contents, ça a même dépassé nos attentes en termes de stabilité et de facilité d'intégration. Et donc, on se dit qu'on allait pouvoir passer nos journées au barbe en face. Mais non. Parce qu'à ce moment-là, l'organisation nous a rattrapés. Donc, j'appelle que le bon coin, ça grossit. À un moment donné, on arrive à la limite de notre organisation en l'air technologique et on passe sur une organisation inspirée du modèle de Spotify en feature team. Et ce nouveau paradigme d'organisation nécessite le passage de l'architecture back-end d'un monolithe vers des microservices. Et là, on doit passer d'une base unique pour l'ensemble des métiers de la boîte à autant de bases de données que de services et donc que de domaines.

Et on se rend compte que notre technique d'alors, qui consiste à aller fêter les données directement en base, elle ne peut pas passer à l'échelle. D'autant plus que les développeurs back-end qui gèrent ces services, sont assez chatouilleux sur ce principe-là, cette dépendance. un petit peu implicite avec nos pipelines, ils la vivent assez mal parce que dès qu'ils changent quelque chose, ils sont susceptibles de les casser sans pour autant avoir de contrat d'interface. Et donc, ce qu'on choisit de faire, c'est de mettre à profit une des pièces d'infrastructure de l'ordre Nouvelle Archy, le bus d'événements, pour être l'interface entre eux et la data platform. Ça nécessite de discuter, de négocier sur ce qu'on va se donner comme règle autour de cette interface, vu qu'on va l'expliciter, on va essayer aussi d'en définir des contours qui soient les plus satisfaisants possibles pour les deux parties. Pour définir le contour de ces nouvelles interfaces, on écrit entre Dev Backend et Data Engineer

les nouvelles normes qui vont nous permettre de définir leur contour. On arrive à ces Boy's Cut Rules. La première règle qu'on établit, c'est que la responsabilité, le ownership de la data, il est dans le camp du producteur, dans les FT qui ont les domaines et qui opèrent le code. Ils doivent opérer, c'est ces équipes qui opèrent les binaires qui produisent les événements. Donc là, une fois qu'on a dit ça, on arrête complètement le... passage par les backdoors dans les BDB des copains, on n'a plus que des interfaces explicites. Ces équipes choisissent aussi le scope de leur événement, c'est-à-dire elles font la distinction entre ceux qui sont publics et qui sont concevables par tout le monde et ceux qui sont privés, dans lesquels il y a des internals propres à leur propre domaine. On acte que le bus d'événement, c'est une API qui doit être traitée pareil, tant en termes d'évolutivité que de réactivité sur les incidents, et que les...

ont les schémas qui vont nous permettre de porter les contrats. Pour tout public d'événements, on a les backends qui s'engagent à sérialiser en Avro, donc il y a un format de sérialisation bindé à un schéma. Assure la backward compatibility, avoir des squelettes communs pour s'assurer qu'on ait systématiquement un UID et des dates métiers formatées de la même façon. On opte aussi pour une minimalisation maximisée des contenus de ces événements, c'est-à-dire qu'on veut uniquement les infos du domaine, mais le maximum d'infos de ce domaine, donc pas les internals. On a des IDs vers les objets métiers des domaines externes, mais pour ce qui est des infos du domaine, on met tout ce qui peut être utile pour maximiser la réutilisabilité de ces événements, quitte à générer un petit peu plus de couplage. On insiste aussi pour que chaque schéma soit pleinement documenté champ par champ.

On définit des normes de naming et de typage et des normes de configuration du bus d'événement. Et donc, on passe de notre stack de batch qui ressemblait à ça, à ceci. Et donc, on voit qu'on a remplacé le fetch des données depuis la base du legacy par un interfaçage au-dessus du bus entre microservices et un archiveur qui va maintenant dépiler le bus dans le data lake. À ce moment-là, on nous tape sur l'épaule pour nous dire que toutes ces questions de tuyaux, c'est bien intéressant, mais qu'on avait promis de faire de l'argent au-dessus de tout ça. Et on avait peut-être même, à un moment donné, avancé les mots Big Data, Machine Learning, ainsi de suite. Et il est temps d'y aller. Et donc, on incrémente notre stack à ce moment-là d'un premier service de machine learning online. On construit un système de recommandation d'annonce pour les utilisateurs en fonction de leur parcours de navigation sur le site.

Donc ce service, il est à la fois lié à la partie batch de la stack, dans laquelle on rajoute toute la partie entraînement de modèle et serving, et à la partie bus d'événements, où il reçoit en temps réel les navigations des différents utilisateurs. À ce moment-là, on se dit que notre mission est accomplie et qu'on va pouvoir passer la rue et aller dans le bar d'en face pour boire des bières. Mais non, toujours pas. Pourquoi? L'orga, là encore, nous rattrape. Cette fois pour des raisons un petit peu différentes. On n'a pas changé de mode d'organisation, mais la croissance des effectifs est telle que le ratio entre les développeurs data qui sont restés en équipe centrale et les développeurs des feature teams, dont le nombre croît de façon assez exponentielle, parce que c'est justement un pattern qui permet la paralysation, Ce ratio évolue de plus en plus défavorable au data engineer. Là, vous voyez sur ce graphique la croissance des effectifs de la boîte à gauche et en bleu, avec l'échelle à gauche et la ligne en bleu, et la croissance des effectifs côté product and tech en vert.

Et vous voyez que par exemple, entre 2018 et 2019, ces effectifs ont doublé. Si bien que nos équipes data central, en fait, elles se retrouvent à être un bottleneck de l'organisation. Dès qu'on leur demande quelque chose, les temps de traversée des tâches et des tickets sont très très longs. Et donc à partir de ce moment-là, on se met à réfléchir à la façon dont on peut décentraliser les compétences data. En gros, on sait maintenant technologiquement construire des produits data-driven, maintenant on voudrait arriver à construire des produits data-driven à l'échelle de l'organisation. Et donc, pour ce faire, on s'intéresse à un concept qui vient tout juste de sortir à l'époque, dans un article écrit par Zamaq Degani, qui travaille pour Soswork, qui est le Data Mesh. Donc Zamaq, il fait le constat que l'organisation pour laquelle on a opté est partagée dans de nombreuses entreprises à travers le monde et qu'elle a un problème d'échelle.

Qui fait qu'on peut réussir à optimiser l'ingestion de la donnée et craquer les problèmes d'échelle technique, mais en gardant des écrits. centralisé, on limite forcément à un moment donné la réutilisabilité des données et des pièces technologiques qu'on a construites autour. Et donc, elle propose un modèle de data mesh qui est un modèle collaboratif, où grosso modo, on fait rentrer dans les feature teams des compétences de data engineering, et on outille ces équipes avec des plateformes qui abstraient toute une partie de la complexité, notamment autour de l'infrastructure data. Donc là, quelque part, on se retrouve un petit peu dans... DevOps 2, le retour. Et autre avantage de la méthode, ça permet de pousser le... Domain Driven Design, vraiment de bout en bout. C'est-à-dire qu'aujourd'hui, à ce moment-là, nos équipes métiers, nos feature teams, elles ont le code métier de leur domaine jusqu'à la data platform.

Là, on l'étendrait jusqu'à ce qu'elles aient justement leur propre code ETL et qu'elles puissent opérer et construire de bout en bout, sans cette rupture technologique au milieu de l'organisation. Pour le coup, on signe, on essaye d'aller dans cette direction. On a en plus un petit avantage, c'est que l'interopérabilité dans ce modèle, elle est permise notamment par un système de standards et de gouvernance globale que nous, en fait, on a déjà. On l'a écrit à la phase d'avant. On l'incrémente un petit peu, il s'est lui-même incrémenté de la partie privacy et de la partie security. Et là, on ajoute le fait qu'on va considérer aussi le data lake comme une API de la même façon que le bus. Mais au final, c'est quelque chose qu'on a déjà sur l'étagère. Sur la partie organisation, on va inclure des DE dans des feature teams, donc des data engineers dans les feature teams, et on va faire évoluer les équipes centrales vers des rôles de platform team, au sens team typologies, donc des équipes dont la mission, ça devient d'outiller les autres devs.

En 2019, on a une trentaine de FT, On ne vise pas de big bang, on commence donc à recruter des data engineers dans les FT qui ont les besoins les plus critiques et on laisse le temps au modèle d'émerger. À côté de ça, par contre, on va créer de nouvelles features teams autour de certains produits qui sont gérés par les équipes data centrales, comme la recommandation. Sur la partie tooling maintenant, là-dessus, on investit assez fortement. Sur quatre axes. Le premier, du coup, c'est l'infrastructure data en self-serve. Là-dessus, ce qu'on construit, c'est un data infra provisionneur, c'est un nom barbare, pour Un système qui est relativement simple, c'est un repo git avec une CI CD sur laquelle les développeurs vont venir poser des fichiers de conf descriptifs des infrastructures qu'ils veulent créer. Je dis infrastructure, mais en fait, en gros, c'est généralement des topiques Kafka.

En décrivant dedans la topologie du topic, est-ce que c'est un flux d'événements, est-ce que c'est une job queue, et ainsi de suite. Un t-shirt sizing, un scope privé-public, la partie schéma et les choix d'encoding, toute une partie de configuration sur la criticité au niveau privacy des données. Tout ça, c'est rattaché à un domaine et une équipe. Et on a aussi... toute la partie producteur et consommateur au sens applicatif, puisque notre data infra-provisionneur va, une fois qu'il a validé que la conf répond bien à l'ensemble des règles métiers qu'on s'est données, aller provisionner les infrastructures vers Kafka, vers le schéma registri, vers Vault pour la gestion des secrets et vers la partie archiver pour transférer le topic automatiquement sur le data lake. Donc ça c'est quelque chose qui a un impact vraiment fort sur le confort des devs au quotidien, surtout les bacs qui sont nombreux à ce moment-là déjà,

et pour qui rentrer dans les primitifs de Kafka, ce n'est vraiment pas une option. Donc là, on a mis une couche d'attraction qui fonctionne bien, de l'auto-provisioning, on on-force le respect des standards par le code, et tout ce qu'ils ont à sortir, c'est une configuration descriptive de ce qu'ils sont en train de faire. On propose aussi un outil de data discovery. C'est assez simple, il s'agit d'un moteur de recherche interne au-dessus de nos données. Le challenge ici, c'est d'arriver à agréger l'ensemble des sources, que ce soit les flux Kafka, les différents fichiers sur S3, ce qui existe et qui est raffiné dans le dataware. Et d'y lier la documentation, les méthodes d'attaque qu'on a vues un petit peu plus haut, de quel domaine il s'agit. de quelle équipe il s'agit, quelle est la criticité en termes de privacy, qui utilise, par qui c'est produit, et ainsi de suite. Donc ici, un petit screenshot du moteur et de lui.

On propose aussi de mettre sur l'étagère un outil de monitoring de la data quality. Donc, c'est finalement quelque chose d'assez simple. C'est des consumers sur lesquels on met... dans lesquels on met des règles métiers et qui les valident et remontent des métriques dans Datadog. De là, on peut calculer des SLO et ainsi de suite pour chaque flux qui sort. Et toute la partie provisionning est faite de façon transparente, c'est disponible sur l'étagère as a service. On construit des dashboards comme ça, au-dessus notamment des topics de sortie Kafka. Et ce qu'il y a d'assez sympa avec ça, c'est qu'on peut aussi l'orienter un petit peu en contract testing et donc avoir les consommateurs qui testent leurs assumptions sur les flux qu'ils consomment avant de construire des choses métiers au-dessus. Dernier type d'outil qu'on met sur l'étagère, on a commencé à rationaliser la partie pipeline de ML. Et donc, pour supporter toute la partie ML Ops, on met des outils qui vont permettre de gérer le versionning des modèles et des datasets, le contrôle des performances et d'intégrer tout ça à la CI CD.

C'est là où on est aujourd'hui. On n'a pas craqué cette notion de data mesh, on est au milieu du chemin. Je dirais presque qu'on a fait le plus simple, c'est-à-dire qu'on a créé les outils et on a adapté l'ORGA en partant de ce qu'on avait. Mais on a encore une grosse problématique qui est comment est-ce qu'on passe les compétences de data engineering véritablement à l'échelle. Alors bien sûr, il y a une solution simple, qui est le recrutement. Seulement aujourd'hui, on a 50 FT. Et donc, faire entrer 50 DE, ce n'est pas forcément quelque chose de complètement évident sur le marché. Et on a aussi certaines équipes, certains managers qui, tant qu'à avoir des recrutements, se demandent si un back-end engineer, ce n'est pas plus utilisable qu'un DE engineer pour lequel ils n'ont pas forcément un usage full-time en l'état. Et donc, nous, ce qu'on vise, c'est une convergence entre backend et data engineering.

Zamak, dans son article, parle de pollinisation des compétences. Moi, j'aime beaucoup ce mot-là, je le trouve très poétique. Elle montre avant qu'en mettant dans la même équipe des data engineers et des backend engineers, ils se tirent vers le haut mutuellement. Ils s'apportent des compétences les uns aux autres. Et nous, on a pu l'observer effectivement dans les équipes pour lesquelles on le fait. Et donc, ce qu'on veut faire maintenant, c'est catalyser cette pollinisation. Comment le faire? Alors, on va former tous les data engineers qui rentrent à la partie software craftsmanship, donc à toutes les bases du développement logiciel. Dès l'entrée. Et côté bac, tous les devs intéressés, on va leur proposer des formations sur la partie data engineering. Et on va aussi faire en sorte, ça s'est déjà commencé, que les comités de pratique interne, donc les guildes respectives, Bacen et Data, collaborent de la façon la plus proche possible et qu'on trouve des projets pilotes sur lesquels les faire atterrir ensemble.

Donc, on est en train de mettre tout ça sur rail. On sait déjà que ça va prendre du temps. On s'est fait à l'idée qu'on peut encore un peu attendre de bien. Je pense qu'on devrait y être vers 2023. J'ai fini, merci. Si vous avez des questions, je serai heureux de les prendre. Justement, ça va être le démarrage du live maintenant pour pouvoir répondre à toutes ces questions que la communauté vous a adressées. Je vous attends. Moi aussi.