Designing Data-Intensive Applications, une revue honnete
- #book review
- #data-engineering
- #distributed systems
- #Databases
- #System Design
- #Software Engineering
- #software development
- #Machine Learning
- #Devops
Chaque engineer a un livre achete parce qu’il revenait sans cesse dans les recommandations des autres.
Pour moi, c’etait Designing Data-Intensive Applications de Martin Kleppmann. Je m’attendais a une lecture lourde sur les internals de bases de donnees. J’ai trouve quelque chose de plus rare : un livre qui donne des noms precis a des problemes que j’avais deja vus a moitie en production, puis qui explique pourquoi ils arrivent.
Ce n’est pas un resume chapitre par chapitre. Kleppmann a deja ecrit le livre, et il le fait mieux. Voici plutot ce qui m’est reste, filtre par mon travail : pipelines data, systemes ML et l’architecture qui les relie.
Les idees que j’utilise chaque semaine
Decrire la charge avant de designer pour la scalabilite. La “scalabilite” ne veut rien dire tant que tu ne peux pas nommer les parametres de charge : lectures versus ecritures, fan-out, working set size, taux de cache hit, volume de donnees, request rate et attentes de latence.
C’est evident, et pourtant presque personne ne le fait assez rigoureusement.
Cela a change ma premiere question quand quelqu’un dit qu’un pipeline est “lent” : lent a faire quoi exactement ? Tres souvent, ecrire les parametres de charge repond deja a la question avant tout redesign.
Des percentiles, pas des moyennes. Le temps de reponse moyen est un mensonge confortable. Le p99 est souvent la ou vivent les vraies plaintes, parce que l’utilisateur avec le plus de donnees est souvent celui qui touche le slow path.
J’utilise les percentiles par defaut : dashboards de latence, temps d’inference modele, batch jobs avec stragglers, delais de queue et fraicheur des feature pipelines.
Les storage engines expliquent la personnalite d’une base. Le chapitre sur LSM-trees versus B-trees est celui que je recommande le plus.
Quand tu sais que PostgreSQL met a jour les pages in place alors que Cassandra append puis compacte, une classe entiere de documentation vendor cesse de ressembler a de l’incantation. Tu peux predire quelles operations seront probablement bon marche avant meme de benchmarker.
L’evolution de schema est un probleme de deploiement. La compatibilite forward et backward rend les rolling deploys possibles : le nouveau code lit les anciennes donnees, et l’ancien code survit aux nouvelles donnees.
Quiconque a casse un consumer en “ajoutant juste un champ” connait cette douleur. Le chapitre sur l’encodage justifie tres bien la ceremonie d’Avro ou Protobuf au lieu d’envoyer du JSON et d’esperer que tout le monde suive.
Le replication lag est une classe de bugs, pas un cas limite. Si un utilisateur sauvegarde un changement, rafraichit, puis le voit disparaitre, tu as rencontre l’incoherence read-after-write.
Avant ce livre, j’aurais traite cela comme un incident mysterieux. Maintenant, je reconnais toute la famille : stale reads, violations de monotonic reads, violations de causalite, et les petits choix UX qui peuvent cacher ou exposer ces problemes.
Une grande partie de mon travail est de la donnee derivee. Feature tables, embeddings, search indexes, caches, dashboards agreges : aucun n’est un system of record. Ce sont des vues derivees d’une verite upstream, et elles devraient etre reconstruisibles.
Le pipeline chunk-embed-index de mon projet MkDocs RAG est un systeme de donnee derivee classique. Une fois qu’on le voit ainsi, les priorites deviennent claires :
- Garder la source immutable ou versionnee.
- Rendre chaque transformation idempotente.
- Suivre la lineage entre source records et outputs derives.
- Traiter “puis-je tout retraiter depuis zero ?” comme une exigence forte.
Ce qu’on peut parcourir plus vite
Le materiel MapReduce est surtout historique aujourd’hui. Il vaut la peine pour les algorithmes de jointure, qui ont survecu au framework, mais la plupart des engineers n’ecriront pas directement des jobs MapReduce.
Les sections sur les fautes byzantines peuvent etre sautees sauf si tu travailles sur des systemes peer-to-peer, de l’infrastructure blockchain ou des environnements adversariaux similaires.
Le chapitre sur les transactions est excellent, mais il va plus loin dans les anomalies d’isolation que beaucoup d’application engineers n’en auront besoin au quotidien avec des bases managees. Je le lirais quand meme, lentement, avec un vrai systeme en tete.
Ce qui a bien vieilli
Le dernier chapitre, sur l’unbundling des bases de donnees, a vieilli dans le sens oppose au materiel MapReduce. Il ressemble a une prediction du modern data stack avant que celui-ci prenne sa forme actuelle.
Storage engines specialises, integration centree sur les logs, stream processors reliant les systemes, vues derivees optimisees pour differents access patterns : c’est une bonne description de ce que beaucoup d’equipes operent aujourd’hui.
C’est une raison pour laquelle le livre reste utile. Il n’est pas attache a un vendor ou a un framework. Il donne le vocabulaire sous les outils.
La partie honnete
J’utilise des services manages, comme presque tout le monde.
Je n’ai jamais opere un cluster leaderless de style Dynamo en colere, ni debugge une implementation Raft a 3h du matin. Lire sur le consensus n’est pas la meme chose que porter le pager. Une partie de la Part 2 restera theorique pour moi jusqu’au jour ou elle ne le sera plus.
Mais c’est precisement la valeur.
Le service manage fait ces choses pour moi, et le livre me dit quelles questions poser :
- Que se passe-t-il pendant un failover ?
- Quelles garanties de replication sont exposees ?
- Ce timestamp est-il vraiment monotone ?
- Quel modele de consistance voit l’application ?
- Que se passe-t-il quand un consumer prend du retard ?
- Puis-je reconstruire cette vue derivee depuis la source ?
Savoir que la mecanique existe, et a peu pres comment elle echoue, fait la difference entre lire la documentation vendor et simplement y croire.
Pourquoi cela compte pour la data et le ML
On decrit souvent ce livre comme un livre backend ou distributed systems. Il l’est, mais il est aussi tres pertinent pour la data et le ML engineering.
Les systemes ML modernes sont pleins de problemes data-intensive :
- Les donnees d’entrainement sont derivees de systemes operationnels.
- Les feature stores ont besoin de fraicheur et de reproductibilite.
- Les pipelines batch et streaming ont besoin d’attentes de consistance claires.
- Les embedding indexes doivent etre reconstruisibles et versionnes.
- Les sorties modele deviennent souvent des entrees pour des workflows downstream.
- Les tables analytics doivent conserver le sens business malgre les changements de schema.
Si ton travail touche aux pipelines data ou au ML en production, le livre donne un meilleur modele mental des systemes autour du modele.
Faut-il le lire ?
Oui, avec une strategie.
Lis la Part 1 attentivement. Elle paie tout le livre.
Lis la Part 2 lentement, idealement avec un vrai systeme en tete.
Lis la Part 3 pour la vision. C’est la que le livre se connecte le plus directement aux plateformes data modernes, aux pipelines ML, aux systemes de recherche et a la donnee derivee.
Puis garde-le a portee de main. C’est un livre de reference qui porte la veste d’un manuel, et son rendement augmente chaque fois qu’un probleme de production te renvoie vers un chapitre que tu pensais avoir termine.
Reference
Kleppmann, M. (2017). Designing Data-Intensive Applications. O’Reilly Media.
Page portfolio : Designing Data-Intensive Applications, Honestly Reviewed