Ceph : le chemin vers 1 TiB/s
(ceph.io)- Clyso a réalisé des tests de burn-in avant de transformer un cluster Ceph basé sur des HDD en déploiement NVMe de 10 Po, et a atteint 1,0 TiB/s en lecture sur un cluster unique de 630 OSD
- Le matériel final reposait sur 68 Dell PowerEdge R6615 avec 10 NVMe par nœud, mais le test de performances maximal a été mené avec les 63 machines disponibles et 630 OSD
- Les premiers goulets d’étranglement ont été levés en corrigeant les c-states CPU dans le BIOS, une contention du mapping IOMMU dans le noyau, ainsi qu’un problème de flags de compilation RocksDB dans les paquets Deb Ubuntu upstream de Ceph ; le temps de compaction a été réduit d’environ 3× et les écritures aléatoires 4 Ko ont été améliorées de 2×
- En réplication 3X, les meilleurs résultats ont été de 1025 GiB/s en lecture 4 Mo, 270 GiB/s en écriture 4 Mo, 25,5 M IOPS en lecture aléatoire 4 Ko et 4,9 M IOPS en écriture aléatoire 4 Ko ; l’erasure coding 6+2 a atteint 547 GiB/s en lecture 4 Mo et 387 GiB/s en écriture
- Le risque restant est un phénomène où, lors de grosses écritures, certains PG passent à l’état active+clean+laggy et le débit s’effondre ; pour obtenir un débit plus élevé avec plus de 10 NVMe par nœud, il faut un réseau d’au moins 200GbE
Conception d’un cluster Ceph NVMe de 10 Po
- Le client voulait transformer son cluster Ceph existant basé sur des HDD en déploiement NVMe de 10 Po, sans exigences particulières pour RBD, RGW ou CephFS
- Les contraintes de conception incluaient une répartition sur 17 racks, 4U d’espace par rack, l’alimentation, le refroidissement, la densité et les préférences de fournisseur
- Les nouveaux nœuds devaient être intégrés au cluster existant sans interruption de service, et le réseau était déjà une configuration Ethernet rapide en place
- La proposition initiale consistait à placer 34 nœuds 2U double socket dans 17 racks, mais c’est finalement la configuration Dell conçue par Clyso qui a été retenue
- Le devis final était environ 13 % moins cher que la configuration d’origine
- La mémoire par OSD était réduite, mais restait d’environ 12 GiB par OSD, avec un débit mémoire plus rapide
- La configuration utilisait un seul socket, davantage de ressources CPU totales, un débit réseau total plus élevé, des processeurs AMD récents et de la RAM DDR5
- L’usage de nœuds plus petits a réduit de moitié l’impact d’une panne de nœud sur la reconstruction du cluster
Matériel et configuration de base
- Les spécifications système étaient les suivantes
- Nodes: 68 × Dell PowerEdge R6615
- CPU: 1 × AMD EPYC 9454P 48C/96T
- Memory: 192GiB DDR5
- Network: 2 × 100GbE Mellanox ConnectX-6
- NVMe: 10 × Dell 15.36TB Enterprise NVMe Read Intensive AG
- OS: Ubuntu 20.04.6 Focal
- Ceph: Quincy v17.2.7 upstream Deb packages
- Le client voulait limiter la consommation électrique supplémentaire par rack à environ 1000~1500 W
- Le TDP total de 4 nœuds par rack était estimé à au moins 1120 W, auxquels s’ajoutaient la puissance de base, les pics CPU et l’inefficacité des alimentations
- Il a été estimé qu’en cas de besoin, abaisser le cTDP des processeurs permettrait de réduire la consommation d’environ 100 W par rack
- Les serveurs Dell 1U étaient proches de la dernière génération des systèmes utilisés dans le laboratoire de performances upstream de Ceph
- Des problèmes de performances, absents du matériel de génération précédente mais affectant celui-ci, ont été découverts pendant les tests
Méthode de test et choix des benchmarks
- Les tests de burn-in ont été effectués en déployant un cluster Ceph temporaire avec CBT et en lançant des tests FIO
- Les OSD étaient configurés avec
osd_memory_targetà 8 Go- En production, une valeur plus élevée pour
osd_memory_targetsemblait possible
- En production, une valeur plus élevée pour
- Le client n’avait pas besoin de tests de charge block ou S3, mais le moteur
librbdde FIO a été utilisé au lieu deRADOS bench- Avec un
RADOS benchà grande échelle, il est difficile de déterminer le nombre d’instances nécessaires pour saturer le cluster, et l’expérience passée avait nécessité plusieurs pools simultanés - Pour comparer avec les résultats du laboratoire upstream existants, les mêmes tests FIO basés sur librbd ont été utilisés
- Le fait que FIO soit un outil bien connu et jugé fiable a également été pris en compte
- Avec un
- Les tests kernel RBD ont été omis
- Le moteur
librbdpermet d’éviter les problèmes où d’anciens points de montage finissent par nécessiter un redémarrage du système - Ce cluster ne disposait pas d’accès IPMI, et le délai de fin des tests était serré
- D’après les tests précédents, avec suffisamment de clients, les performances totales devaient être globalement similaires
- Le moteur
- Les tests couvraient la réplication 3X et l’erasure coding 6+2
- msgr V2 a été testé à la fois en mode non chiffré et en mode secure
ms_client_mode = securems_cluster_mode = securems_service_mode = securems_mon_client_mode = securems_mon_cluster_mode = securems_mon_service_mode = secure
- FIO remplissait d’abord les volumes RBD avec de grosses écritures, puis exécutait les tests d’IO 4 Mo et 4 Ko pendant 300 secondes chacun
- Pour les exécutions de débogage, la durée était réduite à 60 secondes
- Les processus en arrière-plan comme scrub, deep scrub, PG autoscaling et PG balancing étaient désactivés
Effet du nombre de PG sur les performances
- Des tests précédents dans le laboratoire upstream avaient confirmé que le nombre de PG pouvait avoir un effet important sur les performances
- Avec un faible nombre de PG, la tendance à former des paquets dans la distribution aléatoire peut affecter les performances, et certains cas peuvent être atténués par un balancing supplémentaire
- Sur des clusters rapides, la contention des verrous de PG au sein des OSD peut aussi jouer un rôle important dans les performances globales
- Ce problème n’est pas facile à atténuer autrement qu’en augmentant le nombre de PG
- Même dans un test n’utilisant que 60 OSD, les performances de lecture aléatoire du pool RBD en réplication 3X montaient jusqu’à 16384 PG
- Les écritures atteignaient leur pic plus tôt, mais bénéficiaient encore d’une hausse jusqu’à 2048 PG
- Il ne faut pas appliquer aveuglément un grand nombre de PG en production
- Les valeurs par défaut de Ceph, comme la longueur du PG log et les mises à jour de PG stat, peuvent avoir un impact
- Il est nécessaire de réexaminer si la pratique historique des 100 PG par OSD reste pertinente
Premiers problèmes de performances et comportements étranges
- Le premier accès au nouveau matériel a eu lieu la semaine suivant Thanksgiving aux États-Unis, et le plan initial était de l’intégrer au cluster existant après 1 à 2 semaines de validation de burn-in
- Les tests de performances bas niveau semblaient d’abord bons
- Les tests réseau iperf approchaient 200 Gb/s par nœud
- Les performances brutes des disques NVMe sur certains nœuds semblaient également raisonnables
- Le système d’exploitation des 68 nœuds avait été déployé par erreur sur 2 disques OSD au lieu des disques de démarrage Dell BOSS m.2 internes
- Au lieu du test prévu avec 3 nœuds et 30 OSD, les tests ont donc été réalisés avec seulement 8 NVMe par nœud
- Les premiers résultats Ceph étaient bien inférieurs aux attentes, même en tenant compte du nombre réduit d’OSD
- Seules les lectures aléatoires approchaient un niveau acceptable, mais ce n’était pas suffisant
- En réduisant le périmètre à des tests sur un seul nœud et un seul OSD, un schéma anormal est apparu
- Un système qui fonctionnait bien dans un test à un seul OSD voyait ses performances se dégrader après un test à 8 OSD
- Ensuite, même le test à un seul OSD conservait de mauvaises performances pendant plusieurs heures avant de se rétablir
- Sans test multi-OSD, les performances restaient élevées
- Le même problème ne se reproduisait pas avec FIO exécuté directement sur les disques
- Pendant les tests à 8 OSD, un OSD particulier consommait beaucoup plus de CPU que les autres
- Le profil wallclock des OSD montrait beaucoup de temps passé dans
io_submit, un schéma généralement observé lorsque la queue du disque est pleine et que le noyau se bloque
Trois correctifs
-
Mode performance du BIOS et c-state
- Le premier correctif concernait le fait que le BIOS n’était pas en mode maximum performance, laissant les c-states CPU activés
- Ceph est très sensible à la latence induite par les transitions de c-state CPU
- Désactiver les c-states via le mode maximum performance a amélioré les performances de 10 à 20 %, mais pas suffisamment pour atteindre l’objectif
-
Contention IOMMU
- Le deuxième problème est apparu dans le profil perf côté noyau
- Lors des mauvaises exécutions, beaucoup de temps était passé dans
native_queued_spin_lock_slowpathet dans le chemin de mapping DMA IOMMU alloc_iovaiommu_dma_alloc_iovaiommu_dma_map_sgnvme_map_datanvme_queue_rq- La désactivation de l’IOMMU dans le noyau a fortement amélioré les performances de lecture/écriture 4 Mo du test à 8 nœuds
- Même après ce correctif, le problème des écritures aléatoires 4 Ko subsistait
-
Flags de compilation RocksDB
- Le troisième problème était que les performances des écritures aléatoires 4 Ko et de la compaction RocksDB étaient inférieures aux attentes
- Dans le passé, des symptômes similaires dans Ceph étaient liés à deux causes
- Une compilation sans prise en charge de TCMalloc
- Une compilation sans les bons flags cmake ni optimisations du compilateur
- Les paquets Ubuntu upstream de Ceph incluaient TCMalloc
- Les logs de build des paquets Ubuntu 17.2.7 ont confirmé que RocksDB n’avait pas été compilé avec les bons flags
- Canonical et Gentoo avaient déjà corrigé ce problème dans leurs propres builds
- Les utilisateurs Debian/Ubuntu de cephadm utilisant les conteneurs upstream ne semblaient pas affectés
- Après compilation de paquets custom 17.2.7 corrigés, le temps de compaction a diminué d’environ 3× et les performances d’écriture aléatoire 4 Ko ont doublé
Tests de montée en charge durant la première semaine de 2024
- Le 2 janvier, les tests de performances ont été retardés par la gestion d’une panne majeure sur un autre cluster lié
- À partir du vendredi, CBT et les tests ont été reconfigurés, cette fois avec les 10 disques par nœud disponibles
- Le nombre de clients FIO a été augmenté pour atteindre en moyenne environ 1 client FIO avec
io_depth128 par OSD - Le test à 3 nœuds a atteint 63 GiB/s en lecture aléatoire 4 Mo
- Le test à 10 nœuds a atteint 213,5 GiB/s
- Une montée en charge presque linéaire par rapport aux 3 nœuds, à 98,4 %
- À ce moment-là, seuls 63 des 68 nœuds étaient disponibles
- 32 nœuds, soit 320 OSD, ont été placés d’un côté
- Sur 31 nœuds clients, 10 processus FIO par nœud ont été exécutés
- À l’échelle de 320 OSD, le test a atteint 635 GiB/s en lecture et plus de 15 millions d’IOPS en lecture aléatoire 4 Ko
- La latence moyenne et la tail latency se sont montrées cohérentes dans les tests de montée en charge
- L’augmentation conjointe du nombre de PG et de clients FIO avec les OSD semble avoir joué un rôle
- Les tests étaient dans un état très chargé en IO, au point où ajouter davantage d’IO n’augmentait plus les performances et ne faisait qu’accroître la latence
Atteindre 1 TiB/s avec 630 OSD
- Faute de nœuds clients supplémentaires pour tester toute la capacité, les processus FIO ont été colocalisés sur les nœuds OSD
- Il existait une probabilité de 1/63 qu’un client communique avec un OSD local, ce qui donnait un léger avantage réseau
- À l’inverse, colocaliser les clients FIO sur les nœuds OSD pouvait provoquer une perte de performances
- Le déploiement CBT avec 630 OSD sur 63 nœuds a pris environ 15 minutes
- La première tentative a atteint environ 950 GiB/s, très près de 1 TiB/s
- Ensuite, le nombre de shards OSD et de threads async messenger a été réduit, et le tuning RocksDB de Reef a été appliqué
- Les performances en lecture ont légèrement baissé et les performances en écriture se sont améliorées
- Les performances d’écriture aléatoire se sont améliorées de près de 20 %
- L’impact le plus important semblait venir des changements de shards/threads
- Des expériences ont aussi été menées en doublant le nombre de PG et en augmentant de nouveau le nombre de clients
- La lecture aléatoire 4 Mo s’est légèrement améliorée avec l’augmentation du nombre de clients
- Les IOPS de petites lectures aléatoires se sont dégradées
- Avec 8 FIO par nœud, soit 504 processus au total, les performances d’écriture séquentielle ont fortement chuté
- Lorsque 504 processus FIO ont effectué des écritures 4 Mo, certains PG sont passés à l’état active+clean+laggy
- Même avec un débit ne représentant qu’une partie des capacités du cluster, le nombre de PG laggy augmentait avec le temps
- Le cluster ne récupérait pas de cet état avant la fin de la charge
- Selon la documentation Ceph, en état laggy, une réplique ne confirme pas à temps le nouveau lease du primary, ce qui suspend temporairement les IO
- Au final, la configuration par défaut de Ceph — 8 shards, 2 threads par shard et 3 threads msgr — était la plus adaptée à la lecture 4 Mo
- Avec 256K PG, 630 OSD et 504 processus clients FIO,
ceph -saffichait 1,0 TiB/s read- Les 630 OSD étaient tous en état up/in
- Les 262145 PG étaient tous en état active+clean
- Les opérations de lecture affichées étaient de 266,15k op/s
Résultats en erasure coding 6+2
- Le cluster cible réel du client utilisait auparavant une configuration erasure coding 6+2, ce qui nécessitait des tests séparés
- Les valeurs de PG, shards et clients qui avaient bien fonctionné dans les tests précédents ont été retenues pour les tests EC
- Comme les threads async messenger semblaient très sollicités, des essais avec un nombre supérieur à la valeur par défaut ont été menés
- Avec 4 à 5 threads async msgr, les performances suivantes ont été atteintes
- Lecture : plus de 500 GiB/s
- Écriture : près de 400 GiB/s
- La raison pour laquelle la lecture EC 6+2 est plus lente que la réplication 3X est la différence de surcharge réseau
- En réplication, l’OSD primary lit les données locales et les envoie au client, soit une surcharge réseau effectivement de 1X
- En EC 6+2, le primary doit lire 5 des 6 chunks depuis les réplicas pour reconstruire l’object, puis l’envoyer au client
- La surcharge réseau totale de la requête est approximativement
(1 + 5/6)X
- En écriture, la situation est inverse
- En réplication 3X, le client envoie l’object au primary, qui le renvoie aux deux secondaires, pour une surcharge réseau totale de 3X
- En EC, il suffit d’envoyer 7/8 des chunks aux secondaires, ce qui donne de meilleures performances sur les grosses écritures
- Les IOPS des petites IO sont un problème distinct
- Pour les très petites lectures/écritures, Ceph accède à tous les OSD participant au PG de l’object
- Même si les données recherchées ne se trouvent que dans un seul chunk, les données sont récupérées depuis tous les OSD participant à la stripe
- Clyso a ressuscité une PR implémentant les lectures de stripe partielles pour l’erasure coding, réalisée à l’été 2023, avec un impact important
- Il n’est pas encore clair si elle pourra être mergée dans Squid
Impact du chiffrement msgr
- Pour estimer l’impact si le client utilisait le chiffrement au niveau msgr, des tests de msgr v2 encryption ont aussi été réalisés
- Les résultats avec chiffrement activé ont été comparés aux résultats précédents, à la fois en réplication 3X et en erasure coding 6+2
- L’impact le plus important est apparu sur les grosses lectures
- Passage d’environ 1 TiB/s à environ 750 GiB/s
- Les autres métriques montrent une baisse de performances plus modérée mais cohérente
- Des tests de PG scaling et kernel RBD étaient également souhaités, mais le système a dû être rendu au client pour re-imaging et intégration
Résumé des meilleures performances finales
- Les meilleurs chiffres obtenus lors des tests sont les suivants
| Élément | 30 OSDs (3x) | 100 OSDs (3x) | 320 OSDs (3x) | 630 OSDs (3x) | 630 OSDs (EC62) |
|---|---|---|---|---|---|
| FIO colocalisé | Non | Non | Non | Oui | Oui |
| Lecture 4 Mo | 63 GiB/s | 214 GiB/s | 635 GiB/s | 1025 GiB/s | 547 GiB/s |
| Écriture 4 Mo | 15 GiB/s | 46 GiB/s | 133 GiB/s | 270 GiB/s | 387 GiB/s |
| Lecture aléatoire 4 Ko | 1,9M IOPS | 5,8M IOPS | 16,6M IOPS | 25,5M IOPS | 3,4M IOPS |
| Écriture aléatoire 4 Ko | 248K IOPS | 745K IOPS | 2,4M IOPS | 4,9M IOPS | 936K IOPS |
- Après la fin des tests, tout le matériel a été réimagé, et les nouveaux OSD ont été déployés dans le cluster HDD existant du client
- La migration a été contrôlée avec le script upmap-remapped de Dan, et environ 80 % des données existantes ont été déplacées vers les OSD basés sur NVMe
- Au départ, il a été décidé de ne pas appliquer immédiatement tout le tuning utilisé pendant les tests, mais de vérifier d’abord le comportement du cluster avec une configuration majoritairement par défaut
- Les données de test pourront servir à affiner davantage le système si le client rencontre des problèmes de performances à l’avenir
Problèmes restants et limites de montée en charge
- Le problème des PG laggy survenant sous forte charge d’écriture doit être résolu
- Il n’est pas acceptable que Ceph s’effondre lorsque la charge d’écriture augmente
- Ces tests ont confirmé que Ceph peut saturer des NIC 2×100GbE
- Pour augmenter davantage le débit avec plus de 10 disques NVMe par nœud, il faut au moins 200GbE
- Les IOPS sont plus complexes
- Le nombre de PG peut avoir un effet important
- Le modèle de threading des OSD joue aussi un rôle clé
- Dans plusieurs déploiements, un plafond d’environ 400K~600K IOPS en lecture aléatoire par nœud a été rencontré
- Les pistes d’amélioration identifiées incluent l’interface entre async msgr et le noyau, ainsi que la manière dont les threads OSD sont réveillés lorsque de nouvelles tâches arrivent dans la shard queue
- Du code OSD a déjà été modifié pour obtenir de meilleurs résultats sous forte charge, mais au prix d’une latence plus élevée sous faible charge
- Améliorer les IOPS nécessitera plusieurs approches et possiblement une réécriture d’une partie du code de threading des OSD
1 commentaires
Avis sur Hacker News
Ceph a une histoire intéressante.
Les fondateurs de DreamHost l’ont créé pour leurs besoins internes, et DreamHost proposait déjà de fait ce type de services, comme des VPS et des serveurs OS/bases de données/apps managés, avant même que les termes IaaS et PaaS ne s’imposent dans le secteur.
Ceph a ensuite été scindé, puis racheté par Red Hat.
https://en.wikipedia.org/wiki/DreamHost
Il n’y avait pas de discours marketing où chaque phrase est polie pour vendre ; c’était l’époque où l’on partageait simplement ce avec quoi on s’amusait.
Si je me souviens bien, c’était le projet universitaire de l’un des fondateurs, auquel les autres fondateurs se sont associés en le soutenant ; il me semble que Docker a une origine similaire.
L’UCSC est un endroit d’où sont sortis beaucoup de bons travaux de recherche sur le stockage.
Bon article. Au CERN, nous avons aussi récemment atteint 1 To/s, mais avec EOS (https://cern.ch/eos), pas Ceph.
https://www.home.cern/news/news/computing/exabyte-disk-stora...
Cela dit, notre cluster EOS compte beaucoup plus de nœuds et utilise majoritairement des HDD. Le CERN utilise aussi largement Ceph.
J’adorais vraiment ce genre d’expériences. Quand j’étais tech lead chez Cisco, j’ai eu le luxe de pouvoir mettre en place Kubernetes sur bare metal, puis de configurer moi-même GlusterFS et Ceph afin d’apprendre et de comparer lequel était le meilleur.
De mémoire, c’était vers 2017/2018, une bonne époque. Cet article était très bon aussi.
Certains SSD NVMe avaient été davantage utilisés que d’autres, ce qui créait des écarts ; c’était vraiment absurde comme travail.
J’aimerais que quelqu’un essaie de réduire encore l’échelle des nœuds. Le système décrit ici a 10 disques par nœud et environ 300 W/nœud, soit autour de 30 W par disque.
La surcharge est assez importante, et il faut aussi une quantité de stockage non négligeable pour obtenir ne serait-ce qu’un peu de redondance.
Avec un peu d’ingénierie, on pourrait sans doute réduire l’ensemble d’un facteur 10 : fabriquer un petit ordinateur monocarte avec 4 lignes PCIe pour le NVMe, 2×10GbE (deux sockets SFP+), un CPU ARM ou RISC-V suffisamment rapide, et de l’eMMC ou un slot SD pour le démarrage.
Cela permettrait de descendre à quelques nœuds, tout en réduisant l’exposition où une seule panne fait disparaître 10 disques d’un coup.
On pourrait probablement en mettre beaucoup dans un châssis 4U, avec en option deux switches totalement indépendants dans le même châssis pour agréger les nœuds internes.
L’installation a été vraiment pénible à cause du processeur armhf, mais une fois lancé, ça fonctionnait bien. C’était seulement lent à cause de l’unique NIC 1Gb.
À l’époque, c’était juste pour apprendre.
[0] https://www.hardkernel.com/shop/odroid-hc2-home-cloud-two/
Je dois bientôt recevoir deux ARM Turing RK1 de 7 W, chacun capable de 4 Go/s en PCIe 3x4, et la carte de cluster Turing Pi 2 peut en accueillir 4 au format ITX.
Pour un coût total de 820 dollars, j’espère dépasser 3 Gbit/s par watt.
Jusqu’ici, ce sont les lignes PCIe qui limitent. Même un SSD de 2 To à 90 dollars est annoncé à 7 Go/s en PCIe 4x4 ; je ne considère donc pas encore les ordinateurs monocarte comme la solution optimale.
La gamme Ampere Altra semble prendre en charge PCIe 4x128 à 40 W, donc une lame 1U avec du réseau 100G pourrait être intéressante.
Cela dit, même en homelab, j’ai vu beaucoup de bugs liés à ARM et d’optimisations manquantes ; il est donc difficile de dire qu’une telle solution est déjà prête pour le datacenter.
Pour justifier aujourd’hui une configuration Ceph avec des interfaces 10 Gbit/s, il faudrait qu’elle soit vraiment petite et très peu coûteuse.
À une échelle aussi réduite, il est probablement préférable de mettre du stockage NVMe local dans chaque serveur.
C’est un calcul approximatif du type 1 To/s × 8 bits/octet × 1024 Go/To ÷ 34 nœuds ÷ 300 W.
Un système ARM très efficace comme un Mac mini récent consomme environ 10 W en usage interactif et peut traiter du réseau 10 Gbit/s, soit à peu près 1 Gbit/s par watt côté données.
Autrement dit, le cluster de l’article est grosso modo au même niveau en bits/s/watt qu’un système ARM très efficace.
Je ne pense pas que de petits nœuds amélioreraient réellement l’efficacité ; ils risqueraient plutôt de coûter plus cher. Les serveurs puissants actuels ont de très bonnes performances par watt.
Quoi qu’il en soit, c’est du logiciel open source qui tourne sur du matériel généraliste, donc on peut l’essayer soi-même pour quelques centaines de dollars.
Quand le système d’exploitation et le périphérique NVMe sont éloignés, le contrôleur doit déduire l’intention des requêtes pour gérer au mieux le regroupement et le nivellement d’usure, ce qui introduit naturellement de l’inefficacité.
La nouvelle fonctionnalité FDP (flexible data placement) tente de résoudre cela en donnant davantage de contrôle au système d’exploitation.
Le mieux serait de remonter cela côté système d’exploitation hôte et d’exposer la flash autant que possible comme « un immense tableau idiot de transistors attaché en périphérique PCIe ».
En supprimant les couches d’abstraction, on pourrait probablement construire le système par unités matérielles de type Atom, avec une NIC 100 Gbit/s intégrée et une quantité proportionnelle de flash pour obtenir le parallélisme voulu.
Il y a forcément eu un moment dans l’histoire où la quantité totale de données numériques stockées dans le monde a atteint pour la première fois 1 Tio.
Ce jour se situe presque certainement dans les 60 dernières années.
Et aujourd’hui, les serveurs d’une organisation assez quelconque déplacent cette quantité de données chaque seconde. Sans être un État ni un projet de recherche supranational.
Article intéressant. Nous exploitons un cluster de stockage Ceph pour maintenir notre cache de couches Docker.
Après être passés d’EBS à Ceph, la différence de débit a été énorme. Le débit en écriture est passé de 146 Mo/s et 3 000 IOPS à 900 Mo/s et 30 000 IOPS.
Le meilleur, c’est que ça fonctionne quasiment tout seul. À part parfois un trim du système de fichiers, il n’y a presque rien à faire.
Pour un système de cache, c’était une amélioration énorme.
[0] https://depot.dev/blog/cache-v2-faster-builds
Nous avons fini par migrer vers notre propre rack, ce qui a encore réduit les coûts d’environ un facteur 10, et gagner cette capacité d’exploitation en interne nous a donné beaucoup de liberté.
Ce n’était pas immédiatement clair à la lecture du blog.
Les pires problèmes que j’ai rencontrés avec le stockage dynamique interne à un cluster n’étaient pas de purs problèmes d’I/O.
Ils venaient plutôt du fait que le logiciel de contrôleur de stockage de Kubernetes gérait mal les problèmes du monde réel, par exemple lorsqu’un pod meurt, que le PVC ne se rattache pas avant l’expiration d’un très long timeout, et que le pod reste en état ContainerCreating jusqu’à ce que le verrou du PVC soit libéré.
Cela s’est produit sur plusieurs clusters utilisant rook/ceph et Longhorn.
Je me demande si quelqu’un a déjà fait tourner Ceph dans un homelab. La dernière fois que je m’étais renseigné, les exigences matérielles étaient assez élevées
Quand ça fonctionne bien, c’est excellent, mais quand un problème survient, ça devient un énorme casse-tête
Si le stockage distribué en lui-même t’intéresse, il existe de meilleures options pour une configuration de homelab
seaweedfs a été très stable pendant des années, aussi bien à petite qu’à très grande échelle, et nous avons même migré une configuration Ceph de production vers celui-ci
Dans l’univers Kubernetes, Longhorn a aussi été stable
GlusterFS reste correct si l’on sait dans quoi on s’engage
Mais obtenir de bonnes performances était très difficile, et dans un petit cluster, le démon de métadonnées pouvait assez facilement s’arrêter
Au final, quand l’amusement est retombé, je suis revenu à ZFS sur une seule machine
Il faut d’abord garder à l’esprit que Ceph est un système de stockage distribué ; l’hypothèse de base est donc d’avoir plusieurs nœuds
Pour l’apprentissage, on peut aussi tout virtualiser sur une seule machine, mais disposer de machines physiques distinctes est nettement préférable
Comme ZFS, Ceph préfère avoir un accès physique aux disques
Il lui faut aussi une bonne connectivité réseau. C’est surtout à cela, je pense, que les gens font référence quand ils parlent des fortes exigences matérielles de Ceph
Idéalement, il faut au minimum du 10GbE, et davantage si l’on veut de meilleures performances. Les opérations comme le backfill, en particulier, peuvent générer beaucoup de trafic réseau
Si l’on peut trouver du matériel de homelab bon marché, le 25Gbps est aussi très bien, le 50Gbps est techniquement proche d’une impasse, et le 100Gbps fonctionne bien
Cela dit, pour un homelab, de petits mini-PC ou NUC bon marché avec du 10GbE suffisent à faire fonctionner l’ensemble, avec des performances acceptables et un bon apprentissage à la clé
On peut installer Ceph directement sur du bare metal, ou utiliser Rook (https://rook.io/) si l’on veut suivre la voie Kubernetes en homelab
J’espère que cela aide ; n’hésite pas si tu as d’autres questions
À ce niveau, on peut difficilement parler de gros matériel
[1] https://ceph.io/en/news/blog/2022/install-ceph-in-a-raspberr...
Au minimum 10Gb, idéalement 40Gb ou plus ; et si l’on utilise des disques rotatifs, il vaut mieux avoir plusieurs nœuds avec au moins 6 disques chacun
Si tout est en SSD, on peut très probablement réduire fortement le nombre de disques par nœud
J’ai fait le calcul parce que je voulais voir comment 1 TiB/s se compare aux limites théoriques du matériel réel
Ce cluster est composé de 68 nœuds, chacun étant un Dell PowerEdge R6615 (https://www.delltechnologies.com/asset/en-us/products/server...)
La configuration utilisée est un R6615 avec 10 baies pour disques U.2, et les liens U.2 transmettent les données via 4 lignes PCIe Gen 4. Une ligne PCIe fait 16 Gbit/s et, grâce à l’encodage 128b-132b, l’overhead est d’environ 3 %, donc négligeable
La bande passante maximale d’un lien U.2 est donc de 16×4=64 Gbit/s, soit 8 Go/s. Cela dit, le disque U.2 NVMe utilisé, le Dell 15.36TB Enterprise NVMe Read Intensive AG, semble avoir un débit en lecture de 7 Go/s (https://www.serversupply.com/SSD%20W-TRAY/NVMe/15.36TB/DELL/...), donc le lien U.2 à 8 Go/s n’est pas le goulot d’étranglement
Avec 10 disques U.2 par nœud, chaque nœud peut fournir jusqu’à 10×7=70 Go/s d’I/O en lecture locale
Mais la bande passante réseau de chaque nœud n’est que de 200 Gbit/s (2×100GbE Mellanox ConnectX-6), soit 25 Go/s. Cela signifie que, pour les lectures distantes, on ne peut pas exploiter les 70 Go/s des disques et que le réseau est le goulot d’étranglement
En supposant qu’il n’y ait pas d’autre goulot d’étranglement réseau, les 68 nœuds peuvent fournir 68×25=1700 Go/s de lecture via le réseau. L’auteur a effectivement mesuré 1 TiB/s, plus exactement 1025 Gio/s = 1101 Go/s, soit environ 65 % du maximum théorique de 1700 Go/s
C’est plutôt correct, mais si tous les nœuds pouvaient saturer simultanément et complètement leur lien réseau à 200 Gbit/s, il serait théoriquement possible de faire un peu mieux
En lisant tout l’article, j’ai eu l’impression que la complexité de Ceph pèse assez lourdement sur le CPU. Le simple fait de ne pas compiler les modules avec -O2 (le « Fix Three » cité par l’auteur : https://bugs.launchpad.net/ubuntu/+source/ceph/+bug/1894453) peut faire que « certaines charges de travail soient jusqu’à 5 fois plus lentes » (https://bugs.gentoo.org/733316) sur une charge purement I/O, ce qui est assez surprenant
Il est également étrange que les threads OSD gaspillent autant de CPU à prendre un spinlock IOMMU. Je suis d’accord avec la conclusion selon laquelle le modèle de threading des OSD n’est pas optimal
Un benchmark synthétique relativement simple en 100 % lecture ne devrait pas faire apparaître de contention de threading. Du moins si cette partie de l’architecture logicielle de Ceph avait été bien conçue. Comme c’est un problème corrigeable, j’espère que les développeurs de Ceph lui donneront une priorité plus élevée
Le labo Ceph upstream dispose de machines Dell de la génération précédente dans le même châssis 1U, avec des processeurs AMD Rome, et elles n’ont pas ce problème tout en offrant des performances similaires à la même échelle, autour de 30 OSD
Le client a indiqué avoir déjà observé ce problème auparavant dans son datacenter, et nous espérons pouvoir en identifier la cause avec AMD
L’été dernier, j’ai travaillé un peu à renforcer temporairement le modèle de threading existant des OSD. Des choses comme le double buffering du handoff entre async msgr et les threads workers, ou le réveil adaptatif des threads
Sous charge, cela permettait d’améliorer fortement les performances et l’efficacité, mais au prix d’une latence accrue à faible charge. Par défaut, Ceph est très agressif pour réveiller un thread lorsqu’une nouvelle I/O arrive sur un shard donné
J’en ai discuté avec un autre développeur core, et nous sommes tous deux arrivés à la conclusion qu’une refonte complète du code de threading serait plus pertinente
Avec 320 OSD, cela donne environ 1,6 Tio/s
C’est en tout cas le chiffre que j’ai trouvé. Il n’y a pas non plus énormément de tests de ce type de disques NVMe enterprise
Cela dit, le chiffre semble bien correspondre aux NIC. À cette échelle, la plupart des charges de travail ont de bonnes chances de ressembler à des I/O aléatoires au niveau de la couche de stockage
Ce qui m’étonne, c’est pourquoi ils ont choisi des nœuds 1U, plus difficiles à refroidir, avec 10 SSD et des NIC 2×100Gb
Avec des nœuds 2U, 24 SSD et des NIC 2×200Gb ou 400Gb, ils auraient pu éliminer le goulot d’étranglement réseau et réduire aussi la consommation grâce à des ventilateurs plus grands et plus lents, ainsi qu’à moins de packages CPU. Le nombre de cœurs par socket aurait même pu être plus élevé
Avec moins de nœuds, le domaine d’impact des pannes augmente, mais autour de 34 nœuds, cela ne me semblerait pas être un si gros problème
Avec moins de nœuds, ils auraient aussi probablement pu construire un réseau plus plat avec environ 4 switches
Les racks et les switches existaient déjà et sont aussi largement utilisés pour d’autres usages, donc l’espace physique ajouté à cause de Ceph est très faible :)