Reddit passe de Python à Go : Retour d'expérience sur une migration à grande échelle

Reddit passe de Python à Go : Retour d'expérience sur une migration à grande échelle

Quand une plateforme servant des centaines de millions d'utilisateurs décide de réécrire ses systèmes critiques, chaque décision technique a des conséquences massives. Reddit vient de franchir une étape majeure : la migration de son backend de commentaires, l'un de ses systèmes les plus sollicités, d'un monolithe Python vers des microservices Go. Résultat : une latence divisée par deux et des pics de 15 secondes qui appartiennent désormais au passé.

Le contexte : un monolithe Python à bout de souffle

Reddit existe depuis 2005. Comme beaucoup de startups de cette époque, la plateforme a été construite sur Python, un choix pragmatique pour itérer rapidement. Deux décennies plus tard, ce monolithe Python gère toujours quatre modèles de données critiques : Comments, Accounts, Posts et Subreddits. Ces quatre entités alimentent la quasi-totalité des fonctionnalités de Reddit.

Le système de commentaires représente un défi particulier. Avec des millions de commentaires créés chaque jour, des threads pouvant atteindre des dizaines de milliers de réponses, et des pics de trafic imprévisibles lors d'événements viraux, les performances sont cruciales. Or, le monolithe Python montrait ses limites : des latences p99 atteignant parfois 15 secondes sur les opérations d'écriture critiques.

Pour les utilisateurs, cela se traduisait par des commentaires qui mettaient une éternité à apparaître, des erreurs lors des pics de trafic, et une expérience globalement dégradée sur les threads populaires.

Pourquoi Go plutôt qu'une optimisation Python ?

Architecture avant/après : du monolithe Python aux microservices Go
Architecture avant/après : du monolithe Python aux microservices Go

La question mérite d'être posée : pourquoi ne pas simplement optimiser le code Python existant ? Reddit a choisi Go pour plusieurs raisons fondamentales.

La concurrence native

Go a été conçu dès l'origine pour la programmation concurrente. Ses goroutines, des threads légers gérés par le runtime Go, permettent de traiter des milliers de requêtes simultanées avec une empreinte mémoire minimale. Le scheduler Go distribue automatiquement ces goroutines sur tous les cœurs disponibles.

Python, malgré les améliorations récentes comme la suppression du GIL dans Python 3.14, reste fondamentalement limité pour le parallélisme CPU-bound. Les benchmarks récents montrent des écarts considérables : sur une charge de calcul répartie sur 4 cœurs, Go complète l'opération en 3 secondes là où Python en prend 394.

Les performances brutes

Go est un langage compilé qui produit des binaires natifs. Python est interprété. Cette différence architecturale se traduit par des performances jusqu'à 30 fois supérieures pour Go sur certaines charges de travail.

Pour Reddit, l'équipe infrastructure a constaté qu'à débit équivalent, Go nécessitait significativement moins de pods Kubernetes que Python. Moins de pods signifie moins de coûts cloud, moins de complexité opérationnelle, et une meilleure utilisation des ressources.

Un modèle de déploiement simplifié

Un binaire Go est autonome et ne nécessite aucune dépendance externe. Pas de virtualenv à gérer, pas de conflits de versions de packages, pas d'interpréteur à maintenir. Le déploiement devient trivial : un seul fichier à copier.

La stratégie de migration : tap-compare

Stratégie tap-compare : validation parallèle sans impact utilisateur
Stratégie tap-compare : validation parallèle sans impact utilisateur

Reddit n'a pas basculé d'un coup. L'équipe a développé une méthodologie rigoureuse appelée "tap-compare" pour valider chaque étape de la migration sans risquer l'intégrité des données.

Phase 1 : Migration des lectures

La première étape a consisté à réécrire tous les endpoints de lecture en Go. Ces nouveaux services ont été déployés en parallèle du monolithe Python, sans remplacer ce dernier.

Le principe du tap-compare : une portion du trafic de production est envoyée simultanément aux deux systèmes. Les réponses sont comparées automatiquement, mais seules les réponses Python sont renvoyées aux utilisateurs. Cette approche permet de détecter les divergences en conditions réelles sans impact utilisateur.

Phase 2 : Validation des écritures

Pour les opérations d'écriture, la validation est plus complexe. Reddit a créé des environnements miroirs avec PostgreSQL, Memcached et Redis configurés identiquement à la production. Chaque écriture Go était validée contre 18 chemins distincts, couvrant trois endpoints différents et trois datastores.

Cette rigueur a permis de détecter des problèmes subtils avant qu'ils n'affectent les utilisateurs.

Phase 3 : Bascule progressive

Une fois la confiance établie, le trafic a été progressivement migré vers les services Go. D'abord 1%, puis 10%, puis 50%, avec une surveillance continue des métriques.

Les défis techniques rencontrés

La migration n'a pas été sans obstacles. L'équipe Reddit a documenté plusieurs défis significatifs.

Incompatibilités de sérialisation

Le premier problème majeur : les services Python ne parvenaient pas à désérialiser les données écrites par Go. Les formats internes, bien que nominalement identiques, présentaient des différences subtiles dans l'encodage.

