Bei der Einrichtung eines neuen Proxmox VE Ceph Clusters sind viele Faktoren relevant. Die richtige Dimensionierung der Hardware, die Konfiguration von Ceph, sowie das richtige Testen der Datenträger, des Netzwerks und des Ceph-Pools haben große Auswirkungen auf die erzielbare Performance des Systems. In diesem Artikel erfahren Sie, wie Sie einen Proxmox Ceph Cluster planen. Der Artikel hilft Ihnen auch bei der Fehlersuche im Falle von Performance-Problemen von Ceph.
Folgende Begriffe werden im Artikel verwendet:
Node: Ein Node ist ein Host-System bzw. Server im Cluster.OSD: ein OSD (Object Storage Daemon) ist ein Prozess, der für die Speicherung von Daten auf einem Datenträger verantwortlich ist.Cluster: Ein Cluster ist der Zusammenschluss mehrerer Hosts-Systeme in einem gemeinsamen Storage-Netzwerk.Pool: Ist der Gesamtspeicher, der aus OSDs und Nodes gebildet wird.CRUSH: Der CRUSH-Algorithmus berechnet die Speicherorte, um zu bestimmen, wie die Daten gespeichert und abgerufen werden sollen.[1]In einer Minimalkonfiguration besteht ein Ceph Cluster aus 3 Nodes mit je 4 Datenträgern (OSDs), welche zusammen den Pool aus 12 Datenträgern bilden.
Bei Proxmox VE Ceph Pools ist der Standard-Replikations-Faktor SIZE=3, d.h. es wird 1 Kopie pro Host vorgehalten.
Im folgenden werden Faktoren aus Cluster Konfiguration und Hardware-Zusammenstellung erläutert, welche die Leistung eines Ceph Clusters beeinflussen.
Die Leistung in einem Ceph-Cluster wird auf Konfigurations-Ebene hauptsächlich durch 3 Faktoren bestimmt: Die Anzahl der OSDs, die Anzahl der Nodes und das Pool-Setup.
Mehr OSDs ermöglichen eine höhere parallele Verarbeitung und Verteilung der Last.
Eine höhere Anzahl an OSDs erhöht jedoch auch die Anforderungen an die Netzwerkbandbreite, die Prozessor-Leistung und die benötigte Menge an Arbeitsspeicher im Cluster.
Mehr Nodes im Cluster bieten mehr Ressourcen und mehr Platz für die Verteilung von OSDs. Somit verteilen sich Lese- und Schreibzugriffe auf das Storage über mehrere Nodes.
Daher hat auch die Anzahl der Nodes einen Einfluss auf die Anforderungen an die Netzwerkbandbreite. Eine ausreichende Anzahl an Switch Ports und entsprechende Switching Capacity[2] sollte vorhanden sein.
Das Pool-Setup beeinflusst die Verfügbarkeit und die Sicherheit der Daten im Cluster. Ein Pool besteht aus einer Gruppe von OSDs, die für die Speicherung von Daten verantwortlich sind. Ein Replikationsfaktor legt fest, wie oft ein Objekt auf mehrere OSDs via CRUSH repliziert wird. Ein höherer Replikationsfaktor erhöht die Datensicherheit, erfordert jedoch auch mehr Speicherplatz. Zudem erhöht er die Latenz für Schreibvorgänge, da Replikate in der Regel mindestens 2 mal geschrieben werden müssen (bei Replikationsfaktor SIZE=3), damit ein ACK (Acknowledgement) an den Storage-Client geschickt wird.
Bei einer zu geringen Anzahl an OSDs konzentriert sich die Last auf zu wenige OSDs, was zu Engpässen und einer schlechten Leistung führen kann. Eine zu hohe Anzahl an OSDs kann jedoch auch zu höheren Anforderungen an die Netzwerkbandbreite und Ressourcen des Clusters führen. Hier gilt es eine passende Balance zu finden und ausreichend Ressourcen für das Vorhaben einzuplanen.
Es ist wichtig, die Anzahl der OSDs und Knoten sowie das Netzwerk für Ceph sorgfältig zu planen und zu überwachen, um die Leistung und die Verfügbarkeit des Ceph-Clusters zu maximieren und Fallstricke zu vermeiden.
Je nach geplanter Konfiguration und Größe des Clusters muss die Hardware sorgfältig ausgewählt werden, um die maximale Leistung des Clusters zu gewährleisten.
Die Hauptkomponenten sind dabei CPU, RAM, Netzwerkkomponenten und Datenträger.
Je nach Anzahl an Ceph Datenträgern sollte man entsprechende Ressourcen für CPU und RAM einplanen.[3][4][5] Je mehr OSDs im System konfiguriert werden, desto mehr CPU Kerne und RAM sind erforderlich.
Da die Dimensionierung auch abhängig von der Auswahl und Anzahl der Ceph Dienste (Ceph MON, Ceph MGR, Ceph MDS) ist, muss die Dimensionierung individuell gestaltet und sorgfältig abgewogen werden.
Die wohl größte Rolle für die Performance in Ceph hat die Konfiguration des Netzwerks.
Sehr viele der in Ceph relevanten Dienste sind komplett netzwerkbasiert. Die einzelnen Nodes kommunizieren rein über das Netzwerk miteinander und tauschen ständig Daten und Informationen untereinander aus. Sie schreiben auch die Datenreplikate über das Netzwerk auf die jeweils anderen Datenträger (OSDs) der Nodes. Das hat natürlich große Auswirkungen auf die Leistung, die man für ein performantes Ceph-Netzwerk benötigt.
Bei der Dimensionierung gilt:
Zusätzlich kann der Einsatz von Jumbo-Frames eine Verbesserung der Ceph-Performance erzielen.
Die Leistung eines Ceph-Systems wird bedeutend durch die Leistung der verwendeten Datenträger beeinflusst. Kommen SSDs zum Einsatz, sollten folgende Faktoren bei der Auswahl berücksichtigt werden:
DWPD (Drive Writes Per Day): Dieser Wert gibt an, wie oft ein Datenträger pro Tag beschrieben werden kann, bevor er potentiell ausfallen könnte. Ein höherer DWPD-Wert bedeutet, dass der Datenträger langlebiger ist.TBW (Total Bytes Written): Dieser Wert gibt die Gesamtmenge an Daten an, die auf einen Datenträger geschrieben werden können, bevor er potentiell ausfallen könnte. Ein höherer TBW-Wert bedeutet, dass der Datenträger langlebiger ist.IOPS (Input/Output Operations Per Second): Dieser Wert gibt die Anzahl der Ein- und Ausgabeoperationen pro Sekunde an, die ein Datenträger ausführen kann. Typischerweise werden dabei 4 kB große Blockoperationen betrachtet. Ein höherer IOPS-Wert bedeutet, dass mehr Operationen pro Sekunde durchgeführt werden können. Relevant ist dabei auch die Queue Depth, die beschreibt wie viele I/O Operationen parallel vom Testsystem durchgeführt werden.Throughput: Dieser Wert (dt. Datendurchsatz) gibt die Geschwindigkeit an, mit der Daten auf einen Datenträger geschrieben oder von einem Datenträger gelesen werden können. Ein höherer Throughput-Wert bedeutet, dass der Datenträger schneller ist.Latency: Latency (dt. Latenzzeit) bezieht sich auf die Zeit, die ein Datenträger benötigt, um auf eine Anfrage vollständig zu reagieren, sowohl beim Schreiben als auch beim Lesen von Daten.PLP (Powerloss Protection): Der Cache des Datenträgers wird bei einem Stromausfall des Servers noch komplett auf den Datenträger geschrieben und geht somit nicht verloren. Dies bringt den generellen Vorteil, dass das Write-ACK an den Storage-Client bereits nach dem Schreiben in den Cache erfolgen kann, was in einer erhöhten Leistung resultieren kann.Im folgenden werden Mittel beschrieben, wie verschiedene Leistungsdaten erhoben werden können. Betrachtet werden die Leistung von Datenträger, Netzwerk und Pool.
Um die Leistung eines einzelnen Datenträgers zu testen, kann das Tool fio verwendet werden. Fio ermöglicht es, verschiedene Schreib- und Lesevorgänge auf dem Datenträger auszuführen und die Ergebnisse in Bezug auf IOPS und Throughput auszugeben. Der folgende Befehl kann verwendet werden, um den Datenträger /dev/nvme0 auf IOPS zu testen, unter Verwendung der Blockgröße 4K:
fio --ioengine=libaio --filename=/dev/nvme0n1 --direct=1 --sync=1 --rw=write --bs=4K --numjobs=1 --iodepth=1 --runtime=60 --time_based --name=fio
| Parameter | Erklärung |
|---|---|
| ioengine=libaio | Legt die I/O-Engine für fio fest |
| filename=/dev/nvme0n1 | Legt das zu testende Gerät fest |
| direct=1 | Aktiviert direkten I/O ohne Cache (kein Pagecache, kein RAM) |
| sync=1 | Aktiviert synchronen I/O-Modus (synchronized writes) |
| rw=write | Legt den Schreib-Modus für das Test fest |
| bs=4K | Legt die Block-Größe des Tests fest |
| numjobs=1 | Legt die Anzahl der parallelen Jobs fest |
| iodepth=1 | Legt die IO-Tiefe pro Job fest |
| runtime=60 | Legt die Dauer des Tests in Sekunden fest |
| time_based | Aktiviert zeitgesteuerten Modus für den Test |
| name=fio | Legt den Namen des Tests fest |
Dieser Befehl führt einen Schreibtest mit einer Blockgröße von 4K auf dem Datenträger /dev/nvme0 durch. Der Test wird für eine Dauer von 60 Sekunden durchgeführt und die Ergebnisse in Bezug auf IOPS ausgegeben.
Wichtig: die nachfolgenden Ergebnisse haben wir analog zum Proxmox Ceph Performance Paper von der Proxmox Server Solutions GmbH durchgeführt, diese Tests sind nicht geschönt und spiegeln die absolute Minimal-Performance eines einzelnen Datenträgers wieder, da keine Parallelisierung (Number of Jobs = 1) und IO-Depth entsprechend eingestellt wurde. Wir tun dies, damit Sie einen Vergleich ziehen können zu den Werten von Proxmox. Die tatsächliche Performance innerhalb der VM hängt von vielen anderen Faktoren ab und sollte nicht mit den Werten hier verglichen werden, da es hierzu sehr viele Optimierungen und Verbesserungen gibt.
root@PMX1:~# fio --ioengine=libaio --filename=/dev/nvme0n1 --direct=1 --sync=1 --rw=write --bs=4K --numjobs=1 --iodepth=1 --runtime=60 --time_based --name=fio
fio: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
fio-3.25
Starting 1 process
Jobs: 1 (f=1): [W(1)][100.0%][w=445MiB/s][w=114k IOPS][eta 00m:00s]
fio: (groupid=0, jobs=1): err= 0: pid=2028745: Wed Feb 1 10:37:38 2023
write: IOPS=114k, BW=444MiB/s (465MB/s)(26.0GiB/60001msec); 0 zone resets
slat (nsec): min=1092, max=125185, avg=1238.68, stdev=769.33
clat (nsec): min=251, max=859795, avg=7242.66, stdev=1484.45
lat (usec): min=7, max=861, avg= 8.51, stdev= 1.70
clat percentiles (usec):
| 1.00th=[ 8], 5.00th=[ 8], 10.00th=[ 8], 20.00th=[ 8],
| 30.00th=[ 8], 40.00th=[ 8], 50.00th=[ 8], 60.00th=[ 8],
| 70.00th=[ 8], 80.00th=[ 8], 90.00th=[ 8], 95.00th=[ 8],
| 99.00th=[ 9], 99.50th=[ 9], 99.90th=[ 13], 99.95th=[ 17],
| 99.99th=[ 118]
bw ( KiB/s): min=433496, max=460096, per=100.00%, avg=454720.47, stdev=4372.66, samples=119
iops : min=108374, max=115024, avg=113680.13, stdev=1093.17, samples=119
lat (nsec) : 500=0.01%, 750=0.01%, 1000=0.01%
lat (usec) : 2=0.01%, 4=0.01%, 10=99.78%, 20=0.18%, 50=0.02%
lat (usec) : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
cpu : usr=11.52%, sys=23.95%, ctx=6816318, majf=0, minf=14
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=0,6816793,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
WRITE: bw=444MiB/s (465MB/s), 444MiB/s-444MiB/s (465MB/s-465MB/s), io=26.0GiB (27.9GB), run=60001-60001msec
Disk stats (read/write):
nvme0n1: ios=92/6805234, merge=0/0, ticks=2/45719, in_queue=45722, util=99.91%
Ein weiterer wichtiger Faktor, der die Ceph-Performance beeinflussen kann, ist die Netzwerkverbindung. Um die Leistung des Ceph-Netzwerks zu testen, kann das Tool iperf3 verwendet werden. Mit iperf3 können die Bandbreite und die Latenz des Netzwerks gemessen werden. Hierzu erstellt man am besten zwei iperf3 Server und verbindet sich mit einem Client zu diesen iperf-Servern parallel, damit man die maximale Bandbreite des Netzwerks ausreizen kann.
Wichtig: Sollten Sie nicht die gewünschte Bandbreite erreichen, erhöhen Sie die Anzahl der iperf3-Server und iperf3-Clients.
# iperf Server auf Server 1 und Server 3 root@PMX1:~# iperf3 -s C-m root@PMX3:~# iperf3 -s C-m # Zwei parallele iperf Clients auf Server 2 root@PMX2:~# iperf3 -c 192.168.99.34 -t 3600 C-m root@PMX2:~# iperf3 -c 192.168.99.36 -t 3600 C-m # Überprüfen der Netzwerklast des Ceph Bonds: bond1 root@PMX2:~# nload bond1 C-m
Innerhalb Ceph kann man auf verschiedenen Ebenen Performance-Tests durchführen. Diese sind grundsätzlich beim Erst-Setup zur Kontrolle einer korrekten Konfiguration sinnvoll, können aber auch nützlich für das Debugging von Performance-Problemen sein.
Um die Leistung eines einzelnen OSD-Datenträgers zu testen, kann das Tool tell osd bench verwendet werden. Der Befehl ceph tell osd.X benchgibt die Leistungsdaten des OSD-Datenträgers mit der ID X zurück.
root@PMX4:~# ceph tell osd.1 bench
{
"bytes_written": 1073741824,
"blocksize": 4194304,
"elapsed_sec": 0.572842187,
"bytes_per_sec": 1874411222.4402215,
"iops": 446.89446030622042
}
Die Ausgabe enthält folgende Informationen:
| Parameter | Erklärung |
|---|---|
| bytes_written | Die Anzahl der Bytes, die während des Tests geschrieben wurden |
| blocksize | Die Größe der Datenblöcke, die während des Tests verwendet wurden |
| elapsed_sec | Die Zeitdauer des Tests in Sekunden |
| bytes_per_sec | Die durchschnittliche Schreibrate in Bytes pro Sekunde |
| iops | Die durchschnittliche Anzahl der Schreiboperationen pro Sekunde (IOPS) |
Die Ausgabe zeigt, dass während des Tests 1 GB (1.073.741.824 Bytes) mit einer Blockgröße von 4 MB (4.194.304 Bytes) in 0,57 Sekunden geschrieben wurde. Das entspricht einer durchschnittlichen Schreibrate von 1,87 GB (1.874.411.222 Bytes) pro Sekunde und einer durchschnittlichen IOPS-Anzahl von 446 (unter Berücksichtigung von 4 MB Blocksize).
Man kann den Befehl natürlich auch für IOPS mit einer Blocksize von 4K durchführen:
root@PMX4:~# ceph tell osd.1 bench 12288000 4096
{
"bytes_written": 12288000,
"blocksize": 4096,
"elapsed_sec": 0.043518787000000003,
"bytes_per_sec": 282360811.20551449,
"iops": 68935.744923221311
}
Hier ergeben sich aufgrund der Blockgröße 4K ein höherer Wert bei den IOPS und zwar: 68.935 IOPS.
| Die Performance-Tests auf Ceph Pool Ebene benötigen - um einen realistischen Gesamtwert der Leistung zu erhalten - mehrfache Ausführung und Parallelisierung. Das heißt konkret: ein einzelner Performance-Test spiegelt niemals die Gesamtleistung des Systems wieder. Bei einem 3-Node Ceph Cluster führen wir z.B. 6 bis 8 parallele RADOS-Bench Writes aus, damit man das Netzwerk im Ceph komplett auslasten kann. Bitte beachten Sie dies bei der Ausführung dieser Kommandos. |
|---|
Ein Pool ist eine Gruppe von OSDs, die gemeinsam Daten speichern und verwalten. Für einen optimalen Pool ist es wichtig, die richtige Anzahl an PGs (Placement Groups) zu wählen. PGs sind kleine Gruppen innerhalb der OSDs, die für die Verteilung und Redundanz von Daten verantwortlich sind. Eine zu geringe Anzahl an PGs kann zu einer schlechten Verteilung der Daten führen, während eine zu hohe Anzahl an PGs zu einer unnötigen Belastung der Ressourcen führen kann.
Wichtig: Um die tatsächlichen Performance in einem Ceph Cluster messen zu können, sollten Sie die nachfolgenden Befehle mehrfach und parallel ausführen. Hierzu eignet sich der Einsatz von tmux.
Mittels des PG-Autoscalers kann die optimale Anzahl an PGs je Pool automatisch von Ceph errechnet werden. Dies ist allerdings nur empfehlenswert, wenn Sie kein untypisches Daten-Wachstum (mehrere 100 GB) oder untypische Daten-Abnahme im System haben.
Sonst müsste der PG-Autoscaler anhand des stetigen Daten-Wachstums oder Daten-Abnahme ständig die optimale Anzahl an PGs erhöhen und oder verringern. Eine Erhöhung oder Reduktion der PGs bedeutet aber auch immer eine Neuverteilung der Daten im Ceph. Dies würde zu einem ständigen Daten-Rebalancing führen, was schlecht für die Cluster-Performance und die Datenträger ist.
Da der PG-Autoscaler die Konfiguration der PGs stark erleichtert, empfehlen wir seinen Einsatz für Unternehmen mit normalem Datenzuwachs.
Um die Leistung eines Ceph-Pools zu testen, kann das Tool rados bench verwendet werden. Mit rados bench können Schreibvorgänge auf dem Pool durchgeführt und die Ergebnisse in Bezug auf IOPS und Throughput ausgegeben werden.
rados bench -p vm_nvme 600 write -t 16 --object_size=4MB --no-cleanup
| Parameter | Erklärung |
|---|---|
| -p vm_nvme | Gibt den Namen des Pools an, auf dem der Test durchgeführt wird |
| 600 | Legt die Dauer des Tests in Sekunden fest |
| write | Gibt an, dass der Test Schreiboperationen durchführt |
| -t 16 | Legt die Anzahl der parallelen Threads[6] fest, die verwendet werden sollen |
| --object_size=4MB | Legt die Blocksize fest |
| --no-cleanup | Legt fest, dass die erstellten Testdaten nach dem Test nicht gelöscht werden (da wir von diesen lesen werden, brauchen wir diese noch) |
Die Ergebnisse werden in Bytes pro Sekunde ausgegeben und der Test wird mit 16 parallelen Threads durchgeführt.
Total time run: 600.017 Total writes made: 383501 Write size: 4194304 Object size: 4194304 Bandwidth (MB/sec): 2556.6 Stddev Bandwidth: 1098.42 Max bandwidth (MB/sec): 4620 Min bandwidth (MB/sec): 1540 Average IOPS: 639 Stddev IOPS: 274.605 Max IOPS: 1155 Min IOPS: 385 Average Latency(s): 0.0250308 Stddev Latency(s): 0.0178465 Max latency(s): 0.15803 Min latency(s): 0.00460356
Ebenso können Lesevorgänge auf dem Pool durchgeführt werden, um die Leseleistung des Pools zu testen. Der folgende Befehl kann verwendet werden, um den Lesedurchsatz eines Ceph-Pools mit einer Blocksize von 4MB zu testen:
rados bench -p vm_nvme 60 read -t 16 --object_size=4MB
| Parameter | Funktion |
|---|---|
| -p vm_nvme | Gibt den Namen des Pools an, auf dem der Test durchgeführt wird |
| 60 | Legt die Dauer des Tests in Sekunden fest |
| seq | Gibt an, dass der Test mit sequentielle Lesevorgänge durchführt wird |
| -t 16 | Legt die Anzahl der parallelen Threads fest, die verwendet werden sollen |
Dieser Befehl führt einen Lesedurchsatz-Test auf dem Pool vm_nvme durch, bei dem sequentielle Lesevorgänge durchgeführt werden. Der Test wird für eine Dauer von 60 Sekunden durchgeführt und die Ergebnisse werden in Bytes pro Sekunde ausgegeben. Der Test wird mit 16 parallelen Threads durchgeführt.
Total time run: 60.0276 Total reads made: 53525 Read size: 4194304 Object size: 4194304 Bandwidth (MB/sec): 3566.69 Average IOPS: 891 Stddev IOPS: 20.0448 Max IOPS: 935 Min IOPS: 842 Average Latency(s): 0.0176248 Max latency(s): 0.0879089 Min latency(s): 0.00350174
Um einzelne OSD-Datenträger unter Ceph zu messen, kann der Befehl ceph osd perf verwendet werden. Dieser Befehl gibt detaillierte Leistungsdaten für jeden OSD im Cluster zurück. Der Befehl zeigt tatsächlich die ID des OSD und die Commit- und Apply-Latenz an.
Commit-Latenz ist die Zeit, die ein OSD benötigt, um das Journal auf den Datenträger zu schreiben.Apply-Latenz ist die Zeit, die ein OSD benötigt, um eine Schreiboperation auf seine lokale Festplatte zu übertragen. Es ist also die Zeit, die vergeht, bis eine Schreiboperation endgültig auf dem OSD gespeichert wurde.Eine hohe Commit- oder Apply-Latenz kann darauf hindeuten, dass der OSD ausgelastet ist und nicht schnell genug schreiben kann, was die Leistung des gesamten Ceph-Clusters beeinträchtigen kann. Eine niedrige Commit- und Apply-Latenz hingegen deutet darauf hin, dass der OSD korrekt funktioniert und der darunterliegende Datenträger keine Problem aufweist.
Folgende Faktoren beeinflussen die Ceph Performance:
Eine sorgfältige Überwachung und Messung dieser Faktoren kann dazu beitragen, die Leistung des Ceph-Systems zu optimieren. Hier empfehlen wir zum Beispiel den Einsatz von checkMK.
|
Autor: Jonas Sterr Ich beschäftige mich mit den Themen Software Defined Storage, Proxmox Virtualisierung auf Basis von KVM, QEMU & Ceph im Produktmanagement der Thomas-Krenn.AG in Freyung. Proxmox ist meine absolute Leidenschaft und ich freue mich gerne über Kontaktanfragen und einen Austausch auf LinkedIn.
|