Wahl des CEPH. Teil 1
Wir hatten fünf Stände, zehn optische Switches, konfiguriertes BGP, ein paar Dutzend SSDs und eine Menge SAS-Festplatten in allen Farben und Größen, dazu proxmox und den Wunsch, die gesamte Statik in ein eigenes S3-Speicher zu integrieren. Es wäre nicht nötig gewesen für die Virtualisierung, aber wenn man opensource nutzt, sollte man sein Hobby bis zum Ende verfolgen. Das einzige, was mich störte, war das BGP. Es gibt niemanden in der Welt, der hilfloser, verantwortungsloser und unmoralischer ist als das interne Routing über BGP. Und ich wusste, dass wir ziemlich bald darin eintauchen würden.

Die Aufgabe war banal – ein CEPH war vorhanden, funktionierte aber nicht besonders gut. Es musste "gut" gemacht werden.
Der Cluster, der mir zur Verfügung gestellt wurde, war heterogen, hastig konfiguriert und praktisch nicht optimiert. Er bestand aus zwei Gruppen verschiedener Nodes, mit einem gemeinsamen Netzwerk, das sowohl die Rolle des Cluster- als auch des öffentlichen Netzwerks erfüllte. Die Nodes waren mit vier Arten von Festplatten ausgestattet – zwei Arten von SSDs, die in zwei separaten Placement-Regeln zusammengefasst wurden, und zwei Arten von HDDs unterschiedlicher Größe in einer dritten Gruppe. Das Problem mit den unterschiedlichen Größen wurde mit verschiedenen Gewichten der OSDs gelöst.
Die Konfiguration wurde in zwei Teile unterteilt – Optimierung des Betriebssystems und Optimierung des CEPH selbst und seiner Einstellungen.
Optimierung des OS
Netzwerk
Eine hohe Latenz wirkte sich sowohl beim Schreiben als auch bei der Balance aus. Beim Schreiben, weil der Client keine Bestätigung über das erfolgreiche Schreiben erhält, bis die Datenreplikate in anderen Placement-Gruppen den Erfolg bestätigen. Da die Regeln zur Verteilung der Replikate im CRUSH-Plan nur eine Replikat pro Host vorsahen, wurde das Netzwerk immer genutzt.
Deshalb habe ich zuerst entschieden, das aktuelle Netzwerk leicht zu optimieren, während ich versuchte, zu überzeugen, auf separate Netzwerke umzusteigen.
Zunächst habe ich die Einstellungen der Netzwerkkarten angepasst. Ich begann mit der Konfiguration der Warteschlangen:
Was war vorhanden:
ethtool -l ens1f1
root@ceph01:~# ethtool -l ens1f1
Channel parameters for ens1f1:
Pre-set maximums:
RX: 0
TX: 0
Other: 1
Combined: 63
Current hardware settings:
RX: 0
TX: 0
Other: 1
Combined: 1
root@ceph01:~# ethtool -g ens1f1
Ring parameters for ens1f1:
Pre-set maximums:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
Current hardware settings:
RX: 256
RX Mini: 0
RX Jumbo: 0
TX: 256
root@ceph01:~# ethtool -l ens1f1
Channel parameters for ens1f1:
Pre-set maximums:
RX: 0
TX: 0
Other: 1
Combined: 63
Current hardware settings:
RX: 0
TX: 0
Other: 1
Combined: 1Es ist deutlich zu sehen, dass die aktuellen Parameter weit von den Maximalwerten entfernt sind. Ich habe sie erhöht:
root@ceph01:~#ethtool -G ens1f0 rx 4096
root@ceph01:~#ethtool -G ens1f0 tx 4096
root@ceph01:~#ethtool -L ens1f0 combined 63Leitend durch einen hervorragenden Artikel
habe ich die Länge der Warteschlange erhöht txqueuelen von 1000 bis 10 000
root@ceph01:~#ip link set ens1f0 txqueuelen 10000Und entsprechend der Dokumentation von Ceph
erhöht MTU auf 9000.
root@ceph01:~#ip link set dev ens1f0 mtu 9000Hinzugefügt in /etc/network/interfaces, damit alles oben Genannte beim Start geladen wird
cat /etc/network/interfaces
root@ceph01:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto ens1f0
iface ens1f0 inet manual
post-up /sbin/ethtool -G ens1f0 rx 4096
post-up /sbin/ethtool -G ens1f0 tx 4096
post-up /sbin/ethtool -L ens1f0 combined 63
post-up /sbin/ip link set ens1f0 txqueuelen 10000
mtu 9000
auto ens1f1
iface ens1f1 inet manual
post-up /sbin/ethtool -G ens1f1 rx 4096
post-up /sbin/ethtool -G ens1f1 tx 4096
post-up /sbin/ethtool -L ens1f1 combined 63
post-up /sbin/ip link set ens1f1 txqueuelen 10000
mtu 9000Nach dem, was ich in diesem Artikel gelesen habe, begann ich, die Einstellungen des Kernels 4.15 durchdacht anzupassen. Angesichts von 128 GB RAM auf den Nodos entstand eine gewisse Konfigurationsdatei für sysctl
cat /etc/sysctl.d/50-ceph.conf
net.core.rmem_max = 56623104
#Maximale Größe des Empfangspuffers für Daten für alle Verbindungen 54M
net.core.wmem_max = 56623104
#Maximale Größe des Sendepuffers für alle Verbindungen 54M
net.core.rmem_default = 56623104
#Standardgröße des Empfangspuffers für alle Verbindungen. 54M
net.core.wmem_default = 56623104
#Standardgröße des Sendepuffers für alle Verbindungen 54M
# für jeden Socket
net.ipv4.tcp_rmem = 4096 87380 56623104
#Vektor (Minimum, Standard, Maximum) Variable in der tcp_rmem-Datei
# enthält 3 Ganzzahlen, die die Größe des Empfangspuffers für TCP-Sockets definieren.
# Minimum: Jeder TCP-Socket hat das Recht, diesen Speicher bei
# seiner Erstellung zu verwenden. Die Möglichkeit, einen solchen Puffer zu nutzen,
# wird selbst bei Erreichen des Grenzwerts (mittlerer Speicherbedarf) garantiert.
# Die Standardgröße des minimalen Puffers beträgt 8 KB (8192).
#Standardwert: Die Menge an Speicher, die für den Standard-Übertragungspuffer
# von TCP-Sockets zulässig ist. Dieser Wert ersetzt
# die Einstellung /proc/sys/net/core/rmem_default, die von anderen Protokollen verwendet wird.
# Der standardmäßig verwendete Pufferwert beträgt normalerweise
# 87830 Byte. Dies definiert die Fenstergröße 65535 mit
# dem standardmäßig festgelegten Wert tcp_adv_win_scale und tcp_app_win = 0,
# was etwas kleiner ist als der standardmäßig festgelegte Wert von tcp_app_win.
# Maximum: maximale Größe des Puffers, die automatisch
# für das Empfangen von TCP-Socket zugewiesen werden kann. Dieser Wert hebt nicht das Maximum auf,
# das in der Datei /proc/sys/net/core/rmem_max festgelegt ist. Bei „statischer“
# Speicherzuweisung mit SO_RCVBUF hat dieser Parameter keine Bedeutung.
net.ipv4.tcp_wmem = 4096 65536 56623104
net.core.somaxconn = 5000
# Maximale Anzahl der offenen Sockets, die auf Verbindungen warten.
net.ipv4.tcp_timestamps=1
# Erlaubt die Verwendung von Zeitstempeln (timestamps) gemäß RFC 1323.
net.ipv4.tcp_sack=1
# Erlaubt die Verwendung von selektiven Bestätigungen im TCP-Protokoll
net.core.netdev_max_backlog=5000 (Standard 1000)
# Maximale Anzahl der Pakete in der Warteschlange zur Verarbeitung, wenn
# das Interface Pakete schneller empfängt, als der Kernel sie verarbeiten kann.
net.ipv4.tcp_max_tw_buckets=262144
# Maximale Anzahl der Sockets, die gleichzeitig im STATUS TIME-WAIT sind.
# bei Überschreitung dieses Schwellenwerts wird der „übrige“ Socket zerstört und eine
# Nachricht in das Systemprotokoll geschrieben.
net.ipv4.tcp_tw_reuse=1
#Erlaubt die Wiederverwendung von TIME-WAIT-Sockets in Fällen,
# in denen das Protokoll dies für sicher hält.
net.core.optmem_max=4194304
#Erhöht den maximalen Gesamtpufferplatz, der ALLOCATABLE
# in Seiten (4096 Byte) gemessen wird.
net.ipv4.tcp_low_latency=1
#Erlaubt dem TCP/IP-Stack, der niedrigen Latenzzeit
# den Vorzug vor höherer Bandbreite zu geben.
net.ipv4.tcp_adv_win_scale=1
# Diese Variable beeinflusst die Berechnung der Menge an Speicher im Socket-Puffer,
# der für die Größe des TCP-Fensters und für den Anwendungs-Puffer reserviert wird.
# Wenn der Wert von tcp_adv_win_scale negativ ist, wird zur Berechnung der Größe
# der folgende Ausdruck verwendet:
# Bytes - bytes2 hoch -tcp_adv_win_scale
# wobei bytes die Fenstergröße in Bytes ist. Wenn der Wert tcp_adv_win_scale
# positiv ist, wird zur Bestimmung der Größe der folgende Ausdruck verwendet:
# Bytes - bytes2 hoch tcp_adv_win_scale
# Die Variable nimmt einen ganzzahligen Wert an. Der Standardwert beträgt 2,
# d.h. für den Anwendungs-Puffer wird ¼ des Volumens, das durch die Variable
# tcp_rmem bestimmt wird, reserviert.
net.ipv4.tcp_slow_start_after_idle=0
# Mechanismus zum Neustart des langsamen Starts, der den Wert des Fensters
# bei einer Überlast zurücksetzt, wenn die Verbindung einen bestimmten Zeitraum nicht genutzt wurde.
# Es ist besser, SSR auf dem Server zu deaktivieren, um die Leistung
# langlebiger Verbindungen zu verbessern.
net.ipv4.tcp_no_metrics_save=1
#Messwerte der TCP-Verbindung nicht im Cache speichern, wenn diese geschlossen wird.
net.ipv4.tcp_syncookies=0
#Deaktiviert den Mechanismus zum Senden von syncookie.
net.ipv4.tcp_ecn=0
#Explicit Congestion Notification (Explizite Überlastbenachrichtigung) in
# TCP-Verbindungen. Wird verwendet, um über die Entstehung eines „Staus“
# auf dem Weg zu einem bestimmten Host oder Netzwerk zu informieren. Kann verwendet werden, um den
# sendenden Host zu informieren, dass er die Übertragungsgeschwindigkeit über
# einen bestimmten Router oder eine Firewall reduzieren muss.
net.ipv4.conf.all.send_redirects=0
# Deaktiviert die Ausgabe von ICMP Redirect … an andere Hosts. Diese Option muss unbedingt
# aktiv sein, wenn der Host als Router jeglicher Art fungiert.
# Wir haben keine Routing-Funktion.
net.ipv4.ip_forward=0
#Deaktiviert das Forwarding. Wir sind kein Gateway, Docker auf Maschinen ist nicht gestartet,
#wir brauchen das nicht.
net.ipv4.icmp_echo_ignore_broadcasts=1
#Nicht auf ICMP ECHO-Anfragen antworten, die über Broadcast-Pakete gesendet werden.
net.ipv4.tcp_fin_timeout=10
#bestimmt die Zeit, die der Socket im FIN-WAIT-2-Zustand nach seiner
# Schließung durch die lokale Seite bleibt. Standard 60.
net.core.netdev_budget=600 # (Standard 300)
# Wenn die Ausführung von Software-Interrupts nicht lange genug dauert,
# könnte die Rate des eingehenden Datenverkehrs die Fähigkeit des Kernels
# übersteigen, den Puffer zu leeren. Infolgedessen werden die Puffer der NIC überlaufen, und der Verkehr geht verloren.
# Manchmal ist es notwendig, die Dauer der SoftIRQs
# (Software-Interrupts) mit der CPU zu erhöhen. Dafür ist netdev_budget verantwortlich.
# Der Standardwert beträgt 300. Dieser Parameter zwingt den SoftIRQ-Prozess dazu,
# 300 Pakete von der NIC zu verarbeiten, bevor er die CPU freigibt.
net.ipv4.tcp_fastopen=3
# TFO TCP Fast Open
# wenn sowohl der Client als auch der Server Unterstützung für TFO haben, die durch
# ein spezielles Flag im TCP-Paket angezeigt wird. In unserem Fall ist es ein Placebo, sieht einfach
# gut aus.CLuster-Netzwerk wurde auf separaten 10Gbps-Netzwerkschnittstellen in ein separates flaches Netzwerk выделена. Auf jeder Maschine wurden Netzwerkkarten mit zwei Ports installiert. Mellanox 10/25 Gbps, angeschlossen an zwei separate 10Gbps Switches. Die Aggregation erfolgte mit OSPF, da das Bonding mit LACP aus irgendeinem Grund eine maximale Gesamtbandbreite von 16 Gbps zeigte, während OSPF erfolgreich beide zehn auf jeder Maschine vollständig auslastete. In den weiteren Plänen war vorgesehen, ROCE auf diesen Mellanox zu verwenden, um die Latenz zu verringern. So wurde dieser Teil des Netzwerks konfiguriert:
- Da die Maschinen externe IP-Adressen auf BGP haben, benötigen wir die Software — (genauer gesagt, zu dem Zeitpunkt, als der Artikel geschrieben wurde, war dies ) bereits installiert.
- Insgesamt gab es auf den Maschinen zwei Netzwerke mit jeweils zwei Schnittstellen — insgesamt 4 Ports. Eine Netzwerkkarte mit zwei Ports zeigte auf die Fabrik, und dort war BGP konfiguriert, die andere — mit zwei Ports zeigte auf zwei verschiedene Switches und auf sie wurde OSPF aktiviert.
Details zur OSPF-Konfiguration: Die Hauptaufgabe besteht darin, zwei Links zu aggregieren und Fehlertoleranz zu gewährleisten.
zwei Netzwerkschnittstellen sind in zwei einfache flache Netzwerke konfiguriert — 10.10.10.0/24 und 10.10.20.0/24
1: ens1f0: mtu 9000 qdisc mq state UP group default qlen 1000
inet 10.10.10.2/24 brd 10.10.10.255 scope global ens1f0
2: ens1f1: mtu 9000 qdisc mq state UP group default qlen 1000
inet 10.10.20.2/24 brd 10.10.20.255 scope global ens1f1worauf die Maschinen einander sehen.
DISK
Der nächste Schritt war, die Arbeit der Festplatten zu optimieren. Für SSD änderte ich den Scheduler auf noop, für HDD — deadline. Grob gesagt funktioniert NOOP nach dem Prinzip „Wer zuerst kommt, mahlt zuerst“, was auf Englisch als „FIFO (First In, First Out)“ bekannt ist. Anfragen werden in der Reihenfolge bearbeitet, in der sie eingehen. DEADLINE ist stärker auf das Lesen ausgelegt, zudem erhält der Prozess aus der Warteschlange während der Operation nahezu monopolartigen Zugriff auf die Festplatte. Für unser System ist das hervorragend geeignet — denn mit jeder Festplatte arbeitet nur ein Prozess — OSD-Daemon.
(Interessierte können hier mehr über den IO-Scheduler lesen:
Für diejenigen, die lieber auf Russisch lesen: )
In den Empfehlungen zur Optimierung von Linux wird ebenfalls empfohlen, nr_request zu erhöhen.
nr_requests
Der Wert von nr_requests bestimmt die Anzahl der I/O-Anfragen, die zwischengespeichert werden, bevor der I/O-Scheduler Daten an das Blockgerät sendet oder von ihm empfängt. Wenn Sie eine RAID-Karte oder ein Blockgerät verwenden, das eine größere Warteschlange verarbeiten kann, als der I/O-Scheduler eingestellt ist, kann eine Erhöhung des Wertes von nr_requests dazu beitragen, die Durchsatzrate zu verbessern und die Serverlast zu reduzieren, wenn große Mengen an I/O auf dem Server auftreten. Wenn Sie Deadline oder CFQ als Scheduler verwenden, wird empfohlen, den Wert von nr_requests auf das Zwei- oder Dreifache der Wartetiefe zu setzen.
ABER! Die Bürger, die Entwickler von CEPH sind überzeugt, dass ihr Prioritätssystem besser funktioniert

