Comment un fichier GIF a provoqué une défaillance de sauvegarde dans Discourse
Lors d'une sauvegarde d'un des forums sur la plateforme Discourse, un incident anormal s'est produit : le même fichier GIF de 1,6 Mo a été dupliqué 246 173 fois. Cela a fait gonfler la taille de la sauvegarde de 377 Go, corrompu le système de fichiers Linux et fait complètement planter le processus de sauvegarde. Le problème ne venait pas d'un bug dans le code, mais bien de l'architecture de sécurité de la plateforme et des limitations du système de fichiers ext4.
Pourquoi un fichier s'est transformé en des centaines de milliers de copies
Discourse utilise un mécanisme de « téléversement sécurisé » où, chaque fois qu'un fichier est déplacé entre différents contextes (p. ex., d'un message privé vers un message public), le système crée une nouvelle copie avec un hachage SHA1 unique. Bien que le contenu du fichier reste identique, la plateforme le traite comme un objet distinct. Cela est nécessaire pour appliquer les politiques de sécurité et empêcher l'accès non autorisé aux fichiers multimédias.
Dans le cas de ce GIF populaire — la Rachel dansante de la série TV Friends —, les utilisateurs l'ont inséré à répétition dans divers sujets, commentaires et messages privés. Chaque utilisation dans un nouveau contexte générait une nouvelle entrée en base de données et un nouveau fichier sur disque, malgré un contenu binaire exactement identique.
Première tentative d'optimisation : les liens durs
L'équipe Discourse a développé une solution basée sur le regroupement des fichiers par hachage de contenu lors de la sauvegarde. Pour chaque groupe de doublons, une seule copie physique était conservée, le reste étant remplacé par des liens durs vers celle-ci. Cette approche réduisait drastiquement les tailles de sauvegarde et fonctionnait bien sur la plupart des instances.
Cependant, des tests sur un grand forum client ont révélé que le système de fichiers ext4 impose une limite : un maximum d'environ 65 000 liens durs par inode. Avec 246 173 doublons, une fois la limite atteinte, le système a commencé à créer de nouvelles copies physiques — non pas comme de simples doublons, mais comme des fichiers indépendants. Au final, au lieu d'une seule copie, il y avait ~181 000 fichiers supplémentaires, ce qui ne résolvait le problème que partiellement.
Solution finale : basculement dynamique entre liens et copies
La nouvelle solution prend en compte les limitations des systèmes de fichiers et fonctionne de manière universelle :
- Le système commence par créer des liens durs, comme avant.
- Lorsqu'il reçoit une erreur
EMLINK(« Trop de liens ») du noyau Linux, le processus passe à la copie locale de fichiers. - La nouvelle copie devient la « principale » pour les liens suivants, et le cycle recommence à la limite suivante.
Cette approche ne nécessite aucune modification du système de fichiers, est compatible avec tout OS conforme à POSIX, et réduit efficacement les tailles de sauvegarde même avec des nombres extrêmes de doublons.
Exemple de logique de traitement (simplifié) :
if hard_link_fails_with_emlink?
create_new_physical_copy
reset_link_counter
end
Points clés à retenir
- Sécurité vs. Efficacité : Les choix architecturaux pour l'isolation des contextes peuvent entraîner des effets secondaires inattendus à grande échelle.
- Les limites des systèmes de fichiers sont réelles : Même des limites de bas niveau comme 65 000 liens durs par inode dans ext4 peuvent perturber des applications de haut niveau.
- Les solutions universelles sont préférables : Les algorithmes adaptatifs qui réagissent aux erreurs du système d'exploitation sont plus fiables que les optimisations statiques pour des conditions idéales.
- Le contenu populaire génère de la charge : Les fichiers multimédias fréquemment utilisés (emojis, réactions, mèmes) deviennent des gouffres de ressources cachés.
- Les tests avec des données de production sont critiques : Seuls les scénarios d'utilisation réels révèlent ces cas limites.
Leçons pour les développeurs de systèmes distribués
L'incident Discourse met en lumière un dilemme classique : équilibrer la sécurité des données avec l'efficacité du stockage. Lors de la conception de systèmes gérant du contenu généré par les utilisateurs, il faut considérer :
- La déduplication au niveau applicatif avant écriture sur disque.
- La surveillance des métriques relatives aux nombres de fichiers et doublons.
- Une dégradation gracieuse en cas de collision avec les limites système.
Bien que le problème provienne d'une utilisation massive d'un seul GIF, ses racines résident dans des compromis architecturaux. La solution trouvée par l'équipe Discourse peut servir d'exemple pour d'autres projets confrontés à des défis similaires.
— Editorial Team
Aucun commentaire pour le moment.