Contexte initial
Les Sprites de Fly.io utilisent un stockage d’objets comme source de vérité. Au départ, la couche de persistance était assurée par JuiceFS, un système de fichiers distribué qui sépare les données (chunks dans le bucket) et les métadonnées (une base SQLite répliquée avec Litestream). Un disque virtuel de 100 GB était créé, monté en boucle et formaté en ext4. Cette architecture fonctionnait tant que les trois journaux – chunks, métadonnées et base de checkpoints – restaient synchronisés.
Limites du système JuiceFS
Le modèle à trois sources de vérité présentait des points de défaillance. En mode write‑back, JuiceFS enregistre d’abord le pointeur de chunk dans la base avant d’uploader le bloc réel. Si le processus est interrompu, la métadonnée pointe vers un chunk inexistant, ce qui entraîne un échec de lecture (404) et fait basculer le système de fichiers ext4 en lecture‑seule. De plus, chaque checkpoint était un clone copy‑on‑write du disque image ; les clones partageaient les mêmes chunks, de sorte qu’une corruption affectait tous les checkpoints simultanément. Les tests internes sur 400 Sprites pendant 5 000 cycles ont révélé une perte irréversible de capacité de checkpoint pour plusieurs instances.
Architecture du Sprites Block Device
Le Sprites Block Device (SBD) simplifie la pile en exposant le bucket d’objet comme un périphérique bloc via NBD. Un seul démon, sbd serve, répond aux requêtes du noyau : il lit/écrit dans un cache local, pousse les blocs modifiés vers le bucket en arrière‑plan et effectue un flush explicite lorsqu’une garantie de persistance est requise. Les métadonnées sont stockées dans le même bucket que les blocs, éliminant ainsi la base de données séparée. Ext4 continue de gérer l’allocation de fichiers, mais il opère désormais directement sur le périphérique bloc présenté par SBD.
# Lancement du daemon SBD dans un Sprite
sbd serve --bucket my-sprites-bucket --device /dev/nbd0
Analyse de fiabilité et de restauration
Les checkpoints sous SBD sont des instantanés de volume complet, identifiés par un numéro de version et consignés dans un catalogue interne unique. La restauration consiste à démonter le système de fichiers, réinitialiser le volume à la version souhaitée et remonter. Cette opération ne dépend que d’une source de vérité, ce qui réduit le risque d’incohérence. En cas de corruption, SBD détecte la divergence de bloc lors de la lecture et arrête le Sprite, forçant un redémarrage complet qui reconstruit l’état à partir du bucket fiable. Les tests de dog‑fooding ont montré une amélioration notable de la robustesse par rapport à la solution précédente.