WBThrottle und/oder nr_requests
WBThrottle und/oder nr_requests
Der Dateispeicher verwendet zwischengespeicherte I/O-Operationen zum Schreiben; dies bringt eine Vielzahl von Vorteilen, wenn das Log des Dateispeichers auf einem schnelleren Medium liegt. Kundenanfragen werden benachrichtigt, sobald die Daten im Log gespeichert sind, und dann später mit der Standardfunktionalität von Linux auf die eigentliche Festplatte zurückgeschrieben. Dies ermöglicht es OSD-Spindelplatten, eine Schreiblatency ähnlich der von SSDs bei kleinen Schreiboperationen bereitzustellen. Diese verzögerte Schreibpolitik ermöglicht es dem Kernel zudem, I/O-Anfragen an die Festplatte umzusortieren, in der Hoffnung, sie entweder zusammenzuführen oder den vorhandenen Köpfen der Festplatte einen optimaleren Pfad über ihre Platten zu ermöglichen. Das Endergebnis ist, dass Sie etwas mehr I/O-Operationen aus jeder Festplatte herausholen können, als dies bei direkten oder synchronen I/O-Operationen möglich wäre.
Es tritt jedoch ein Problem auf, wenn das Volumen der eingehenden Schreibvorgänge in diesem Ceph-Cluster alle Möglichkeiten der zugrunde liegenden Festplatten übersteigt. In einem solchen Szenario kann die Gesamtzahl der I/O-Operationen, die auf die Speicherung auf der Festplatte warten, unkontrolliert steigen und zu Warteschlangen von I/O-Operationen führen, die die gesamte Festplatte und die Ceph-Queues füllen. Leseanfragen sind besonders betroffen, da sie zwischen Schreibanfragen stecken bleiben, die mehrere Sekunden für die Rückschreibung auf das Hauptlaufwerk benötigen können.
Um dieses Problem zu überwinden, verfügt Ceph über einen in den Dateispeicher integrierten Mechanismus zur Drosselung der verzögerten Schreibvorgänge (writeback) mit dem Namen WBThrottle. Dieser wurde entwickelt, um das Gesamtvolumen der verzögerten E/A-Vorgänge zu begrenzen, die in die Warteschlange gestellt werden können und ihren Rückgabeverlauf früher beginnen als dies natürlich durch den Kernel geschehen würde. Leider zeigt das Testen, dass die standardmäßig festgelegten Werte das vorhandene Verhalten möglicherweise nicht auf ein Niveau drosseln, das die Auswirkungen auf die Latenz von Lesevorgängen verringern könnte. Anpassungen können dieses Verhalten ändern und die Gesamtlängen der Schreibwarteschlangen reduzieren sowie eine weniger starke Beeinträchtigung ermöglichen. Es gibt jedoch einen Kompromiss: Wenn Sie die maximale Anzahl der zulässigen Warteschreibvorgänge verringern, können Sie die Fähigkeit des Kernels herabsetzen, die Effizienz bei der Reihenfolge der ankommenden Anfragen zu maximieren. Es ist ratsam, sich zu überlegen, was für Ihren spezifischen Anwendungsfall und die Arbeitslasten wichtiger ist, und die Einstellungen entsprechend anzupassen.
Um die Tiefe der Warteschlange für verzögerte Schreibvorgänge zu verwalten, können Sie entweder die maximale Anzahl der ausstehenden E/A-Vorgänge verringern, indem Sie die WBThrottle-Einstellungen anwenden, oder den maximalen Wert für ausstehende Operationen auf Blockebene im Kernel selbst verringern. Beides kann effektiv dasselbe Verhalten steuern, und Ihre Präferenzen werden die Implementierung dieser Einstellung bestimmen.
Es ist auch wichtig zu beachten, dass das bestehende Prioritätssystem von Ceph auf der Festplattenebene effizienter für kürzere Abfragen ist. Durch die Verringerung der Gesamtwarteschlange zu diesem Festplattenort verschiebt sich die Hauptlage des Wartens in Ceph, wo es mehr Kontrolle darüber hat, welche Priorität eine E/A-Operation hat. Betrachten wir folgendes Beispiel:
echo 8 > /sys/block/sda/queue/nr_requestsALLGEMEIN
Und noch einige Kernel-Einstellungen, mit denen Sie Ihr System sanfter und geschmeidiger machen und ein wenig mehr Leistung aus der Hardware herauspressen können.
cat /etc/sysctl.d/60-ceph2.conf
kernel.pid_max = 4194303
# In jeder Maschine gibt es 25 Laufwerke, daher haben wir mit vielen Prozessen gerechnet.
kernel.threads-max=2097152
# Threads, natürlich auch.
vm.max_map_count=524288
# Erhöhte Anzahl der Speicherbereichskarten des Prozesses.
# Wie in der Dokumentation zu den Kernel-Variablen angegeben
# Werden die Speicherbereichskarten als Nebenwirkung des Aufrufs
# malloc, direkt durch mmap, mprotect und madvise sowie beim Laden
# gemeinsamer Bibliotheken verwendet.
fs.aio-max-nr=50000000
# Optimieren von Input-Output-Parametern
# Der Linux-Kernel stellt eine Funktion für asynchronen, nicht-blockierenden Input-Output (AIO) bereit,
# die es dem Prozess ermöglicht, mehrere Input-Output-Operationen
# gleichzeitig zu initiieren, ohne auf den Abschluss einer von ihnen zu warten.
# Dies hilft, die Leistung von Anwendungen zu steigern,
# die Datenverarbeitung und Input-Output überlappen können.
# Der Parameter aio-max-nr definiert die maximale Anzahl von erlaubten
# gleichzeitigen Anfragen.
vm.min_free_kbytes=1048576
# Die minimale Größe des freien Speichers, die aufrechterhalten werden muss.
# Auf 1 GB eingestellt, was für den Betrieb des Betriebssystems völlig ausreichend ist,
# und es hilft, den OOM Killer für OSD-Prozesse zu vermeiden. Auch wenn der Speicher
# im Überfluss vorhanden ist, schadet ein Puffer nicht.
vm.swappiness=10
# Wir sagen, dass Swap verwendet werden soll, wenn noch 10 % Speicher frei sind.
# Auf Maschinen mit 128 GB RAM sind 10 % also 12 GB. Mehr als ausreichend für den Betrieb.
# Der Standardwert von 60 % ließ das System ins Stocken geraten, indem es in den Swap ging,
# während noch viel Speicher frei war.
vm.vfs_cache_pressure=1000
# Erhöhen von den standardmäßigen 100. Wir zwingen den Kernel, ungenutzte
# Speicherseiten aus dem Cache aktiver zu entladen.
vm.zone_reclaim_mode=0
# Erlaubt, weniger oder mehr aggressive Ansätze zur
# Speicherwiederherstellung zu bestimmen, wenn der Speicher in der Zone zur Neige geht.
# Wenn er auf null gesetzt ist, findet in der Zone keine Wiederherstellung statt.
# Für Datei-Server oder Workloads
# ist es vorteilhaft, wenn ihre Daten im Cache gehalten werden, zone_reclaim_mode
# sollte deaktiviert bleiben, da der Cache-Effekt
# wahrscheinlich wichtiger sein wird als der Standort der Daten.
vm.dirty_ratio=20
# Der Prozentsatz des RAMs, der für "schmutzige" Seiten reserviert werden kann.
# Berechnet aus einer groben Schätzung:
# Das System hat 128 GB Speicher.
# Ungefähr 20 SSDs, für die in den CEPH-Einstellungen
# 3 GB RAM für das Caching reserviert sind.
# Ungefähr 40 HDDs, für die dieser Parameter 1 GB beträgt.
# 20 % von 128 sind 25.6 GB. Insgesamt bleiben im Falle einer maximalen Speicherauslastung
# noch 2.4 GB für das System. Das sollte ausreichen, um zu überleben und zu warten,
# bis die Kavallerie anrückt, sprich der DevOps, der alles repariert.
vm.dirty_background_ratio=3
# Der Prozentsatz des Systemspeichers, der mit schmutzigen Seiten gefüllt werden kann,
# bevor die Hintergrundprozesse pdflush/flush/kdmflush sie auf die Festplatte schreiben.
fs.file-max=524288
# Und wahrscheinlich werden wir deutlich mehr geöffnete Dateien haben als standardmäßig angegeben. Eintauchen in CEPH
Einstellungen, auf die ich näher eingehen möchte:
cat /etc/ceph/ceph.conf
osd:
journal_aio: true # Drei Parameter, die
journal_block_align: true # direktes i/o
journal_dio: true # auf das Journal
journal_max_write_bytes: 1073714824 # Etwas die maximale Größe dehnen
# der einmalig im Journal geschriebene Operation
journal_max_write_entries: 10000 # Und die Anzahl gleichzeitiger Einträge
journal_queue_max_bytes: 10485760000
journal_queue_max_ops: 50000
rocksdb_separate_wal_dir: true # Wir haben uns entschieden, ein separates wal zu erstellen
# Wir haben sogar versucht, dafür etwas zu bekommen
# NVMe
bluestore_block_db_create: true # Und für das Journal ein separates Gerät
bluestore_block_db_size: '5368709120 #5G'
bluestore_block_wal_create: true
bluestore_block_wal_size: '1073741824 #1G'
bluestore_cache_size_hdd: '3221225472 # 3G'
# großer Arbeitsspeicher ermöglicht
# die Speicherung von relativ großen Mengen
bluestore_cache_size_ssd: '9663676416 # 9G'
keyring: /var/lib/ceph/osd/ceph-$id/keyring
osd_client_message_size_cap: '1073741824 #1G'
osd_disk_thread_ioprio_class: idle
osd_disk_thread_ioprio_priority: 7
osd_disk_threads: 2 # Anzahl der Threads beim Daemon für eine Festplatte
osd_failsafe_full_ratio: 0.95
osd_heartbeat_grace: 5
osd_heartbeat_interval: 3
osd_map_dedup: true
osd_max_backfills: 2 # Anzahl gleichzeitiger Fülloperationen auf ein OSD.
osd_max_write_size: 256
osd_mon_heartbeat_interval: 5
osd_op_threads: 16
osd_op_num_threads_per_shard: 1
osd_op_num_threads_per_shard_hdd: 2
osd_op_num_threads_per_shard_ssd: 2
osd_pool_default_min_size: 1 # Eigenschaften der Gier. Der Speicherplatz wurde sehr schnell
osd_pool_default_size: 2 # eng, weil wir
# die Anzahl der
# Datenreplikate reduziert haben.
osd_recovery_delay_start: 10.000000
osd_recovery_max_active: 2
osd_recovery_max_chunk: 1048576
osd_recovery_max_single_start: 3
osd_recovery_op_priority: 1
osd_recovery_priority: 1 # Parameter, den wir bei Bedarf anpassen
osd_recovery_sleep: 2
osd_scrub_chunk_max: 4Einige Parameter, die in der QA-Version 12.2.12 getestet wurden, fehlen in der Version Ceph 12.2.2, zum Beispiel. osd_recovery_threads. Daher war geplant, auf der Produktion auf 12.2.12 zu aktualisieren. Die Praxis hat die Kompatibilität in einem Cluster zwischen den Versionen 12.2.2 und 12.2.12 gezeigt, was ein Rolling Update ermöglicht.
Testcluster
Natürlich war es für die Tests erforderlich, die gleiche Version wie im Live-Betrieb zu haben, aber zum Zeitpunkt, als ich mit dem Cluster arbeitete, gab es im Repository nur eine neuere Version. Nachdem wir gesehen hatten, dass die Unterschiede in der Minor-Version nicht sehr groß sind (1393 Zeilen in den Konfigurationen gegen 1436 in der neuen Version), beschlossen wir, mit der neuen Version zu testen (wir müssen sowieso aktualisieren, warum also mit altem Kram arbeiten)
Das einzige, was wir von der alten Version beibehalten haben, ist das Paket ceph-deploy, da einige Dienstprogramme (und einige Mitarbeiter) auf deren Syntax ausgelegt waren. Die neue Version unterschied sich erheblich, hatte jedoch keinen Einfluss auf die Funktionalität des Clusters, sodass wir sie beibehielten. 1.5.39
Da das Team von ceph-disk deutlich darauf hinweist, dass es veraltet ist und die geschätzten Kollegen die ceph-volume-Befehle verwenden sollten, begannen wir, OSD genau mit diesem Befehl zu erstellen, ohne Zeit mit veralteten Dingen zu verschwenden.
Der Plan war folgender: Ein Spiegel aus zwei SSD-Laufwerken zu erstellen, auf denen wir die Journale der OSDs ablegen, die ihrerseits auf spindelbetriebenen SAS-Laufwerken liegen. So schützen wir uns vor Datenproblemen beim Ausfall eines Laufwerks mit einem Journal.
Der Cluster wurde nach der Dokumentation erstellt.
cat /etc/ceph/ceph.conf
root@ceph01-qa:~# cat /etc/ceph/ceph.conf # vorbereitete Konfiguration
[client]
rbd_cache = true
rbd_cache_max_dirty = 50331648
rbd_cache_max_dirty_age = 2
rbd_cache_size = 67108864
rbd_cache_target_dirty = 33554432
rbd_cache_writethrough_until_flush = true
rbd_concurrent_management_ops = 10
rbd_default_format = 2
[global]
auth_client_required = cephx
auth_cluster_required = cephx
auth_service_required = cephx
cluster network = 10.10.10.0/24
debug_asok = 0/0
debug_auth = 0/0
debug_buffer = 0/0
debug_client = 0/0
debug_context = 0/0
debug_crush = 0/0
debug_filer = 0/0
debug_filestore = 0/0
debug_finisher = 0/0
debug_heartbeatmap = 0/0
debug_journal = 0/0
debug_journaler = 0/0
debug_lockdep = 0/0
debug_mon = 0/0
debug_monc = 0/0
debug_ms = 0/0
debug_objclass = 0/0
debug_objectcatcher = 0/0
debug_objecter = 0/0
debug_optracker = 0/0
debug_osd = 0/0
debug_paxos = 0/0
debug_perfcounter = 0/0
debug_rados = 0/0
debug_rbd = 0/0
debug_rgw = 0/0
debug_throttle = 0/0
debug_timer = 0/0
debug_tp = 0/0
fsid = d0000000d-4000-4b00-b00b-0123qwe123qwf9
mon_host = ceph01-q, ceph02-q, ceph03-q
mon_initial_members = ceph01-q, ceph02-q, ceph03-q
public network = 8.8.8.8/28 # Adresse natürlich geändert ))
rgw_dns_name = s3-qa.meinunternehmen.ru # und diese Adresse geändert
rgw_host = s3-qa.meinunternehmen.ru # und diese auch
[mon]
mon allow pool delete = true
mon_max_pg_per_osd = 300 # mehr als dreihundert Platzierungsgruppen
# auf einer Festplatte haben wir uns nicht getraut
# auch wenn der Parameter natürlich von der Anzahl der Pools,
# deren Größen und der Anzahl der OSD abhängt. Wenige, aber gesunde PGs
# sind ebenfalls keine beste Wahl – die Ausgewogenheit leidet
mon_osd_backfillfull_ratio = 0.9
mon_osd_down_out_interval = 5
mon_osd_full_ratio = 0.95 # vorerst bei SSD-Festplatten ist der Speicher für deren
# Protokoll dasselbe Gerät wie für OSD
# wir haben entschieden, dass 5% des Festplattenspeichers (der selbst 1.2Tb groß ist)
# völlig ausreichen sollten, und korrelierend mit dem Parameter
# bluestore_block_db_size plus Variabilität bei größeren
# Platzierungsgruppen
mon_osd_nearfull_ratio = 0.9
mon_pg_warn_max_per_osd = 520
[osd]
bluestore_block_db_create = true
bluestore_block_db_size = 5368709120 #5G
bluestore_block_wal_create = true
bluestore_block_wal_size = 1073741824 #1G
bluestore_cache_size_hdd = 3221225472 # 3G
bluestore_cache_size_ssd = 9663676416 # 9G
journal_aio = true
journal_block_align = true
journal_dio = true
journal_max_write_bytes = 1073714824
journal_max_write_entries = 10000
journal_queue_max_bytes = 10485760000
journal_queue_max_ops = 50000
keyring = /var/lib/ceph/osd/ceph-$id/keyring
osd_client_message_size_cap = 1073741824 #1G
osd_disk_thread_ioprio_class = idle
osd_disk_thread_ioprio_priority = 7
osd_disk_threads = 2
osd_failsafe_full_ratio = 0.95
osd_heartbeat_grace = 5
osd_heartbeat_interval = 3
osd_map_dedup = true
osd_max_backfills = 4
osd_max_write_size = 256
osd_mon_heartbeat_interval = 5
osd_op_num_threads_per_shard = 1
osd_op_num_threads_per_shard_hdd = 2
osd_op_num_threads_per_shard_ssd = 2
osd_op_threads = 16
osd_pool_default_min_size = 1
osd_pool_default_size = 2
osd_recovery_delay_start = 10.0
osd_recovery_max_active = 1
osd_recovery_max_chunk = 1048576
osd_recovery_max_single_start = 3
osd_recovery_op_priority = 1
osd_recovery_priority = 1
osd_recovery_sleep = 2
osd_scrub_chunk_max = 4
osd_scrub_chunk_min = 2
osd_scrub_sleep = 0.1
rocksdb_separate_wal_dir = true# создаем мониторы
root@ceph01-qa:~#ceph-deploy mon create ceph01-q
# генерируем ключи для аутентификации нод в кластере
root@ceph01-qa:~#ceph-deploy gatherkeys ceph01-q
# Это если поштучно. Если у нас несколько машин доступны - те, которые описаны в конфиге в секции
# mon_initial_members = ceph01-q, ceph02-q, ceph03-q
# можно запустить эти две команды в виде одной
root@ceph01-qa:~#ceph-deploy mon create-initial
# Положим ключи в указанные в конфиге места
root@ceph01-qa:~#cat ceph.bootstrap-osd.keyring > /var/lib/ceph/bootstrap-osd/ceph.keyring
root@ceph01-qa:~#cat ceph.bootstrap-mgr.keyring > /var/lib/ceph/bootstrap-mgr/ceph.keyring
root@ceph01-qa:~#cat ceph.bootstrap-rgw.keyring > /var/lib/ceph/bootstrap-rgw/ceph.keyring
# создадим ключ для управления кластером
root@ceph01-qa:~#ceph-deploy admin ceph01-q
# и менеджер, плагинами управлять
root@ceph01-qa:~#ceph-deploy mgr create ceph01-qDas erste, worüber ich in der Arbeit dieser Version von ceph-deploy mit dem Cluster der Version 12.2.12 gestolpert bin, ist ein Fehler beim Versuch, einen OSD mit db auf einem Software-RAID zu erstellen —
root@ceph01-qa:~#ceph-volume lvm create --bluestore --data /dev/sde --block.db /dev/md0
blkid konnte keine PARTUUID für das Gerät: /dev/md1 erkennenTatsächlich zeigt blkid keine PARTUUID an, ich musste die Partitionen per Hand erstellen:
root@ceph01-qa:~#parted /dev/md0 mklabel GPT
# Es werden viele Partitionen benötigt,
# ohne GPT lassen sie sich nicht erstellen
# Die Größe der Partition haben wir oben in der Konfiguration angegeben = bluestore_block_db_size: '5368709120 #5G'
# Ich habe 20 Festplatten für OSD, es ist mühsam, Partitionen manuell zu erstellen
# deshalb habe ich eine Schleife gemacht
root@ceph01-qa:~#for i in {1..20}; do echo -e "nnnn+5Gnw" | fdisk /dev/md0; doneScheinbar ist alles bereit, versuchen wir es erneut, einen OSD zu erstellen, und erhalten den folgenden Fehler (der übrigens im Produktionsumfeld nicht reproduziert wurde)
beim Erstellen eines OSD vom Typ bluestore ohne Angabe des Pfades zu WAL, aber mit Angabe von db
root@ceph01-qa:~#ceph-volume lvm create --bluestore --data /dev/sde --block.db /dev/md0
stderr: 2019-04-12 10:39:27.211242 7eff461b6e00 -1 bluestore(/var/lib/ceph/osd/ceph-0/) _read_fsid unlesbare uuid
stderr: 2019-04-12 10:39:27.213185 7eff461b6e00 -1 bdev(0x55824c273680 /var/lib/ceph/osd/ceph-0//block.wal) konnte nicht geöffnet werden, Fehler: (22) Ungültiges Argument
stderr: 2019-04-12 10:39:27.213201 7eff461b6e00 -1 bluestore(/var/lib/ceph/osd/ceph-0/) _open_db add block device(/var/lib/ceph/osd/ceph-0//block.wal) zurückgegeben: (22) Ungültiges Argument
stderr: 2019-04-12 10:39:27.999039 7eff461b6e00 -1 bluestore(/var/lib/ceph/osd/ceph-0/) mkfs fehlgeschlagen, (22) Ungültiges Argument
stderr: 2019-04-12 10:39:27.999057 7eff461b6e00 -1 OSD::mkfs: ObjectStore::mkfs Fehlgeschlagen mit Fehler (22) Ungültiges Argument
stderr: 2019-04-12 10:39:27.999141 7eff461b6e00 -1 ** FEHLER: Fehler beim Erstellen des leeren Object Stores in /var/lib/ceph/osd/ceph-0/: (22) Ungültiges ArgumentWenn jedoch auf demselben Mirror (oder an einem anderen Ort nach Wahl) eine weitere Partition für WAL erstellt und bei der Erstellung von OSD angegeben wird, verläuft alles reibungslos (abgesehen von der getrennten WAL, die Sie möglicherweise nicht wollten).
Da es jedoch sowieso in fernen Plänen war, WAL auf NVMe auszulagern, war die Praxis nicht umsonst.
root@ceph01-qa:~#ceph-volume lvm create --bluestore --data /dev/sdf --block.wal /dev/md0p2 --block.db /dev/md1p2Wir haben Monitore, Manager und OSD erstellt. Jetzt möchten wir sie unterschiedlich gruppieren, da geplant ist, Festplatten verschiedener Typen zu haben — schnelle Pools auf SSD und große, langsame auf SAS-Platten.
Wir gehen davon aus, dass die Server jeweils 20 Festplatten haben, die erste Zehn ist ein Typ, die zweite — ein anderer.
Die ursprüngliche, standardmäßige Karte sieht folgendermaßen aus:
ceph osd tree
root@ceph01-q:~# ceph osd tree
ID Klasse Gewicht Typ Name Status Neugewicht PRI-AFF
-1 14.54799 Wurzel Default
-3 9.09200 Host ceph01-q
0 SSD 1.00000 osd.0 aktiv 1.00000 1.00000
1 SSD 1.00000 osd.1 aktiv 1.00000 1.00000
2 SSD 1.00000 osd.2 aktiv 1.00000 1.00000
3 SSD 1.00000 osd.3 aktiv 1.00000 1.00000
4 HDD 1.00000 osd.4 aktiv 1.00000 1.00000
5 HDD 0.27299 osd.5 aktiv 1.00000 1.00000
6 HDD 0.27299 osd.6 aktiv 1.00000 1.00000
7 HDD 0.27299 osd.7 aktiv 1.00000 1.00000
8 hdd 0.27299 osd.8 aktiv 1.00000 1.00000
9 hdd 0.27299 osd.9 aktiv 1.00000 1.00000
10 hdd 0.27299 osd.10 aktiv 1.00000 1.00000
11 hdd 0.27299 osd.11 aktiv 1.00000 1.00000
12 hdd 0.27299 osd.12 aktiv 1.00000 1.00000
13 hdd 0.27299 osd.13 aktiv 1.00000 1.00000
14 hdd 0.27299 osd.14 aktiv 1.00000 1.00000
15 hdd 0.27299 osd.15 aktiv 1.00000 1.00000
16 hdd 0.27299 osd.16 aktiv 1.00000 1.00000
17 hdd 0.27299 osd.17 aktiv 1.00000 1.00000
18 hdd 0.27299 osd.18 aktiv 1.00000 1.00000
19 hdd 0.27299 osd.19 aktiv 1.00000 1.00000
-5 5.45599 host ceph02-q
20 ssd 0.27299 osd.20 aktiv 1.00000 1.00000
21 ssd 0.27299 osd.21 aktiv 1.00000 1.00000
22 ssd 0.27299 osd.22 aktiv 1.00000 1.00000
23 ssd 0.27299 osd.23 aktiv 1.00000 1.00000
24 hdd 0.27299 osd.24 aktiv 1.00000 1.00000
25 hdd 0.27299 osd.25 aktiv 1.00000 1.00000
26 hdd 0.27299 osd.26 aktiv 1.00000 1.00000
27 hdd 0.27299 osd.27 aktiv 1.00000 1.00000
28 hdd 0.27299 osd.28 aktiv 1.00000 1.00000
29 hdd 0.27299 osd.29 aktiv 1.00000 1.00000
30 hdd 0.27299 osd.30 aktiv 1.00000 1.00000
31 hdd 0.27299 osd.31 aktiv 1.00000 1.00000
32 hdd 0.27299 osd.32 aktiv 1.00000 1.00000
33 hdd 0.27299 osd.33 aktiv 1.00000 1.00000
34 hdd 0.27299 osd.34 aktiv 1.00000 1.00000
35 hdd 0.27299 osd.35 aktiv 1.00000 1.00000
36 hdd 0.27299 osd.36 aktiv 1.00000 1.00000
37 hdd 0.27299 osd.37 aktiv 1.00000 1.00000
38 hdd 0.27299 osd.38 aktiv 1.00000 1.00000
39 hdd 0.27299 osd.39 aktiv 1.00000 1.00000
-7 6.08690 host ceph03-q
40 ssd 0.27299 osd.40 aktiv 1.00000 1.00000
41 ssd 0.27299 osd.41 aktiv 1.00000 1.00000
42 ssd 0.27299 osd.42 aktiv 1.00000 1.00000
43 ssd 0.27299 osd.43 aktiv 1.00000 1.00000
44 hdd 0.27299 osd.44 aktiv 1.00000 1.00000
45 hdd 0.27299 osd.45 aktiv 1.00000 1.00000
46 hdd 0.27299 osd.46 aktiv 1.00000 1.00000
47 hdd 0.27299 osd.47 aktiv 1.00000 1.00000
48 hdd 0.27299 osd.48 aktiv 1.00000 1.00000
49 hdd 0.27299 osd.49 aktiv 1.00000 1.00000
50 hdd 0.27299 osd.50 aktiv 1.00000 1.00000
51 hdd 0.27299 osd.51 aktiv 1.00000 1.00000
52 hdd 0.27299 osd.52 aktiv 1.00000 1.00000
53 hdd 0.27299 osd.53 aktiv 1.00000 1.00000
54 hdd 0.27299 osd.54 aktiv 1.00000 1.00000
55 hdd 0.27299 osd.55 aktiv 1.00000 1.00000
56 hdd 0.27299 osd.56 aktiv 1.00000 1.00000
57 hdd 0.27299 osd.57 aktiv 1.00000 1.00000
58 hdd 0.27299 osd.58 aktiv 1.00000 1.00000
59 hdd 0.89999 osd.59 aktiv 1.00000 1.00000
Lass uns unsere virtuellen Racks und Server mit Blackjack und anderem erstellen:
root@ceph01-q:~#ceph osd crush add-bucket rack01 root #neues root erstellt
root@ceph01-q:~#ceph osd crush add-bucket ceph01-q host #neuen host erstellt
root@ceph01-q:~#ceph osd crush move ceph01-q root=rack01 #Server in ein anderes Rack verschoben
root@ceph01-q:~#osd crush add 28 1.0 host=ceph02-q # OSD im Server hinzugefügt
# Wenn falsch erstellt, kann es gelöscht werden
root@ceph01-q:~# ceph osd crush remove osd.4
root@ceph01-q:~# ceph osd crush remove rack01Probleme, die wir festgestellt haben in dem produktiven Cluster, beim Versuch, einen neuen Host zu erstellen und ihn in ein bestehendes Rack zu verschieben — der Befehl ceph osd crush move ceph01-host root=rack01 hing und die Monitore fingen nacheinander an zu fallen. Das Abbrechen des Befehls mit STRG+C brachte den Cluster zurück ins Leben.
Eine Recherche ergab folgendes Problem:
Die Lösung war, die Crushmap zu dumpen und den Abschnitt zu entfernen rule replicated_ruleset
root@ceph01-prod:~#ceph osd getcrushmap -o crushmap.row #Dump der Karte im Rohformat
root@ceph01-prod:~#crushtool -d crushmap.row -o crushmap.txt #in lesbares Format umwandeln
root@ceph01-prod:~#vim crushmap.txt #bearbeiten, das rule replicated_ruleset entfernen
root@ceph01-prod:~#crushtool -c crushmap.txt -o new_crushmap.row #kompiliere zurück
root@ceph01-prod:~#ceph osd setcrushmap -i new_crushmap.row #ins Cluster ladenAchtung: Diese Operation kann ein Rebalancing der Placement-Gruppe zwischen OSD verursachen. Bei uns hat es das getan, aber nur sehr geringfügig.
Eine seltsame Eigenheit, auf die wir im Testcluster gestoßen sind, war, dass nach einem Neustart der Server OSD vergaßen, dass sie auf neue Server und Racks umgezogen wurden, und wieder zum Root-Default zurückkehrten.
Letztendlich haben wir ein endgültiges Schema erstellt, in dem wir einen separaten Root für SSD-Laufwerke und einen separaten für spinning platters erstellt haben, und wir haben alle OSDs auf den Racks verteilt und einfach den Default-Root gelöscht. Nach dem Neustart blieben die OSDs an ihren Orten.
Nachdem wir später in der Dokumentation nachgeschaut hatten, fanden wir einen Parameter, der für dieses Verhalten verantwortlich ist. Darum geht es im zweiten Teil.
Wie wir verschiedene Gruppen nach Festplattentypen gebildet haben.
Zuerst haben wir zwei Roots erstellt – für SSD und für HDD.
root@ceph01-q:~#ceph osd crush add-bucket ssd-root root
root@ceph01-q:~#ceph osd crush add-bucket hdd-root rootDa die Server physisch in verschiedenen Racks stehen, haben wir es zur besseren Übersicht in Racks unterteilt und darin die Server platziert.
# Стойки:
root@ceph01-q:~#ceph osd crush add-bucket ssd-rack01 rack
root@ceph01-q:~#ceph osd crush add-bucket ssd-rack02 rack
root@ceph01-q:~#ceph osd crush add-bucket ssd-rack03 rack
root@ceph01-q:~#ceph osd crush add-bucket hdd-rack01 rack
root@ceph01-q:~#ceph osd crush add-bucket hdd-rack01 rack
root@ceph01-q:~#ceph osd crush add-bucket hdd-rack01 rack
# Сервера
root@ceph01-q:~#ceph osd crush add-bucket ssd-ceph01-q host
root@ceph01-q:~#ceph osd crush add-bucket ssd-ceph02-q host
root@ceph01-q:~#ceph osd crush add-bucket ssd-ceph03-q host
root@ceph01-q:~#ceph osd crush add-bucket hdd-ceph01-q host
root@ceph01-q:~#ceph osd crush add-bucket hdd-ceph02-q host
root@ceph01-q:~#ceph osd crush add-bucket hdd-ceph02-q hostund haben die Laufwerke nach ihren Typen auf verschiedene Server verteilt.
root@ceph01-q:~# Die Laufwerke 0 bis 3 sind SSDs, befinden sich in ceph01-q, wir platzieren sie auf dem Server
root@ceph01-q:~# ssd-ceph01-q
root@ceph01-q:~#ceph osd crush add 0 1 host=ssd-ceph01-q
root@ceph01-q:~#ceph osd crush add 1 1 host=ssd-ceph01-q
root@ceph01-q:~#ceph osd crush add 2 1 host=ssd-ceph01-q
root@ceph01-q:~#ceph osd crush add 3 1 host=ssd-ceph01-q
root-ceph01-q:~# analog mit anderen ServernNachdem wir die Laufwerke auf die Roots ssd-root und hdd-root verteilt hatten, ließen wir den Root-Default leer, weshalb wir ihn entfernen können.
root-ceph01-q:~#ceph osd crush remove defaultAls Nächstes müssen wir Verteilungsregeln erstellen, die wir an die zu erstellenden Pools binden – in den Regeln geben wir an, in welche Root wir die Daten unseres Pools ablegen können und das Niveau der Replikationseinzigartigkeit – zum Beispiel müssen die Repliken unbedingt auf verschiedenen Servern oder in verschiedenen Racks liegen (vielleicht sogar in verschiedenen Roots, wenn wir eine solche Verteilung haben).
Bevor Sie den Typ auswählen, lesen Sie am besten die Dokumentation:
root-ceph01-q:~#ceph osd crush rule create-simple rule-ssd ssd-root host firstn
root-ceph01-q:~#ceph osd crush rule create-simple rule-hdd hdd-root host firstn
root-ceph01-q:~# Wir haben zwei Regeln angegeben, in denen die Daten repliziert werden
root-ceph01-q:~# zwischen den Hosts - das heißt, die Replikat muss auf einem anderen Host liegen,
root-ceph01-q:~# selbst wenn sie sich im selben Rack befinden
root-ceph01-q:~# In der Produktion, wenn möglich, ist es besser, die Hosts
root-ceph01-q:~# nach Racks zu verteilen und anzugeben, dass die Repliken nach Racks verteilt werden:
root-ceph01-q:~# ##ceph osd crush rule create-simple rule-ssd ssd-root rack firstnWir erstellen Pools, in denen wir in Zukunft die Images unserer Virtualisierung - PROXMOX - speichern möchten:
root-ceph01-q:~# #ceph osd pool create {NAME} {pg_num} {pgp_num}
root-ceph01-q:~# ceph osd pool create ssd_pool 1024 1024
root-ceph01-q:~# ceph osd pool create hdd_pool 1024 1024Und wir geben diesen Pools die Regeln an, nach denen sie Platz nehmen sollen.
root-ceph01-q:~#ceph osd crush rule ls # schauen wir uns die Liste der Regeln an
root-ceph01-q:~#ceph osd crush rule dump rule-ssd | grep rule_id #wählen wir die benötigte ID aus
root-ceph01-q:~#ceph osd pool set ssd_pool crush_rule 2
Die Wahl der Anzahl der Placement-Gruppen sollte mit einer klaren Vorstellung von Ihrem Cluster erfolgen – wie viele OSDs dort ungefähr vorhanden sein werden, wie viel Daten (in Prozent des Gesamtvolumens) im Pool sein werden, wie viel Daten insgesamt vorhanden sind.
Insgesamt sollten nicht mehr als 300 Placement-Gruppen pro Festplatte vorhanden sein, und es wird einfacher sein, mit kleinen Placement-Gruppen zu balancieren – das heißt, wenn Ihr gesamter Pool 10 Tb umfasst und er 10 PGs hat, wird es schwierig sein, die Terabyte-Ziegel (PGs) umzuschichten – es ist einfacher, Sand mit kleinen Sandkörnern in Eimern zu verteilen.
Aber man muss bedenken, dass je mehr PGs vorhanden sind, desto mehr Ressourcen für die Berechnung ihrer Platzierung benötigt werden – dadurch wird der Arbeitsspeicher und die CPU beansprucht.
Ein grobes Verständnis kann , bereitgestellt von den Entwicklern der CEPH-Dokumentation, geben.
Materialienliste:
Quelle: habr.com