La solution a impliqué la mise en place de consommateurs CDC (Change Data Capture) pour valider que chaque événement écrit par Go pouvait être correctement lu par les systèmes downstream, qu'ils soient en Python ou en Go.

Pression sur les bases de données

Le monolithe Python utilisait un ORM qui générait des requêtes optimisées au fil des années. Les services Go, écrivant directement en SQL, ont initialement créé une charge plus importante sur les bases de données.

Ce phénomène d'amplification d'écriture a nécessité des optimisations au niveau des requêtes : batching, indexation ciblée, et révision des patterns d'accès aux données.

Conditions de course pendant le tap-compare

Un problème particulièrement vicieux est apparu lors des tests tap-compare sur les écritures. Entre le moment où Go écrivait une donnée et celui où le système comparait avec Python, des écritures Python légitimes pouvaient survenir, faussant la comparaison.

L'équipe a résolu ce problème en améliorant les tests locaux avec des jeux de données dérivés de la production, permettant de valider le comportement avant d'activer le tap-compare en production.

Les résultats : des gains mesurables

Résultats de la migration : latence p99 divisée par deux
Résultats de la migration : latence p99 divisée par deux

Les chiffres parlent d'eux-mêmes. Katie Shannon, ingénieure senior chez Reddit, résume les résultats :

La latence p99 des opérations d'écriture critiques (création, mise à jour, incrémentation) a été divisée par deux. Les pics de 15 secondes qui affectaient régulièrement le système Python ont disparu.

Au-delà des métriques techniques, les utilisateurs ont remarqué la différence. Les commentaires apparaissent instantanément. Les threads populaires restent réactifs même pendant les pics de trafic. Les temps d'arrêt lors des événements majeurs ont drastiquement diminué.

Impact opérationnel

Moins de pods pour le même débit signifie des économies substantielles sur les coûts cloud. L'équipe n'a pas communiqué de chiffres précis, mais d'autres migrations similaires, comme celle de Repustate, ont montré des réductions de 85% du nombre d'instances EC2 nécessaires.

La nouvelle architecture simplifie également la chaîne de dépendances du système de commentaires tout en maintenant les garanties de livraison d'événements pour les systèmes downstream.

État actuel et prochaines étapes

À ce jour, deux des quatre modèles critiques ont été entièrement migrés : Comments et Accounts. Les migrations de Posts et Subreddits sont en cours.

Une fois ces quatre migrations terminées, Reddit disposera d'une architecture de microservices moderne pour tous ses modèles de données fondamentaux. Cette base permettra de continuer la décomposition d'autres services et d'accélérer le développement de nouvelles fonctionnalités.

Leçons pour les équipes techniques

Cette migration offre plusieurs enseignements applicables à d'autres contextes.

Ne pas sous-estimer la validation

Le tap-compare a demandé un investissement significatif en infrastructure de test, mais il a permis de détecter des problèmes qui auraient été catastrophiques en production. Chaque heure passée sur la validation en a économisé des dizaines en debugging post-incident.

Migrer progressivement

La tentation de tout réécrire d'un coup est forte, mais dangereuse. En commençant par les lectures, puis en validant les écritures indépendamment, Reddit a minimisé les risques à chaque étape.

Anticiper les différences subtiles

Un ORM Python et des requêtes SQL directes en Go ne produisent pas les mêmes patterns d'accès aux données. Ces différences, invisibles au niveau fonctionnel, peuvent avoir des impacts majeurs sur les performances des bases de données.

Impliquer les utilisateurs dans la validation

Les retours utilisateurs ont confirmé les améliorations mesurées techniquement. Cette validation externe est précieuse pour justifier l'investissement et maintenir le momentum du projet.

Python vs Go : un faux débat ?

Cette migration ne signifie pas que Python est un mauvais choix. Python reste excellent pour le prototypage rapide, le machine learning, l'analyse de données, et de nombreux autres cas d'usage.

Le choix de Go par Reddit reflète les contraintes spécifiques d'un système à très haute charge nécessitant des latences minimales. Pour une startup en phase de validation, Python permettrait probablement d'itérer plus vite. Pour un système mature servant des centaines de millions d'utilisateurs, les gains de performance de Go justifient l'investissement de migration.

Le vrai enseignement est qu'il n'existe pas de solution universelle. Chaque système, à chaque étape de son évolution, mérite une évaluation pragmatique de ses besoins et contraintes.

Conclusion

La migration de Reddit illustre parfaitement les compromis inhérents aux choix technologiques. Un monolithe Python qui a permis de construire l'une des plateformes les plus influentes d'Internet atteint ses limites après deux décennies de croissance. Go offre les performances nécessaires pour la prochaine phase, mais au prix d'une migration complexe et coûteuse.

Pour les équipes techniques confrontées à des défis similaires, l'approche méthodique de Reddit, le tap-compare rigoureux, la migration progressive, l'attention aux détails de sérialisation, offre un modèle à suivre.

La question n'est pas de savoir si Python ou Go est "meilleur". C'est de comprendre quand et pourquoi passer de l'un à l'autre, et comment le faire sans mettre en péril un système en production servant des millions d'utilisateurs.

Reddit a répondu à cette question avec brio. Leur latence divisée par deux en témoigne.