Ceph: Der Weg zu 1 TiB/s
(ceph.io)- Clyso führte vor der Umstellung eines HDD-basierten Ceph-Clusters auf eine 10-PB-NVMe-Bereitstellung Burn-in-Tests durch und erreichte in einem einzelnen Cluster mit 630 OSDs 1,0 TiB/s Lesedurchsatz
- Die endgültige Hardware bestand aus 68 Dell PowerEdge R6615 mit je 10 NVMe pro Node, der Spitzenleistungstest wurde jedoch mit den verfügbaren 63 Nodes und 630 OSDs durchgeführt
- Anfängliche Engpässe wurden durch die Behebung von BIOS-CPU-c-state, Kernel-IOMMU-Mapping-Contention und Problemen mit den RocksDB-Kompilierungs-Flags der Ubuntu-Deb-Pakete von Upstream Ceph beseitigt; die Compaction-Zeit sank um etwa das Dreifache und 4-KB-Random-Write verbesserte sich um das Doppelte
- Spitzenwerte mit 3-facher Replikation lagen bei 1025GiB/s für 4MB-Lesen, 270GiB/s für 4MB-Schreiben, 25,5M IOPS für 4KB Random Read und 4,9M IOPS für 4KB Random Write; 6+2 Erasure Coding erreichte 547GiB/s beim 4MB-Lesen und 387GiB/s beim Schreiben
- Das verbleibende Risiko ist, dass einige PGs bei großen Schreiblasten in den Zustand active+clean+laggy wechseln und der Durchsatz stark einbricht; für noch höheren Durchsatz mit mehr als 10 NVMe pro Node ist ein Netzwerk mit 200GbE oder mehr nötig
Entwurf eines 10-PB-NVMe-Ceph-Clusters
- Der Kunde wollte einen bestehenden HDD-basierten Ceph-Cluster auf eine 10-PB-NVMe-Bereitstellung umstellen; besondere Anforderungen an RBD, RGW oder CephFS gab es nicht
- Zu den Designvorgaben gehörten die Verteilung über 17 Racks, 4U Platz pro Rack, Stromversorgung, Kühlung, Dichte und Herstellerpräferenzen
- Die neuen Nodes mussten ohne Serviceunterbrechung in den bestehenden Cluster integriert werden, und das Netzwerk war bereits als schnelle Ethernet-Konfiguration vorhanden
- Der erste Vorschlag sah 34 Dual-Socket-2U-Nodes in 17 Racks vor, letztlich wurde aber eine von Clyso entworfene Dell-basierte Konfiguration gewählt
- Das finale Angebot war rund 13 % günstiger als die ursprüngliche Konfiguration
- Der Speicher pro OSD war geringer, lag aber weiterhin bei etwa 12GiB pro OSD, und der Speicherdurchsatz war höher
- Verwendet wurden eine Single-Socket-Konfiguration, mehr gesamte CPU-Ressourcen, höherer gesamter Netzwerkdurchsatz sowie aktuelle AMD-Prozessoren und DDR5-RAM
- Durch kleinere Nodes halbierte sich die Auswirkung eines Node-Ausfalls auf die Wiederherstellung des Clusters
Hardware und Grundkonfiguration
- Die Systemspezifikation war wie folgt
- 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-Pakete
- Der Kunde wollte den zusätzlichen Stromverbrauch pro Rack auf etwa 1000 bis 1500 W begrenzen
- Die gesamte TDP von 4 Nodes pro Rack wurde auf mindestens 1120 W geschätzt, zuzüglich Grundlast, CPU-Spitzenlast und Ineffizienz der Netzteile
- Bei Bedarf könne die cTDP der Prozessoren gesenkt werden, um pro Rack etwa 100 W einzusparen
- Die 1U-Dell-Server entsprachen in ihrer Konfiguration weitgehend der neuesten Generation der Systeme aus dem Upstream-Ceph-Performance-Lab
- Während der Tests wurden Performance-Probleme entdeckt, die es bei der Hardware der vorherigen Generation nicht gegeben hatte, die sich aber auf diese Hardware auswirkten
Testmethode und Benchmark-Auswahl
- Für die Burn-in-Tests wurde mit CBT ein temporärer Ceph-Cluster bereitgestellt und anschließend FIO-Tests ausgeführt
- Für die OSDs wurde
osd_memory_targetauf 8GB gesetzt- In der Produktion sei voraussichtlich auch ein höheres
osd_memory_targetmöglich
- In der Produktion sei voraussichtlich auch ein höheres
- Der Kunde benötigte keine Tests für Block- oder S3-Workloads, dennoch wurde statt
RADOS benchdielibrbd-Engine von FIO verwendet- Bei groß angelegtem
RADOS benchist es schwer zu bestimmen, wie viele Instanzen nötig sind, um den Cluster auszulasten, und früher waren dafür teils mehrere gleichzeitige Pools nötig - Um mit bestehenden Ergebnissen aus dem Upstream-Labor vergleichbar zu bleiben, wurden dieselben librbd-basierten FIO-Tests verwendet
- Außerdem ist FIO ein bekanntes und vertrauenswürdiges Tool
- Bei groß angelegtem
- Kernel-RBD-Tests wurden ausgelassen
- Die
librbd-Engine vermeidet Probleme mit veralteten Mount Points, die sonst Systemneustarts nötig machen können - Für diesen Cluster gab es keinen IPMI-Zugang, und die Frist bis zum Abschluss der Tests war knapp
- Auf Basis bisheriger Tests wurde erwartet, dass die Gesamtleistung mit genügend Clients im Wesentlichen ähnlich sein würde
- Die
- Getestet wurden sowohl 3-fache Replikation als auch 6+2 Erasure Coding
- msgr V2 wurde sowohl im unverschlüsselten Modus als auch im Secure-Modus getestet
ms_client_mode = securems_cluster_mode = securems_service_mode = securems_mon_client_mode = securems_mon_cluster_mode = securems_mon_service_mode = secure
- FIO füllte die RBD-Volumes zunächst mit großen Schreibvorgängen und führte dann jeweils 300 Sekunden lang 4MB- und 4KB-IO-Tests aus
- Bei Debugging-Läufen wurde dies auf 60 Sekunden verkürzt
- Hintergrundprozesse wie Scrub, Deep Scrub, PG-Autoscaling und PG-Balancing wurden deaktiviert
Einfluss der PG-Anzahl auf die Leistung
- Frühere Tests im Upstream-Labor hatten gezeigt, dass die Anzahl der PGs einen großen Einfluss auf die Performance haben kann
- Bei niedriger PG-Anzahl kann die Klumpung zufälliger Verteilung die Performance beeinflussen, teils lässt sich das durch zusätzliches Balancing abmildern
- In schnellen Clustern kann außerdem PG-Lock-Contention innerhalb der OSDs eine wichtige Rolle für die Gesamtleistung spielen
- Dieses Problem lässt sich abgesehen von einer Erhöhung der PG-Anzahl nur schwer entschärfen
- Selbst in Tests mit nur 60 OSDs skalierte die Random-Read-Leistung eines RBD-Pools mit 3-facher Replikation bis auf 16384 PGs
- Schreibvorgänge erreichten ihren Peak früher, profitierten aber noch bis 2048 PGs
- Hohe PG-Zahlen sollten nicht blind in die Produktion übernommen werden
- Ceph-Defaults wie PG-Log-Länge und PG-Stat-Updates können dabei eine Rolle spielen
- Es sollte neu bewertet werden, ob die bisherige Praxis von 100 PG pro OSD weiterhin sinnvoll ist
Frühe Performance-Probleme und merkwürdiges Verhalten
- Auf die neue Hardware konnte erst in der Woche nach Thanksgiving in den USA erstmals zugegriffen werden; ursprünglich waren 1 bis 2 Wochen Burn-in-Validierung geplant, bevor die Integration in den bestehenden Cluster erfolgen sollte
- Die Low-Level-Performance-Tests sahen zunächst gut aus
- Die Netzwerk-Tests mit iperf kamen pro Node nahe an 200Gb/s heran
- Auch die Basisleistung der NVMe-Laufwerke auf einigen Nodes wirkte plausibel
- Das Betriebssystem war jedoch auf allen 68 Nodes versehentlich nicht auf den internen Dell-BOSS-m.2-Boot-Laufwerken, sondern auf 2 OSD-Laufwerken installiert worden
- Statt des geplanten Tests mit 3 Nodes und 30 OSDs musste daher mit nur 8 NVMe pro Node getestet werden
- Die ersten Ceph-Ergebnisse lagen selbst unter Berücksichtigung der reduzierten OSD-Zahl deutlich unter den Erwartungen
- Nur Random Read lag halbwegs in einem akzeptablen Bereich, war aber noch nicht ausreichend
- Bei der Eingrenzung auf Tests mit einem einzelnen Node und einer einzelnen OSD zeigte sich ein abnormales Muster
- Ein System, das in Single-OSD-Tests gut lief, zeigte nach einem Test mit 8 OSDs schlechtere Leistung
- Danach blieb auch der Single-OSD-Test für einige Stunden langsam, bevor er sich erholte
- Ohne Multi-OSD-Tests blieb die Leistung dauerhaft hoch
- Bei direktem FIO auf die Laufwerke ließ sich dasselbe Problem nicht reproduzieren
- Während eines 8-OSD-Tests nutzte eine bestimmte OSD deutlich mehr CPU als die anderen
- Das OSD-Wallclock-Profil zeigte viel Zeit in
io_submit, ein Muster, das typischerweise auftritt, wenn die Laufwerks-Queue voll ist und der Kernel blockiert
Drei Korrekturen
-
BIOS-Performance-Modus und c-state
- Die erste Korrektur betraf den BIOS-Modus: Er stand nicht auf maximum performance, wodurch CPU-c-states aktiv waren
- Ceph reagiert sehr empfindlich auf die Latenz, die durch CPU-c-state-Wechsel entsteht
- Nach dem Umstellen auf maximum performance und dem Deaktivieren der c-states verbesserte sich die Leistung um 10 bis 20 %, das reichte aber noch nicht für die Zielwerte
-
IOMMU-Contention
- Das zweite Problem wurde durch ein Perf-Profiling auf Kernel-Seite sichtbar
- Während schlechter Läufe ging viel Zeit in
native_queued_spin_lock_slowpathund in IOMMU-DMA-Mapping-Pfade alloc_iovaiommu_dma_alloc_iovaiommu_dma_map_sgnvme_map_datanvme_queue_rq- Nach dem Deaktivieren der IOMMU im Kernel verbesserten sich die 4MB-Lese- und Schreibwerte im Test mit 8 Nodes deutlich
- Auch nach dieser Änderung blieb das Problem bei 4KB Random Write bestehen
-
RocksDB-Kompilierungs-Flags
- Das dritte Problem war, dass 4KB Random Write und die RocksDB-Compaction-Performance niedriger als erwartet ausfielen
- In der Vergangenheit waren ähnliche Symptome bei Ceph mit zwei Ursachen verbunden
- Kompilierung ohne TCMalloc-Unterstützung
- Kompilierung ohne passende cmake-Flags und Compiler-Optimierungen
- Die Upstream-Ceph-Ubuntu-Pakete enthielten TCMalloc
- In den Build-Logs der Ubuntu-Pakete für 17.2.7 zeigte sich jedoch, dass RocksDB nicht mit den korrekten Kompilierungs-Flags gebaut worden war
- Canonical und Gentoo hatten dieses Problem in ihren eigenen Builds bereits behoben
- Nutzer von Debian/Ubuntu cephadm mit Upstream-Containern scheinen nicht betroffen zu sein
- Nach dem Bauen angepasster 17.2.7-Pakete sank die Compaction-Zeit um etwa das Dreifache, und die 4KB-Random-Write-Performance verdoppelte sich
Skalierungstests in der ersten Woche 2024
- Am 2. Januar verzögerten großflächige Ausfälle in einem anderen verwandten Cluster die Performance-Tests
- Ab Freitag wurden CBT und die Tests neu aufgesetzt; diesmal konnten alle 10 Laufwerke pro Node verwendet werden
- Die Zahl der FIO-Clients wurde erhöht, sodass im Durchschnitt etwa 1 FIO-Client mit
io_depth128 pro OSD vorhanden war - Der Test mit 3 Nodes erreichte bei 4MB Random Read 63GiB/s
- Der Test mit 10 Nodes erreichte 213,5GiB/s
- Das entsprach einer nahezu linearen Skalierung gegenüber 3 Nodes, nämlich 98,4 %
- Zu diesem Zeitpunkt waren nur 63 der 68 Nodes verfügbar
- 32 Nodes mit 320 OSDs wurden auf einer Seite genutzt
- Auf 31 Client-Nodes liefen jeweils 10 FIO-Prozesse pro Node
- Im Maßstab von 320 OSDs wurden 635GiB/s Lesedurchsatz und mehr als 15 Millionen IOPS bei 4KB Random Read erreicht
- Durchschnittslatenz und Tail Latency blieben in den Skalierungstests konsistent
- Vermutlich wirkte sich aus, dass PG-Anzahl und Zahl der FIO-Clients zusammen mit den OSDs erhöht wurden
- Die Tests liefen bereits unter sehr hoher IO-Last; zusätzliche IOs steigerten die Leistung nicht weiter, sondern erhöhten nur die Latenz
1 TiB/s mit 630 OSDs erreicht
- Da keine zusätzlichen dedizierten Client-Nodes für Tests mit voller Kapazität verfügbar waren, wurden FIO-Prozesse gemeinsam mit den OSD-Nodes platziert
- Dadurch bestand eine Chance von 1/63, dass ein Client mit einer lokalen OSD kommunizierte, was einen kleinen Netzwerkvorteil bringt
- Umgekehrt kann die gemeinsame Platzierung von FIO-Clients auf OSD-Nodes auch Leistung kosten
- Die CBT-Bereitstellung mit 63 Nodes und 630 OSDs dauerte etwa 15 Minuten
- Der erste Versuch kam mit rund 950GiB/s dem Ziel von 1 TiB/s sehr nahe
- Danach wurden OSD-Shards und Async-Messenger-Threads reduziert und Reef-RocksDB-Tuning angewendet
- Die Leseleistung sank leicht, die Schreibleistung verbesserte sich
- Die Random-Write-Performance verbesserte sich um fast 20 %
- Der größere Effekt scheint von den Änderungen bei Shards und Threads gekommen zu sein
- Es gab auch Versuche, die PG-Anzahl zu verdoppeln und die Zahl der Clients erneut zu erhöhen
- 4MB Random Read verbesserte sich mit mehr Clients leicht
- Die IOPS bei kleinen Random Reads verschlechterten sich
- Bei 8 FIO pro Node, insgesamt 504 Prozessen, fiel die sequentielle Schreibleistung stark ab
- Als 504 FIO-Prozesse 4MB-Schreibvorgänge ausführten, wechselten einige PGs in den Zustand active+clean+laggy
- Obwohl der Durchsatz nur einen Teil der eigentlich möglichen Clusterleistung ausmachte, nahm die Zahl der laggy PGs mit der Zeit zu
- Bis zum Ende des Workloads erholte sich der Cluster aus diesem Zustand nicht
- Laut Ceph-Dokumentation bedeutet der Zustand laggy, dass Replikate neue Leases vom Primary nicht rechtzeitig bestätigen und IO dadurch vorübergehend angehalten wird
- Letztlich erwiesen sich die Standardwerte von Ceph mit 8 Shards, 2 Threads pro Shard und 3 msgr-Threads als am besten für 4MB-Lesevorgänge geeignet
- Unter den Bedingungen 256K PG, 630 OSD und 504 FIO-Client-Prozesse zeigte
ceph -s1,0 TiB/s read- Alle 630 OSDs waren up/in
- Alle 262145 PGs waren active+clean
- Angezeigt wurden 266,15k op/s für Leseoperationen
Ergebnisse mit 6+2 Erasure Coding
- Der tatsächlich geplante Zielcluster des Kunden nutzte 6+2 Erasure Coding, daher waren separate Tests nötig
- Für die EC-Tests wurden jene PG-, Shard- und Client-Werte gewählt, die sich in den vorherigen Tests bewährt hatten
- Da zu sehen war, dass die Async-Messenger-Threads stark ausgelastet waren, wurde ausprobiert, mehr als den Default zu verwenden
- Mit 4 bis 5 Async-msgr-Threads wurden folgende Werte erreicht
- Lesen: über 500GiB/s
- Schreiben: fast 400GiB/s
- Dass 6+2-EC-Lesen langsamer als 3-fach repliziertes Lesen ist, liegt am Unterschied beim Netzwerk-Overhead
- Bei Replikation liest die Primary-OSD lokale Daten und sendet sie an den Client; der Netzwerk-Overhead beträgt damit faktisch 1X
- Bei 6+2 EC muss die Primary zum Zusammensetzen des Objekts 5 der 6 Chunks von Replikaten lesen und sie dann an den Client senden
- Der gesamte Netzwerk-Overhead der Anfrage liegt damit grob bei
(1 + 5/6)X
- Beim Schreiben zeigt sich das umgekehrte Bild
- Bei 3-facher Replikation sendet der Client das Objekt an die Primary, die es dann an zwei Secondarys weiterleitet; der gesamte Netzwerk-Overhead beträgt 3X
- Bei EC müssen nur 7/8 Chunks an Secondarys gesendet werden, daher ist die Performance bei großen Schreibvorgängen höher
- Die IOPS bei kleinen IOs sind eine eigene Fragestellung
- Bei sehr kleinen Lese- und Schreibvorgängen spricht Ceph alle OSDs an, die an der PG des betreffenden Objekts beteiligt sind
- Selbst wenn sich die relevanten Daten nur in einem Chunk befinden, werden Daten von allen OSDs des Stripes geholt
- Clyso hat den PR zu Partial-Stripe-Reads bei Erasure Coding aus dem Sommer 2023 wiederbelebt, mit deutlicher Wirkung
- Ob er in Squid gemergt wird, ist noch unklar
Einfluss der msgr-Verschlüsselung
- Um die Auswirkungen bei Nutzung von Verschlüsselung auf msgr-Ebene abzuschätzen, wurden auch Tests mit msgr v2 encryption durchgeführt
- Sowohl bei 3-facher Replikation als auch bei 6+2 Erasure Coding wurden die Ergebnisse mit aktivierter Verschlüsselung mit den vorherigen Resultaten verglichen
- Der größte Effekt zeigte sich bei großen Lesevorgängen
- Von etwa 1 TiB/s fiel die Leistung auf rund 750GiB/s
- Die übrigen Werte zeigten ebenfalls Leistungsrückgänge, allerdings moderater und konsistent
- Gewünscht waren auch PG-Scaling-Tests und Kernel-RBD-Tests, doch das System musste an den Kunden zurückgegeben werden, um Re-Imaging und Integration durchzuführen
Zusammenfassung der höchsten Endergebnisse
- Die in den Tests erreichten Spitzenwerte waren wie folgt
| Kennzahl | 30 OSDs (3x) | 100 OSDs (3x) | 320 OSDs (3x) | 630 OSDs (3x) | 630 OSDs (EC62) |
|---|---|---|---|---|---|
| Co-located FIO | Nein | Nein | Nein | Ja | Ja |
| 4MB Read | 63 GiB/s | 214 GiB/s | 635 GiB/s | 1025 GiB/s | 547 GiB/s |
| 4MB Write | 15 GiB/s | 46 GiB/s | 133 GiB/s | 270 GiB/s | 387 GiB/s |
| 4KB Rand Read | 1.9M IOPS | 5.8M IOPS | 16.6M IOPS | 25.5M IOPS | 3.4M IOPS |
| 4KB Rand Write | 248K IOPS | 745K IOPS | 2.4M IOPS | 4.9M IOPS | 936K IOPS |
- Nach Abschluss der Tests wurde die gesamte Hardware neu aufgesetzt, und die neuen OSDs wurden im bestehenden HDD-Cluster des Kunden bereitgestellt
- Mit Dans upmap-remapped-Skript wurde die Migration gesteuert, und etwa 80 % der bestehenden Daten wurden auf NVMe-basierte OSDs verschoben
- Zunächst entschied man sich dagegen, sämtliche im Test verwendeten Tunings sofort zu übernehmen, sondern wollte das Verhalten des Clusters zuerst weitgehend mit der Standardkonfiguration beobachten
- Die Testdaten können künftig genutzt werden, um das System weiter zu tunen, falls beim Kunden Performance-Probleme auftreten
Verbleibende Aufgaben und Skalierungsgrenzen
- Das Problem mit laggy PGs unter großer Schreiblast muss gelöst werden
- Es ist nicht akzeptabel, dass Ceph bei wachsendem Schreib-Workload einbricht
- Diese Tests haben bestätigt, dass Ceph zwei 100GbE-NICs auslasten kann
- Um bei mehr als 10 NVMe-Laufwerken pro Node noch höheren Durchsatz zu erreichen, sind 200GbE oder mehr erforderlich
- Bei IOPS ist die Lage komplexer
- Die PG-Anzahl kann starken Einfluss haben
- Auch das Threading-Modell der OSDs spielt eine wichtige Rolle
- In mehreren Deployments wurde pro Node eine Grenze von etwa 400K bis 600K Random-Read-IOPS erreicht
- Als Ansatzpunkte für Verbesserungen gelten die Schnittstelle zwischen Async-msgr und Kernel sowie die Art, wie OSD-Threads aufwachen, wenn neue Arbeit in eine Shard-Queue gelangt
- Es wurden bereits Änderungen am OSD-Code vorgenommen, um unter hoher Last bessere Ergebnisse zu erzielen, allerdings auf Kosten schlechterer Latenz bei niedriger Last
- Für höhere IOPS sind mehrere Ansätze und möglicherweise eine teilweise Neuschreibung des OSD-Threading-Codes nötig
1 Kommentare
Meinungen auf Hacker News
Ceph hat eine interessante Geschichte.
Es wurde von den Gründern von DreamHost aus internem Bedarf heraus entwickelt, und DreamHost bot im Grunde schon Dienste wie VPS sowie gemanagte OS-/Datenbank-/App-Server an, bevor sich die Begriffe IaaS und PaaS in der Branche etabliert hatten.
Später wurde Ceph ausgegründet und von Red Hat übernommen.
https://en.wikipedia.org/wiki/DreamHost
Es gab keine Marketingtexte, bei denen jeder Satz auf Verkauf getrimmt war; es war einfach die Zeit, in der man teilte, woran man gerade herumspielte.
Soweit ich mich erinnere, war es das Uni-Projekt eines der Gründer, und die anderen Gründer unterstützten ihn und stiegen mit ein; Docker hatte meines Wissens einen ähnlichen Ursprung.
UCSC war ein Ort, aus dem viel gute Storage-Forschung hervorging.
Guter Artikel. Auch CERN hat kürzlich 1 TB/s erreicht, allerdings nicht mit Ceph, sondern mit EOS (https://cern.ch/eos).
https://www.home.cern/news/news/computing/exabyte-disk-stora...
Allerdings hat unser EOS-Cluster deutlich mehr Nodes und nutzt überwiegend HDDs. CERN setzt auch Ceph in großem Umfang ein.
Solche Experimente habe ich wirklich geliebt. Als Technical Lead bei Cisco hatte ich den Luxus, Kubernetes auf Bare Metal aufzusetzen und GlusterFS sowie Ceph selbst zu konfigurieren, um zu lernen und zu vergleichen, was besser ist.
Das war meiner Erinnerung nach etwa 2017/2018, eine gute Zeit. Auch dieser Artikel war sehr gut.
Einige NVMe-SSDs waren stärker genutzt als andere, was Unterschiede verursachte; es war wirklich eine völlig absurde Arbeit.
Jemand sollte versuchen, die Knotengröße weiter zu verkleinern. Das hier beschriebene System hat 10 Platten pro Knoten und etwa 300 W/Knoten, also rund 30 W pro Platte.
Der Overhead ist ziemlich groß, und schon für ein wenig Redundanz braucht man erheblichen Speicherplatz.
Mit etwas Engineering ließe sich das Ganze vermutlich auf ein Zehntel schrumpfen: ein kleiner Single-Board-Computer mit 4 PCIe-Lanes für NVMe, 2x10GbE (zwei SFP+-Sockets) und einer ausreichend schnellen ARM- oder RISC-V-CPU, plus eMMC oder SD-Slot zum Booten.
Damit käme man bis auf nur wenige Knoten herunter und würde außerdem die Gefahr verringern, dass bei einem einzelnen Ausfall auf einmal 10 Platten weg sind.
Viele solcher Systeme ließen sich wohl in ein 4U-Gehäuse packen, optional auch mit zwei vollständig unabhängigen Switches im selben Gehäuse, die die internen Knoten bündeln.
Wegen des armhf-Prozessors war die Installation wirklich schmerzhaft, aber sobald es lief, funktionierte es gut. Es war nur wegen der einzelnen 1-Gb-NIC langsam.
Damals war es nur zum Lernen gedacht.
[0] https://www.hardkernel.com/shop/odroid-hc2-home-cloud-two/
Ich werde bald zwei 7-W-ARM-Turing-RK1 bekommen, die jeweils über PCIe 3x4 auf 4 GB/s kommen, und das Turing-Pi-2-Cluster-Board kann im ITX-Formfaktor vier davon aufnehmen.
Bei Gesamtkosten von 820 Dollar erwarte ich mehr als 3 Gbps pro Watt.
Bisher sind die PCIe-Lanes der Flaschenhals. Selbst eine 90-Dollar-SSD mit 2 TB ist bei PCIe 4x4 mit 7 GB/s angegeben, daher sehe ich Single-Board-Computer noch nicht als optimale Lösung.
Die Ampere-Altra-Reihe scheint bei 40 W PCIe 4x128 zu unterstützen, daher könnte ein 1U-Blade mit 100G-Networking interessant sein.
Allerdings habe ich selbst im Homelab viele ARM-bezogene Bugs und fehlende Optimierungen gesehen, sodass solche Lösungen womöglich noch nicht reif fürs Rechenzentrum sind.
Um heute eine Ceph-Konfiguration mit 10-Gbps-Interfaces zu rechtfertigen, müsste sie wirklich klein und sehr günstig sein.
Bei einer so kleinen Größenordnung ist es wahrscheinlich besser, in jedem Server lokalen NVMe-Speicher zu haben.
Grob gerechnet: 1 TB/s × 8 Bit/Byte × 1024 GB/TB ÷ 34 Knoten ÷ 300 W.
Ein sehr effizientes ARM-System wie ein neuer Mac mini verbraucht bei interaktiver Nutzung etwa 10 W und kann ein 10-Gbps-Netzwerk bedienen, liegt also datenbezogen bei etwa 1 Gbps pro Watt.
Das heißt, der Cluster aus dem Original liegt grob in derselben Größenordnung bei Bit/s/Watt wie ein sehr effizientes ARM-System.
Ich glaube nicht, dass kleinere Knoten in der Praxis wirklich effizienter wären; eher könnten sie teurer werden. Die Performance pro Watt leistungsstarker Server ist heutzutage ziemlich gut.
Jedenfalls ist das Open-Source-Software auf Standardhardware, man kann es also für ein paar Hundert Dollar selbst ausprobieren.
Wenn Betriebssystem und NVMe-Gerät weit voneinander entfernt sind, muss der Controller aus den Requests die Absicht ableiten und Batching sowie Wear-Leveling bestmöglich erledigen, was zwangsläufig Ineffizienzen erzeugt.
Die neue FDP-Funktion (flexible data placement) ist ein Versuch, dem Betriebssystem mehr Kontrolle zu geben und das zu lösen.
Am besten wäre es, das auf die Seite des Host-Betriebssystems hochzuziehen und Flash möglichst als „riesiges, dummes Transistor-Array, das als PCIe-Gerät angebunden ist“ offenzulegen.
Wenn man Abstraktionsschichten entfernt, könnte man die gewünschten Systemparallelität vermutlich mit Hardware-Einheiten à la Atom erreichen, die eine integrierte 100-Gbps-NIC und proportional dazu Flash enthalten.
Es muss in der Geschichte einen Zeitpunkt gegeben haben, an dem die weltweit gespeicherte Gesamtmenge digitaler Daten erstmals 1 TiB erreicht hat.
Dieser Tag lag mit ziemlicher Sicherheit innerhalb der letzten 60 Jahre.
Und heute verschiebt irgendein ziemlich beliebiger Organisationsserver diese Datenmenge jede Sekunde. Nicht einmal ein Staat oder ein supranationales Forschungsprojekt.
Interessanter Artikel. Wir betreiben einen Ceph-Storage-Cluster, um unseren Docker-Layer-Cache vorzuhalten.
Nach dem Wechsel von EBS zu Ceph war der Unterschied im Durchsatz enorm. Der Schreibdurchsatz stieg von 146 MB/s und 3.000 IOPS auf 900 MB/s und 30.000 IOPS.
Das Beste daran ist, dass es fast einfach funktioniert. Abgesehen von gelegentlichen Dingen wie Filesystem-trim gibt es kaum etwas zu pflegen.
Für unser Cache-System war das eine enorme Verbesserung.
[0] https://depot.dev/blog/cache-v2-faster-builds
Am Ende sind wir in ein eigenes Rack umgezogen, haben die Kosten noch einmal auf fast ein Zehntel reduziert und wurden frei, weil wir interne Betriebskompetenz aufgebaut hatten.
Aus dem Blog wurde das nicht sofort klar.
Die schlimmsten Probleme, die ich mit dynamischem Storage innerhalb von Clustern hatte, waren keine reinen I/O-Probleme.
Es ging eher darum, dass die Storage-Controller-Software von Kubernetes mit Problemen aus der realen Welt nicht gut umgehen konnte, etwa wenn ein Pod stirbt und ein PVC erst nach einem sehr langen Timeout wieder angehängt wird, während der Pod im Zustand ContainerCreating bleibt, bis die PVC-Sperre freigegeben ist.
Das passierte in mehreren Clustern mit rook/ceph und Longhorn.
Ich frage mich, ob jemand Ceph in einem Homelab betrieben hat. Als ich mich zuletzt damit beschäftigt habe, waren die Hardware-Anforderungen ziemlich hoch
Wenn es gut läuft, ist es großartig, aber wenn Probleme auftreten, wird es zu einem enormen Kopfzerbrechen
Wenn dich Distributed Storage an sich interessiert, gibt es für Homelab-Setups bessere Optionen
seaweedfs war über Jahre hinweg sowohl in kleinem als auch in sehr großem Maßstab äußerst stabil, und wir haben tatsächlich eine Ceph-Produktionsumgebung darauf migriert
Longhorn war ebenfalls stabil, wenn man in der Kubernetes-Welt unterwegs ist
Auch GlusterFS ist weiterhin in Ordnung, wenn man weiß, worauf man sich einlässt
Es war aber sehr schwierig, eine brauchbare Performance zu erzielen, und in kleinen Clustern konnte der Metadata Daemon ziemlich leicht hängen bleiben
Am Ende, als der Spaß vorbei war, bin ich wieder zu ZFS auf einer einzelnen Maschine zurückgekehrt
Zunächst sollte man im Hinterkopf behalten, dass Ceph ein Distributed-Storage-System ist; mehrere Nodes sind also die Grundannahme
Zum Lernen kann man alles auf einer einzelnen Maschine virtualisieren, aber mit separaten physischen Maschinen ist es deutlich besser
Ceph bevorzugt ähnlich wie ZFS physischen Zugriff auf die Disks
Außerdem braucht es eine ordentliche Netzwerkverbindung. Ich denke, das ist der Teil, an den die meisten denken, wenn sie von den hohen Hardware-Anforderungen von Ceph sprechen
Idealerweise sollte es mindestens 10GbE sein, und für höhere Performance braucht man mehr. Besonders bei Vorgängen wie Backfill kann viel Netzwerk-Traffic anfallen
Wenn man günstig an Homelab-Hardware kommt, sind auch 25Gbps gut; 50Gbps ist technisch eher eine Sackgasse, und 100Gbps funktioniert gut
Für ein Homelab reichen aber auch günstige Mini-PCs oder NUCs mit 10GbE völlig aus, um akzeptable Performance und einen guten Lerneffekt zu bekommen
Man kann Ceph direkt auf Bare Metal installieren, oder, wenn man den Homelab-Kubernetes-Weg gehen möchte, Rook (https://rook.io/) verwenden
Hoffe, das hilft; wenn es weitere Fragen gibt, einfach Bescheid geben
Das kann man wirklich kaum als große Hardware bezeichnen
[1] https://ceph.io/en/news/blog/2022/install-ceph-in-a-raspberr...
Mindestens 10Gb, möglichst 40Gb oder mehr, und wenn man rotierende Festplatten nutzt, sind bei ein paar Nodes jeweils mindestens 6 Disks pro Node sinnvoll
Wenn alles SSDs sind, kann man die Zahl der Disks pro Node sehr wahrscheinlich deutlich reduzieren
Ich wollte sehen, wie sich 1 TiB/s mit den theoretischen Grenzen der tatsächlichen Hardware vergleichen lässt, also habe ich nachgerechnet.
Dieser Cluster besteht aus 68 Nodes, jeder davon ein Dell PowerEdge R6615 (https://www.delltechnologies.com/asset/en-us/products/server...).
Verwendet wird eine R6615-Konfiguration mit 10 U.2-Drive-Bays; ein U.2-Link überträgt Daten über vier PCIe-Gen4-Lanes. Eine PCIe-Lane liefert 16 Gbit/s, und dank 128b/132b-Encoding ist der Overhead mit etwa 3 % vernachlässigbar.
Damit liegt die maximale Link-Bandbreite eines U.2-Links bei 16×4=64 Gbit/s, also 8 Gbyte/s. Allerdings scheint das eingesetzte U.2-NVMe-Laufwerk, die Dell 15.36TB Enterprise NVMe Read Intensive AG, einen Lesedurchsatz von 7 Gbyte/s zu haben (https://www.serversupply.com/SSD%20W-TRAY/NVMe/15.36TB/DELL/...); der U.2-Link mit 8 Gbyte/s ist also nicht der Flaschenhals.
Da es pro Node 10 U.2-Laufwerke gibt, kann jeder Node lokal bis zu 10×7=70 Gbyte/s Lese-I/O liefern.
Die Netzwerkbandbreite jedes Nodes beträgt jedoch nur 200 Gbit/s (2×100GbE Mellanox ConnectX-6), also 25 Gbyte/s. Das bedeutet: Bei Remote-Reads kann die Fähigkeit der Laufwerke von 70 Gbyte/s nicht ausgeschöpft werden, und das Netzwerk ist der Flaschenhals.
Unter der Annahme, dass es keine weiteren Netzwerkengpässe gibt, können 68 Nodes 68×25=1700 Gbyte/s an Netzwerk-Leseleistung bereitstellen. Der Autor hat tatsächlich 1 TiB/s gebenchmarkt, genauer 1025 GiB/s=1101 Gbyte/s, also rund 65 % des theoretischen Maximums von 1700 Gbyte/s.
Das ist ziemlich ordentlich, aber wenn alle Nodes ihre 200-Gbit/s-Netzwerklinks gleichzeitig vollständig auslasten könnten, wäre theoretisch noch etwas mehr möglich.
Beim Lesen des gesamten Artikels hatte ich den Eindruck, dass die Komplexität von Ceph die CPU ziemlich stark belastet. Dass allein das Nicht-Kompilieren von Modulen mit -O2 (das vom Autor verlinkte „Fix Three“: https://bugs.launchpad.net/ubuntu/+source/ceph/+bug/1894453) bei reinen I/O-Workloads dazu führen kann, dass „einige Workloads bis zu 5-mal langsamer werden können“ (https://bugs.gentoo.org/733316), ist ziemlich überraschend.
Dass OSD-Threads übermäßig CPU verschwenden, weil sie IOMMU-Spinlocks halten, ist ebenfalls merkwürdig. Ich stimme der Schlussfolgerung zu, dass das OSD-Threading-Modell nicht optimal ist.
Ein vergleichsweise einfacher synthetischer 100-%-Read-Benchmark sollte keine Threading-Contention offenlegen – jedenfalls dann nicht, wenn dieser Teil der Ceph-Softwarearchitektur gut entworfen wäre. Das ist ein behebbares Problem, daher hoffe ich, dass die Ceph-Entwickler ihm eine höhere Priorität geben.
Im Upstream-Ceph-Lab gibt es Systeme mit der vorherigen Generation desselben 1U-Chassis von Dell und AMD-Rome-Prozessoren; bei ähnlicher Größe, etwa 30 OSDs, liefern sie vergleichbare Performance, ohne dieses Problem zu zeigen.
Der Kunde sagte, er habe dieses Problem in seinem Datacenter auch früher schon gesehen, und hofft, zusammen mit AMD die Ursache finden zu können.
Im vergangenen Sommer habe ich ein wenig daran gearbeitet, das bestehende Threading-Modell der OSDs provisorisch zu verbessern: Double Buffering beim Handoff zwischen async msgr und Worker-Threads sowie adaptives Aufwecken von Threads und Ähnliches.
Unter Last konnten Performance und Effizienz deutlich gesteigert werden, allerdings um den Preis höherer Latenz bei niedriger Last. Ceph ist standardmäßig sehr aggressiv darin, Threads aufzuwecken, wenn auf einem bestimmten Shard neues I/O eintrifft.
Ich habe das mit einem anderen Core-Entwickler besprochen, und wir kamen beide zu dem Schluss, dass eine grundlegende Überarbeitung des Threading-Codes sinnvoller ist.
Bei 320 OSDs wären das etwa 1,6 TiB/s.
Zumindest waren das die Zahlen, die ich gefunden habe. Es gibt auch nicht gerade viele Reviews solcher Enterprise-NVMe-Disks.
Trotzdem scheint der Wert gut zu den NICs zu passen. In dieser Größenordnung dürften die meisten Workloads auf der Storage-Ebene wie Random I/O aussehen.
Erstaunlich ist, warum man sich für 1U-Nodes, die schwerer zu kühlen sind, und eine Konfiguration mit 10 SSDs/2×100Gb-NIC entschieden hat.
Mit 2U-Nodes, 24 SSDs und 2×200Gb- oder 400Gb-NICs hätte man den Netzwerkengpass beseitigen und dank größerer, langsamerer Lüfter sowie weniger CPU-Paketen auch den Stromverbrauch senken können. Die Zahl der Kerne pro Sockel hätte sogar höher sein können.
Weniger Nodes vergrößern zwar die Ausfallauswirkung, aber bei etwa 34 Nodes scheint mir das kein allzu großes Problem zu sein.
Mit weniger Nodes hätte man vermutlich auch ein flacheres Netzwerk mit etwa vier Switches aufbauen können.
Racks und Switches sind bereits vorhanden und werden auch für viele andere Zwecke genutzt, daher ist der durch Ceph zusätzlich belegte physische Platz sehr gering :)