Bonjour à tous,

comme nombre d'entre vous l'ont remarqué, nous rencontrons depuis le mois de mars différent problèmes sur l'infrastructure Swift qui stocke les données hubiC. De votre point de vu, ces problèmes peuvent se résumer simplement par des problèmes de performance et de stabilité. Je vais essayer de vous détailler un peu plus ce qu'il en est.

Les problèmes sont apparu lorsque nous avons décidé de migrer notre stockage vers l'Erasure Coding. L'objectif de cette migration est de permettre de continuer à vous proposer le service dans sa forme actuelle, sans changement de quota sur les comptes gratuit, ni changement de tarif sur les comptes payant.

L'un des problèmes que nous rencontrons à ce jour concerne le système de fichier que nous utilisons. Le système de fichier, c'est la couche intermédiaire qui permet à votre système d'exploitation de parler à votre disque dur. Nous utilisons XFS. Sur chaque serveur qui stocke vos données, il y a plusieurs disques dur qui sont formatés en XFS.

Lorsque nous utilisions le mode replica (x3), stocker votre fichier de 1MB voulait dire pour nous stocker trois fichiers de 1MB sur trois disques dur. Depuis le passage en Erasure Coding 12+3 fragments, chacun de vos fichiers de 1M représentent pour nous 15 fichiers d'environs 83KB
+ 15 fichiers dit "durable" qui ont un role de "commit". On passe donc
sur nos clusters de :
- 3 fichiers à 30 fichiers
- 3MB à 1.25MB

Certes, on gagne de la place, mais on multiplie également le nombre de fichiers par 10. Ca n'a l'air de rien dit comme ça, mais au niveau d'hubiC et de ces milliards de fichiers, cela à quelques conséquences.

La principale, c'est tout simplement une explosion de la taille de la table d'inodes. Dans la structure du système de fichier XFS (comme la plupart des autres systèmes de fichiers), un fichier est représenté par ce qu'on appelle un inode. Pour schématiser, l'inode c'est une entrée dans une base de données qui stocke les méta données du fichier.

La première conséquence c'est que le cache d'inode est moins efficace.
Il faudrait multiplier la RAM par 10 dans les serveurs pour maintenir le cache au niveau actuel (on parle de plusieurs centaines de TB de RAM).
Le cache étant moins efficace, on doit plus souvent aller chercher les informations sur le disque (et un disque dur c'est lent, plusieurs millisecondes à chaque accès). Cela engendre une augmentation de la charge des disques et donc une des performances.

Deuxième conséquence, moins évidente, les soucis de stabilité. Avec un tel niveau d'usage de XFS, nous rencontrons de nombreux soucis. Par moment, le kernel Linux cesse d'envoyer des requêtes au système de fichier : impossible de lire ou d'écrire sur le disque dur. Les données ne sont donc plus accessible tant que le serveur n'a pas été redémarré.
Autre soucis, sous forte charge, le kernel Linux se bloque. La machine est plantée, il faut la redémarrer matériellement (reset). Encore un autre soucis, les corruptions "spontanées" du système de fichier. Des corruptions apparaissent parfois sans raison apparente. De même, si par moment un disque dur se rempli complètement, le système de fichier se corrompt et devient inaccessible. Note importante : il ne s'agit pas de vos données, mais de la structure du système de fichier qui est corrompu.

Ces corruptions sont très génante car, avec la taille de la table d'inode, il devient compliquer de réparer un système de fichier. Ça prend dans les 12h à 24h, et consomme environs 80GB de RAM. On ne peut alors pas le faire directement en production, on est obligé de placer le disque dans une machine dédiée à faire des réparations de système de fichiers avec suffisement de RAM pour ça.

Lors des discussions que j'ai pu avoir avec la communauté Swift, il apparait que :
- nous serions le plus gros cluster Swift en erasure coding dont ils aient connaissance
- nous serions les seuls à rencontrer ce genre de soucis avec XFS

Néanmoins, d'autres recontres des problèmes qui s'approche, sans atteindre notre extrème :
http://oss.sgi.com/archives/xfs/2016-01/msg00169.html
http://oss.sgi.com/archives/xfs/2016-02/msg00053.html

Maintenant que le constat est posé, il faut agir. Patcher le kernel Linux est exclus, il faut avoir des compétences très pointu en développement kernel et de système de fichier. Et sans connaitre l'ampleur du travail à effectuer, on est pas sûr d'en voir le bout dans un délais raisonnable. Nous avons donc étudié plusieurs système de fichier en remplacement de XFS. De part les contraintes de Swift, les systèmes de fichier suivant ont été testé :
- XFS v4 et v5 (bah oui, il faut une référence dans un test )
- ZFS
- JFS
- ReiserFS

Les autres système de fichier plus courant (ext2/3/4, btrfs, ...) ne sont pas compatible avec Swift.

Je ne rentre pas dans les détails des tests, mais si vous souhaitez avoir plus d'information, demandez

La conclusion, c'est qu'aucun système de fichiers n'est parfait. Il y en a juste un moins pire que les autres : ReiserFS. Ses perf sont moyennes mais constante quelque soit le taux de remplissage et le nombre de fichier stockés. Il est résistant, il est nativement intégré au kernel.
(le moins stable c'est JFS, après un reboot hard on a jamais pu re-accéder aux données de test !)

Nous allons donc déployer sur un serveur (et un seul pour le moment) ReiserFS afin de vérifier en situation réelle son comportement et le comparer aux autres serveurs en XFS. Selon les résultats, nous choisirons de continuer ou non. Nous avançons prudemment malgré les soucis actuels car pour un service de stockage, le système de fichier c'est un peu comme la farine pour un boulanger => c'est la base et faut pas se louper.

De cette instabilité avec XFS découle tout un tas de problèmes sur lesquels je reviendrais dans un prochain mail.

Précisons également que si nous validons définitivement ReiserFS, le remplacement total de XFS est peu probable étant donné le nombre de disque dur que ça représente. XFS et ReiserFS cohabiterons donc pendant un moment. Ca signifie que nous travaillons également sur d'autres axes d'améliorations.

Cordialement.