CEPH választás. 1. rész
Öt állványunk, tíz optikai kapcsolónk, beállított BGP-nk, néhány tucat SSD-nk és rengeteg különböző méretű SAS meghajtónk volt, plusz Proxmox és az a vágy, hogy az egész statikus tartalmat a saját S3 tárhelyünkbe tegyük. Nem mintha mindez szükséges lett volna a virtualizáláshoz, de ha már elkezdtem az opensource-t használni, akkor az ember menjen végig a szenvedélyén. Az egyetlen dolog, ami aggasztott - az a BGP volt. A világon nincs senki, aki annyira tehetetlen, felelőtlen és morálisan megkérdőjelezhető, mint a belső BGP útválasztás. És tudtam, hogy elég hamar bele fogunk merülni.

A feladat egyszerű volt - volt egy CEPH, ami nem működött túl jól. Tovább kellett fejleszteni, hogy "jól" működjön.
Az általam kapott klaszter heterogén volt, gyorsan beállítva, alig hangolva. Két különböző csomópont csoportból állt, egy közös hálózattal, amely a cluster és a public network szerepét is betöltötte. A csomópontok négyféle lemezzel voltak tele, kétféle SSD-t két külön placemen szabályba csoportosítva és kétféle HDD-t különböző méretben, amelyek egy harmadik csoportba kerültek. A különböző méretek problémáját különböző OSD súlyok megadásával oldottuk meg.
A beállítást két részre osztottuk - a operációs rendszer hangolása és a CEPH önmagának hangolása és a beállításai.
Az OS fejlesztése
Hálózat
A magas késleltetés íráskor és egyensúlyozáskor is megmutatkozott. Íráskor - mert a kliens nem kap választ a sikeres írásról, amíg a másik elhelyezési csoportokban lévő adatreplikák nem megerősítik a sikert. Mivel a replikációs szabályok a CRUSH térképünkben egy replikát követeltek meg hosztonként, a hálózat folyamatosan használatban volt.
Ezért az első dolog, amit tettünk, az aktuális hálózat apró beállítása volt, miközben megpróbáltam meggyőzni őket, hogy váltsanak különálló hálózatokra.
Először a hálózati kártyák beállításain dolgoztam. A sorok beállításával kezdtem:
ami volt:
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: 1Látható, hogy a jelenlegi paraméterek messze vannak a maximumoktól. Növeltem:
root@ceph01:~# ethtool -G ens1f0 rx 4096
root@ceph01:~# ethtool -G ens1f0 tx 4096
root@ceph01:~# ethtool -L ens1f0 combined 63Egy kiváló cikk alapján
megnöveltem a küldési sor hosszát txqueuelen 1000-től 10 000-ig
root@ceph01:~#ip link set ens1f0 txqueuelen 10000A ceph hivatalos dokumentációja szerint
növeltem MTU 9000-re.
root@ceph01:~#ip link set dev ens1f0 mtu 9000Hozzáadtam a \/etc\/network\/interfaces fájlhoz, hogy minden fent említett dolog induláskor betöltődjön
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 9000Ezután, a cikket követve, gondosan módosítottam a 4.15-ös kernel beállításait. Figyelembe véve, hogy a csomópontok 128G RAM-mal rendelkeznek, létrejött egy konfigurációs fájl sysctl
cat \/etc\/sysctl.d\/50-ceph.conf
net.core.rmem_max = 56623104
#A maximális adatbeküldési puffer mérete minden kapcsolat számára 54M
net.core.wmem_max = 56623104
#A maximális adatátviteli puffer mérete minden kapcsolat számára 54M
net.core.rmem_default = 56623104
#Az alapértelmezett adatbeküldési puffer mérete minden kapcsolat számára. 54M
net.core.wmem_default = 56623104
#Az alapértelmezett adatátviteli puffer mérete minden kapcsolat számára 54M
#az egyes socketekre vonatkozóan
net.ipv4.tcp_rmem = 4096 87380 56623104
#A tcp_rmem fájlban lévő vektor (minimum, alapértelmezett, maximum)
# három egész számot tartalmaz, amelyek meghatározzák a TCP socketek
# adatbeküldési pufferének méretét.
# Minimum: minden TCP socketnek joga van használni ezt a memóriát
# a létrehozása időpontjában. A bútorhasználati lehetőség
# garantált, még akkor is, ha elérjük a korlátot (mérsékelt memóriaterhelés).
# Az alapértelmezett minimum puffer mérete 8 KB (8192).
#Alapértelmezett érték: a TCP socket alapértelmezett
# adatátviteli pufferének megengedett memória mennyisége. Ez az érték
# helyettesíti a /proc/sys/net/core/rmem_default paramétert,
# amit más protokollok használnak.
# Az alapértelmezett puffer általában (alapértelmezetten)
# 87830 byte. Ez meghatározza az ablak 65535 méretét
# az alapértelmezett tcp_adv_win_scale és tcp_app_win = 0 esetén.
# Maximum: a maximális puffer méret,
# amely automatikusan kiosztható a TCP socket számára. Ez az érték nem érvényteleníti a maximális értéket,
# amelyet a /proc/sys/net/core/rmem_max fájl tartalmaz. A "statikus"
# memóriaelosztás során SO_RCVBUF segítségével ez a paraméter figyelmen kívül hagyható.
net.ipv4.tcp_wmem = 4096 65536 56623104
net.core.somaxconn = 5000
#A maximális számú nyitott socket, amely kapcsolatokat vár.
net.ipv4.tcp_timestamps=1
#Engedélyezi a timestamp használatát, a RFC 1323-nak megfelelően.
net.ipv4.tcp_sack=1
#Engedélyezni a TCP protokoll választott megerősítéseit
net.core.netdev_max_backlog=5000 (alapértelmezett 1000)
#A maximális csomagszám a feldolgozásra várakozó sorban, ha az
# interfész gyorsabban fogad csomagokat, mint ahogy a kernel képes azokat feldolgozni.
net.ipv4.tcp_max_tw_buckets=262144
#A maximális socket szám, amely egyszerre TIME-WAIT állapotban lehet.
# E határ túllépésekor a "túlzott" socket megsemmisül és bejegyzés
# készül a rendszer naplóba.
net.ipv4.tcp_tw_reuse=1
#Engedélyezzük a TIME-WAIT socketek újbóli felhasználását,
# ha a protokoll biztonságosnak ítéli.
net.core.optmem_max=4194304
#Növeljük a maximális összesített puffer méretet,
# oldal egységekben (4096 byte)
net.ipv4.tcp_low_latency=1
#Engedélyezi a TCP/IP stack számára, hogy a minimális késleltetésre
# helyezzen prioritást a nagyobb átvitel sebességével szemben.
net.ipv4.tcp_adv_win_scale=1
#Ez a változó hatással van a socket pufferének memóriájának
# számítására, amely a TCP-ablak méretéhez és az alkalmazás pufferhez
# van allokálva. Ha a tcp_adv_win_scale értéke negatív, akkor a méret
# számításához a következő kifejezést használják:
# Bytes - bytes2 a -tcp_adv_win_scale hatványon
# Ahol bytes – az ablak mérete byte-ban. Ha a tcp_adv_win_scale
# értéke pozitív, a méret meghatározásához a következő kifejezést használják:
# Bytes - bytes2 a tcp_adv_win_scale hatványon
# A változó egész szám értéket vesz fel. Az alapértelmezett érték 2,
# tehát az alkalmazás pufferhez a változó által meghatározott térfogat ¼
# része jut.
net.ipv4.tcp_slow_start_after_idle=0
#A lassú indulás újraindítási mechanizmusa, amely visszaállítja az ablak értékét
# a terhelési küszöböléshez, ha a kapcsolat egy meghatározott ideig nem volt használatban.
# Jobb a SSR-t kikapcsolni a szerveren a
# hosszú életű kapcsolatok teljesítményének javítása érdekében.
net.ipv4.tcp_no_metrics_save=1
#Ne mentsük el a TCP kapcsolat mérési eredményeit a cache-be,
# amikor az lezárul.
net.ipv4.tcp_syncookies=0
#Kapcsolja ki a syncookie küldésének mechanizmusát
net.ipv4.tcp_ecn=0
#Explicit Congestion Notification a TCP-kapcsolatokban. Használják
# értesítésre, ha torlódás van az utakon egy adott gazdagéphez vagy hálózathoz.
# Használható a küldő gazdagép értesítésére, hogy csökkentse a csomagok
# átvitelének sebességét egy adott routeren vagy tűzfalon.
net.ipv4.conf.all.send_redirects=0
# Kikapcsolja az ICMP Redirect küldést … más gazdagépeknél. Ez a beállítás
# kötelezően bekapcsolva kell lennie, ha a gazdagép bármilyen
# formában routerként működik. Nincs routerezés.
net.ipv4.ip_forward=0
#Alapvetően a csomagküldést letiltja. Nem vagyunk átjáró,
# a docker gépeken nem emelkedett, erre nincs szükség.
net.ipv4.icmp_echo_ignore_broadcasts=1
#Nem válaszolunk az ICMP ECHO kérésekre, amelyeket széleskörű
# csomagokban küldtek
net.ipv4.tcp_fin_timeout=10
#Meghatározza a socket állapotának megőrzésének idejét FIN-WAIT-2
# állapotban a helyi oldal bezárása után. Alapértelmezett 60
net.core.netdev_budget=600 # (alapértelmezett 300)
# Ha a szoftveres megszakítások végrehajtása nem tart elegendő ideig,
# a beérkező adatok növekedésének üteme meghaladhatja a kernel
# képes elárasztani a puffert. Ennek eredményeként a NIC pufferei
# túlfolynak, és a forgalom elveszik. Néha növelni kell a SoftIRQs
# (szoftveres megszakítások) CPU-hoz való támogatási időt. Erre
# a netdev_budget felelős. Az alapértelmezett érték 300. A paraméter
több ezer csomagot enged feldolgozni a SoftIRQ-nek a NIC-től,
# mielőtt elengedi a CPU-t.
net.ipv4.tcp_fastopen=3
# TFO TCP Gyors Megnyitás
# ha mind a kliens, mind a szerver támogatja a TFO-t, amit jeleznek
# a TCP csomagban lévő speciális zászló. A mi esetünkben placebo,
# egyszerűen jól néz ki)Késleltetett streaming replikációt is beállíthatunk, de van néhány csapda, amelyek a replikációs slotokkal, a forró tartalék visszajelzésével stb. kapcsolatosak. A WAL archívum lehetővé teszi, hogy elkerüljük ezeket.luster hálózat különálló 10Gbps hálózati interfészeken került egy külön lapos hálózatba. Minden gépen kétéltű hálózati kártyák voltak beszerelve. mellanox 10/25 Gbps, két különálló 10Gbps switchbe dugva. Az aggregálás OSPF segítségével történt, mivel a lacp összekapcsolás valamiért maximum 16 Gbps átviteli sebességet mutatott, míg az ospf teljes mértékben kihasználta mindkét tízest minden gépen. Terveztük, hogy ROCE-t használunk ezekben a mellanoxokban a késleltetés csökkentésére. Így állítottuk be ezt a hálózati részt:
- Mivel maguknak a gépeknek külső IP címeik vannak BGP-n, szükségünk van szoftverre — ( pontosabban a cikk írásának időpontjában ez volt a ) már telepítve.
- Összesen a gépeken két hálózati interfész volt négy porttal összesen. Az egyik hálózati kártya két portja a gyárra nézett, és azon BGP-t állítottunk be, a másik — két porttal két különböző switchre nézett, és arra OSPF-t irányoztunk.
Részletesebben az OSPF beállításairól: Az alapvető feladat — a két link aggregálása és a hibaelhárítás biztosítása.
a két hálózati interfész két egyszerű lapos hálózatra volt beállítva — 10.10.10.0/24 és 10.10.20.0/24
1: ens1f0: mtu 9000 qdisc mq állapot: FEL csoport: alapértelmezett qlen: 1000
inet 10.10.10.2/24 brd 10.10.10.255 hatókör globális ens1f0
2: ens1f1: mtu 9000 qdisc mq állapot: FEL csoport: alapértelmezett qlen: 1000
inet 10.10.20.2/24 brd 10.10.20.255 hatókör globális ens1f1amin keresztül a gépek látják egymást.
DISK
A következő lépésként úgy döntöttem, hogy optimalizálom a lemezek működését. Az SSD esetében a tervezőt noop, HDD esetében — deadline. Durván fogalmazva — a NOOP az "aki előbb állt, azt viszik" elv alapján működik, ami angolul "FIFO (First In, First Out)". A kérések érkezésük sorrendjében állnak sorba. A DEADLINE inkább az olvasásra van optimalizálva, plusz a folyamat az sorból gyakorlatilag monopóliumot kap a lemezhez a művelet ideje alatt. A rendszerünknek ez tökéletes, hiszen minden lemezzel csak egy folyamat — OSD daemon foglalkozik.
(Aki szeretne mélyebben belemerülni a be- és kimeneti ütemezőbe, itt olvashat róla:
Az orosz nyelvet preferálók számára: )
A linux optimalizálására vonatkozó ajánlásokban azt is tanácsolják, hogy növeljük az nr_request
nr_requests
A nr_requests értéke határozza meg az I/O kérések számát, amelyeket a bufferekbe helyeznek, mielőtt az I/O ütemező adatokat küldene / fogadna a blokk eszközhöz. Ha RAID kártyát / blokk eszközt használ, amely nagyobb sorfogadási kapacitással rendelkezik, mint amit az I/O ütemező beállítása enged, a nr_requests értékének növelése javíthatja a throughput-ot és csökkentheti a szerver terhelését, amikor nagy mennyiségű I/O történik a szerveren. Ha a Deadline vagy CFQ ütemezőt használja, javasolt a nr_request értékét a sor mélység értékének 2-szeresére állítani.
DE! A CEPH fejlesztői maguk is azt állítják, hogy prioritási rendszerük jobban működik.

WBThrottle és / vagy nr_requests
WBThrottle és / vagy nr_requests
A fájltároló buferelt I/O műveleteket használ írásra; ez számos előnyt nyújt, ha a fájltároló naplója gyorsabb médián található. Az ügyféligények értesítést kapnak, amint az adatok a naplóba íródnak, majd később a tényleges adathordozóra íródnak a Linux alapértelmezett funkcionalitása révén. Ez lehetővé teszi, hogy az OSD lemezek írási késleltetése SSD-hez hasonló latenciát nyújtson kis csomagok írásakor. Ez a késleltetett írás lehetővé teszi a kernel számára, hogy átstrukturálja az I/O műveletek kérdéseit a lemezen azzal a céllal, hogy vagy egyesítse őket, vagy lehetőséget adjon a meglévő lemezfejeknek, hogy optimálisabb utat válasszanak a tányérokon. A végső hatás az, hogy kissé több I/O műveletet tudsz kihozni minden lemezből, mint ami közvetlen vagy szinkron I/O műveletek esetén lehetséges lenne.
Azonban felmerül egy bizonyos probléma, ha a Ceph klaszterbe érkező írások volumene meghaladja az alapul szolgáló lemezek kapacitását. Ilyen forgatókönyvben a lemezre írásra várakozó I/O műveletek összszáma kontrollálatlanul növekedhet, ami I/O műveleti sorokat eredményez, amelyek kitöltik az egész lemezt és a Ceph sorait. A leolvasási kérelmekre különösen kedvezőtlenül hat, mivel ezek a műveletek megrekednek az írási kérelmek között, amelyek néhány másodpercet is igénybe vehetnek a fő lemezre való íráshoz.
A probléma megoldásához a Ceph rendelkezik egy beépített writeback mechanizmussal, amelyet WBThrottle-nak hívnak, és amely a fájlok tárolásakor van jelen. Ez a mechanizmus a késleltetett írási műveletek mennyiségének korlátozására szolgál, amelyeket a rendszer sorba állíthat, és amelyek a normálisnál korábban kezdenek el kiürülni a saját maguk által aktivált kernelen keresztül. Sajnos a tesztelés azt mutatja, hogy az alapértelmezett beállítások még mindig nem csökkentik a meglévő viselkedést olyan szintre, amely csökkentheti a beolvasási műveletek késleltetését. A finomhangolás megváltoztathatja ezt a viselkedést, csökkentheti a teljes írási sorok hosszát, és lehetővé teheti a kisebb hatást. Van azonban egy kompromisszum: azzal, hogy csökkenti a sorba állítható bejegyzések maximális számát, csökkentheti a kernel lehetőségeit arra, hogy maximalizálja a beérkező kérések hatékonyságát. Érdemes elgondolkodnia, hogy mi a fontosabb az adott alkalmazási esetében, a munkaterhelés szempontjából, és ennek megfelelően szabályozni.
A késleltetett írás mélységének kezeléséhez csökkentheti a teljes maximális számot a végrehajtásra váró bemeneti/kimeneti műveletek számára a WBThrottle beállításainak alkalmazásával, vagy csökkentheti a maximális értéket az adott blokk szintjén a kernelében. Mindkettő hatékonyan kezelheti ugyanazt a viselkedést, és az ön preferenciái fogják alapját képezni ennek a beállításnak a megvalósításához.
Fontos megjegyezni, hogy a Ceph által kezelt prioritási rendszer hatékonyabb a rövidebb lemezszintű kérések esetén. Amikor csökkenti a lemezre vonatkozó teljes sort, a sorban lévő fő helyszín a Ceph-be kerül, ahol nagyobb ellenőrzéssel rendelkezik a bemeneti/kimeneti művelet prioritásának meghatározásában. Nézzünk egy következő példát:
echo 8 > /sys/block/sda/queue/nr_requestsKÖZÖS
Továbbá van néhány kernel beállítás, amelyek lehetővé teszik, hogy az ön eszköze simább és selymesebb érzést nyújtson, és kihozzon még egy kicsit a hardverből.
cat /etc/sysctl.d/60-ceph2.conf
kernel.pid_max = 4194303
# Minden gépben 25 lemez van, tehát azt számoltuk, hogy sok folyamat lesz
kernel.threads-max=2097152
# Szálak, természetesen.
vm.max_map_count=524288
# Megnöveltük a folyamatok memória-térképezési területeinek számát.
# Mint az a kernel változók dokumentációjából kiderül,
# A memória térképezési területeket a malloc, mmap, mprotect és madvise hívások,
# valamint a közös könyvtárak betöltése során használják.
fs.aio-max-nr=50000000
# Finomhangoljuk a bemeneti-kimeneti paramétereket.
# A Linux kernel non-blocking aszinkron bemeneti-kimeneti (AIO) funkciót biztosít,
# ami lehetővé teszi a folyamat számára, hogy több I/O műveletet indítson
# egyszerre, anélkül, hogy meg kellene várnia bármelyik befejezését.
# Ez segít javítani az alkalmazások teljesítményét,
# amelyek átfedhetik a feldolgozást és a bemeneti-kimenetet.
# Az aio-max-nr paraméter határozza meg a maximálisan engedélyezett
# egyidejű kérések számát.
vm.min_free_kbytes=1048576
# A minimális szabad memória mérete, amit fenntartani kell.
# 1GB-ra állítva, ami bőven elegendő az operációs rendszer működéséhez,
# és lehetővé teszi az OOM Killer elkerülését az OSD folyamatoknál. Bár a memória
# amúgy is bőséges, de a tartalék sosem árt.
vm.swappiness=10
# Használja a swap-ot, ha a memória 10%-a szabadon marad.
# Az 128G RAM-mal rendelkező gépeken a 10% 12 Gigabyte. Bőven elegendő a működéshez.
# A 60%-os alapértelmezett paraméter lassította a rendszert, belépve a swap-ra,
# miközben még rengeteg szabad memória állt rendelkezésre.
vm.vfs_cache_pressure=1000
# Megnöveljük az alapértelmezett 100-ról. Kényszerítjük a kernelt, hogy aktívan
# törölje a nem használt memóriaoldalakat a cache-ből.
vm.zone_reclaim_mode=0
# Lehetővé teszi a memória helyreállítási módszerek
# agresszívebb beállítását, amikor a zónában a memória kifogy.
# Ha nulla értékre van állítva, nem történik zóna-helyreállítás.
# Fájl szerverek vagy munkahelyi terhelések esetén
# kedvező, ha az adatok gyorsítótárazva vannak, a zone_reclaim_mode
# kikapcsolása előnyös, mivel a gyorsítótárazás hatása
# valószínűleg fontosabb lesz, mint az adatok helye.
vm.dirty_ratio=20
# A memória aránya, amely "koszos" oldalakra kijelölhető
# Körülbelül 128 GB memória áll rendelkezésre.
# Körülbelül 20 SSD lemez, amelynek beállításaiban a CEPH
# 3G RAM-ot jelöl ki a gyorsításhoz.
# Körülbelül 40 HDD lemez, amely esetében ez a paraméter 1G
# 20% a 128-tól az 25.6 GB. Így maximális memória kihasználtság esetén
# a rendszernek 2.4G memória marad. Ennek elegendőnek kell lennie a túléléshez,
# amíg megérkezik a DevOps, aki mindent megjavít.
vm.dirty_background_ratio=3
# A rendszer memória hányada, amelyet koszos oldalakkal tölthetünk fel,
# mielőtt a háttérfolyamatok pdflush/flush/kdmflush írnának a lemezre.
fs.file-max=524288
# Nos, valószínűleg sokkal több nyitott fájlunk lesz, mint amit a default beállítás megad. Bevezetés a CEPH-be
Beállítások, amelyekre érdemes kiterjedni:
cat /etc/ceph/ceph.conf
osd:
journal_aio: true # Három paraméter, amely bekapcsolja
journal_block_align: true # közvetlen i/o
journal_dio: true # a naplóhoz
journal_max_write_bytes: 1073714824 # Egy kicsit megnöveljük a maximális méretet
# egyszerre írt művelet a naplóban
journal_max_write_entries: 10000 # És a párhuzamos bejegyzések száma
journal_queue_max_bytes: 10485760000
journal_queue_max_ops: 50000
rocksdb_separate_wal_dir: true # Úgy döntöttünk, hogy külön wal-t csinálunk
# Még megpróbáltunk helyet keresni ehhez
# NVMe
bluestore_block_db_create: true # Nos, a naplóhoz külön eszköz
bluestore_block_db_size: '5368709120 #5G'
bluestore_block_wal_create: true
bluestore_block_wal_size: '1073741824 #1G'
bluestore_cache_size_hdd: '3221225472 # 3G'
# a nagy memória mennyiség lehetővé teszi
# elég nagy mennyiség tárolását
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 # a démon szálainak száma egy lemezen
osd_failsafe_full_ratio: 0.95
osd_heartbeat_grace: 5
osd_heartbeat_interval: 3
osd_map_dedup: true
osd_max_backfills: 2 # a párhuzamos feltöltési műveletek száma egy OSD-n.
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 # A mohóság sajátosságai. Nagyon gyorsan
osd_pool_default_size: 2 # elfogyott a hely, mert ideiglenes
# megoldásként a másolatok számát
# csökkentették
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 # a paramétert szükség szerint szabályozzuk
osd_recovery_sleep: 2
osd_scrub_chunk_max: 4Néhány paraméter, amelyet a QA tesztelt a 12.2.12-es verzión, hiányzik a ceph 12.2.2-es verziójából, például osd_recovery_threads. Ezért terveztük a 12.2.12-re való frissítést. A gyakorlat megmutatta a 12.2.2 és 12.2.12 verziók kompatibilitását egy klaszterben, ami lehetővé teszi a rolling update-et.
Teszt klaszter
Természetesen a teszteléshez szükséges volt ugyanazt a verziót használni, mint ami a működő rendszerben volt, de amikor elkezdtem dolgozni a klaszteren, a tárolóban csak egy újabb verzió volt elérhető. Megnézve, hogy a kisebb verziók között nem volt nagy különbség,1393 a konfigurációs file-okban lévő sorokkal szemben 1436 (az új verzióban) úgy döntöttünk, hogy új verziót kezdünk tesztelni (úgyis frissíteni kell, minek vesződni a régi cuccal)
Az egyetlen dolog, amit megpróbáltunk megőrizni a régi verzióból, az a csomag ceph-deploy, mivel a kapcsolódó segédprogramok (és néhány munkatárs) e szintaxisra voltak optimalizálva. Az új verzió jelentősen eltért, de a klaszter működésére semmilyen hatással nem volt, így a 1.5.39
mivel a ceph-disk csapat egyértelműen jelzi, hogy elavult, és használjuk inkább a ceph-volume parancsot – elkezdtük OSD-t létrehozni ezzel a paranccsal, nem pazarolva az időt az elavult rendszerre.
A terv az volt, hogy létrehozunk egy tükröt két SSD meghajtóból, amelyeken az OSD naplói lesznek, míg maguk az OSD-k hagyományos SAS meghajtókon helyezkednek el. Így biztosítva leszünk az adatok védelméről lemez hibája esetén.
A klasztert a dokumentáció szerint kezdték létrehozni
cat /etc/ceph/ceph.conf
root@ceph01-qa:~# cat /etc/ceph/ceph.conf # előre elkészített konfigurációs fájl
[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 # az IP cím természetesen megváltozott ))
rgw_dns_name = s3-qa.mycompany.ru # és ez az IP cím is megváltozott
rgw_host = s3-qa.mycompany.ru # és ez is
[mon]
mon allow pool delete = true
mon_max_pg_per_osd = 300 # háromszáz placemente csoport fölé nem mentünk
# a háttértáron, nem mertük megkockáztatni
# de ez a paraméter természetesen függ a csoportok számától,
# azok méretétől és az OSD-k számától. Kevesebb, de egészséges PG
# szintén nem a legjobb választás - szenved az egyensúlyozás pontossága
mon_osd_backfillfull_ratio = 0.9
mon_osd_down_out_interval = 5
mon_osd_full_ratio = 0.95 # a SSD meghajtóknál a
# naplónak a ugyanaz a eszköz, mint az OSD
# úgy döntöttünk, hogy a meghajtó 5%-a (ami 1.2Tb méretű)
# elégséges, és megfelel a
# bluestore_block_db_size plusz variabilitás nagyobb
# placemente csoportok esetén
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-qAz első dolog, amivel a ceph-deploy 12.2.12 verziójának használata során találkoztam, egy hiba volt, amikor megpróbáltam létrehozni egy OSD-t szoftveres RAID-en db-val.
root@ceph01-qa:~#ceph-volume lvm create --bluestore --data /dev/sde --block.db /dev/md0
blkid nem tudta észlelni a PARTUUID-t a következő eszközre: /dev/md1Valóban, a blkid nem mutatott PARTUUID-t, ezért kézi beállítással kellett particionálnom:
root@ceph01-qa:~#parted /dev/md0 mklabel GPT
# sok partíciót fogunk létrehozni,
# GPT nélkül nem lehet őket létrehozni
# a partíció méretét a fentebb megadott konfigurációban állítottuk be = bluestore_block_db_size: '5368709120 #5G'
# 20 lemez áll rendelkezésemre az OSD-hez, kézi particionálás helyett inkább ciklust csináltam
root@ceph01-qa:~#for i in {1..20}; do echo -e "nnnn+5Gnw" | fdisk /dev/md0; doneÚgy tűnik, minden készen áll, megpróbáljuk újra létrehozni az OSD-t, és a következő hibát kapjuk (ami egyébként a éles környezetben nem jelentkezett).
az OSD bluestore típusú létrehozásakor, WAL elérési út megadása nélkül, de db megadásával.
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 érvénytelen uuid
stderr: 2019-04-12 10:39:27.213185 7eff461b6e00 -1 bdev(0x55824c273680 /var/lib/ceph/osd/ceph-0//block.wal) nyitott: (22) Érvénytelen argumentum
stderr: 2019-04-12 10:39:27.213201 7eff461b6e00 -1 bluestore(/var/lib/ceph/osd/ceph-0/) _open_db blokkeszköz hozzáadása(/var/lib/ceph/osd/ceph-0//block.wal) visszatért: (22) Érvénytelen argumentum
stderr: 2019-04-12 10:39:27.999039 7eff461b6e00 -1 bluestore(/var/lib/ceph/osd/ceph-0/) mkfs meghiúsult, (22) Érvénytelen argumentum
stderr: 2019-04-12 10:39:27.999057 7eff461b6e00 -1 OSD::mkfs: ObjectStore::mkfs sikertelen a hiba miatt (22) Érvénytelen argumentum
stderr: 2019-04-12 10:39:27.999141 7eff461b6e00 -1 ** HIBA: üres objektum Bolt létrehozása a következő helyen: /var/lib/ceph/osd/ceph-0/: (22) Érvénytelen argumentum.Ha viszont ugyanazon a tükörön (vagy más helyen, kedv szerint) létrehozok egy további partíciót a WAL számára, és azt megadom az OSD létrehozásakor, akkor minden simán zajlik (kivéve, ha az elkülönített WAL-t nem akarta volna).
Viszont, mivel a távoli terveimen az volt, hogy a WAL-t NVMe-re helyezem, így ez a gyakorlat nem volt felesleges.
root@ceph01-qa:~#ceph-volume lvm create --bluestore --data /dev/sdf --block.wal /dev/md0p2 --block.db /dev/md1p2Létrehoztuk a monitorokat, menedzsereket és OSD-ket. Most szeretnénk őket különböző módon csoportosítani, mivel a terveim között szerepel, hogy különböző típusú lemezeket használjak — gyors paneleket SSD-n, és nagyobb, de lassú SAS-lemezeket.
Tegyük fel, hogy a szervereken 20 lemez van, az első tíz egy típus, a második — más.
Az eredeti, alapértelmezett térkép így néz ki:
ceph osd tree
root@ceph01-q:~# ceph osd tree
ID OSZTÁLY SÚLY TÍPUS NÉV ÁLLAPOT REWEIGHT PRI-AFF
-1 14.54799 gyökér alapértelmezett
-3 9.09200 gazda ceph01-q
0 ssd 1.00000 osd.0 működik 1.00000 1.00000
1 ssd 1.00000 osd.1 működik 1.00000 1.00000
2 ssd 1.00000 osd.2 működik 1.00000 1.00000
3 ssd 1.00000 osd.3 működik 1.00000 1.00000
4 hdd 1.00000 osd.4 működik 1.00000 1.00000
5 hdd 0.27299 osd.5 működik 1.00000 1.00000
6 hdd 0.27299 osd.6 működik 1.00000 1.00000
7 hdd 0.27299 osd.7 működik 1.00000 1.00000
8 hdd 0.27299 osd.8 fel
9 hdd 0.27299 osd.9 fel
10 hdd 0.27299 osd.10 fel
11 hdd 0.27299 osd.11 fel
12 hdd 0.27299 osd.12 fel
13 hdd 0.27299 osd.13 fel
14 hdd 0.27299 osd.14 fel
15 hdd 0.27299 osd.15 fel
16 hdd 0.27299 osd.16 fel
17 hdd 0.27299 osd.17 fel
18 hdd 0.27299 osd.18 fel
19 hdd 0.27299 osd.19 fel
-5 5.45599 gazda ceph02-q
20 ssd 0.27299 osd.20 fel
21 ssd 0.27299 osd.21 fel
22 ssd 0.27299 osd.22 fel
23 ssd 0.27299 osd.23 fel
24 hdd 0.27299 osd.24 fel
25 hdd 0.27299 osd.25 fel
26 hdd 0.27299 osd.26 fel
27 hdd 0.27299 osd.27 fel
28 hdd 0.27299 osd.28 fel
29 hdd 0.27299 osd.29 fel
30 hdd 0.27299 osd.30 fel
31 hdd 0.27299 osd.31 fel
32 hdd 0.27299 osd.32 fel
33 hdd 0.27299 osd.33 fel
34 hdd 0.27299 osd.34 fel
35 hdd 0.27299 osd.35 fel
36 hdd 0.27299 osd.36 fel
37 hdd 0.27299 osd.37 fel
38 hdd 0.27299 osd.38 fel
39 hdd 0.27299 osd.39 fel
-7 6.08690 gazda ceph03-q
40 ssd 0.27299 osd.40 fel
41 ssd 0.27299 osd.41 fel
42 ssd 0.27299 osd.42 fel
43 ssd 0.27299 osd.43 fel
44 hdd 0.27299 osd.44 fel
45 hdd 0.27299 osd.45 fel
46 hdd 0.27299 osd.46 fel
47 hdd 0.27299 osd.47 fel
48 hdd 0.27299 osd.48 fel
49 hdd 0.27299 osd.49 fel
50 hdd 0.27299 osd.50 fel
51 hdd 0.27299 osd.51 fel
52 hdd 0.27299 osd.52 fel
53 hdd 0.27299 osd.53 fel
54 hdd 0.27299 osd.54 fel
55 hdd 0.27299 osd.55 fel
56 hdd 0.27299 osd.56 fel
57 hdd 0.27299 osd.57 fel
58 hdd 0.27299 osd.58 fel
59 hdd 0.89999 osd.59 fel
Hozzunk létre saját virtuális állványainkat és szervereinket!
root@ceph01-q:~#ceph osd crush add-bucket rack01 gyökér #új gyökér létrehozása
root@ceph01-q:~#ceph osd crush add-bucket ceph01-q gazda #új gazda létrehozása
root@ceph01-q:~#ceph osd crush move ceph01-q gyökér=rack01 #szerver mozgatása másik állványba
root@ceph01-q:~#osd crush add 28 1.0 gazda=ceph02-q # OSD hozzáadása a szerverhez
# Ha rosszul hoztuk létre, törölhetjük
root@ceph01-q:~# ceph osd crush remove osd.4
root@ceph01-q:~# ceph osd crush remove rack01Problémák, amelyekbe ütköztünk a harci klaszterben, amikor új gazdát próbáltunk létrehozni és átmozdítani egy meglévő állványba — a parancs ceph osd crush move ceph01-host gyökér=rack01 megszűnt, és a monitorok egyesével kezdtek elhullani. A parancs megszakítása egyszerű CTRL+C-val visszahozta a klasztert az élők közé.
A keresés egy ilyen problémára mutatott rá:
A megoldás az volt, hogy le kellett dumpolni a crushmapet és eltávolítani onnan a szekciót rule replicated_ruleset
root@ceph01-prod:~#ceph osd getcrushmap -o crushmap.row # A térképet nyers formában dumpoljuk
root@ceph01-prod:~#crushtool -d crushmap.row -o crushmap.txt # olvashatóvá alakítjuk
root@ceph01-prod:~#vim crushmap.txt # szerkesztjük, eltávolítva a rule replicated_ruleset-t
root@ceph01-prod:~#crushtool -c crushmap.txt -o new_crushmap.row # visszakomponáljuk
root@ceph01-prod:~#ceph osd setcrushmap -i new_crushmap.row # betöltjük a klaszterbeFigyelmeztetés: ez a művelet a placement group újraelosztását okozhatja az OSD között. Nálunk ez bekövetkezett, de nagyon csekély mértékben.
A különös helyzet, amivel a tesztkészletben találkoztunk, az volt, hogy a szerver OSD-jei újraindítás után elfelejtették, hogy átkerültek új szerverekbe és állványokba, és visszatértek az alapértelmezett gyökérbe.
Végül, miután létrehoztuk a végső sémát, amelyben külön gyökeret állítottunk be az SSD-knek és külön az HDD-knek, az OSD-ket elosztottuk az állványokban, és egyszerűen eltávolítottuk az alapértelmezett gyökeret. Az újraindítás után az OSD-k a helyükön maradtak.
Később a dokumentációban találtunk egy paramétert, ami ezt a viselkedést befolyásolja. Róla a második részben.
Hogyan hoztunk létre különböző csoportokat a lemeztípusok alapján.
Először két gyökér létrehozásával kezdtük — az SSD-nek és az HDD-nek.
root@ceph01-q:~#ceph osd crush add-bucket ssd-root root
root@ceph01-q:~#ceph osd crush add-bucket hdd-root rootMivel fizikailag a szerverek különböző állványokban helyezkednek el — a kényelem kedvéért állványokat hoztunk létre, és azokban már a szervereket.
# Стойки:
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 hostés a lemezeket a típusaik alapján különböző szerverekre osztottuk.
root@ceph01-q:~# A 0-tól 3-ig terjedő lemezek SSD-k, a ceph01-q-n találhatók, ezeket az ssd-ceph01-q szerverre helyezzük
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:~# hasonlóan a többi szerverrel.A lemezek ssd-root és hdd-root gyökerekbe való elosztása után az alapértelmezett gyökér üresen maradt, ezért azt eltávolíthatjuk.
root-ceph01-q:~#ceph osd crush remove defaultEzután létre kell hoznunk az elosztási szabályokat, amelyeket a létrehozott pülákra fogunk alkalmazni — a szabályokban megadjuk, hogy mely gyökerekbe lehet elhelyezni a puha adatainkat, és a replika egyediségének szintjét — például a replikáknak különböző szervereken kell elhelyezkedniük, vagy különböző állványokban (még különböző gyökerekben is, ha van ilyen elosztás).
Mielőtt kiválasztanánk a típust, érdemes elolvasni a dokumentációt:
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:~# Két szabályt adtunk meg, melyekben az adatok replikálódnak
root-ceph01-q:~# a hosztok között - tehát a replika egy másik hoszton kell, hogy elhelyezkedjen,
root-ceph01-q:~# még akkor is, ha ugyanabban az állványban vannak.
root-ceph01-q:~# A termelésben, ha lehetséges, jobb, ha a hosztokat
root-ceph01-q:~# állványok szerint elosztjuk, és megadjuk, hogy a replikák állványok között legyenek elosztva:
root-ceph01-q:~# ##ceph osd crush rule create-simple rule-ssd ssd-root rack firstnLétrehozzuk azokat a púlusokat, amelyekben a jövőben tárolni szeretnénk a virtuális környezetünk disk image-jeit — PROXMOX:
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 1024És megmondjuk ezeknek a púlusoknak, hogy milyen elosztási szabályokat használjanak.
root-ceph01-q:~#ceph osd crush rule ls # listázza a szabályokat
root-ceph01-q:~#ceph osd crush rule dump rule-ssd | grep rule_id # választjuk ki a szükséges ID-t
root-ceph01-q:~#ceph osd pool set ssd_pool crush_rule 2
A plémen csoportok számának kiválasztásakor figyelembe kell venni a klaszterünkre vonatkozó tervezést — körülbelül hány OSD lesz ott, milyen mennyiségű adat (százalékos arányban a teljes méretből) fog a púlban tárolódni, és mennyi adat lesz összesen.
Összességében kívánatos, hogy ne legyen több mint 300 plémen csoport egy lemezen, és könnyebb lesz a kis plémen csoportokkal való egyensúlyozás — tehát ha az egész púl 10 Tb és abban 10 PG van, akkor a terabájt méretű téglák (pg) áthelyezése problémát jelenthet — könnyebb homokot átszórni kis szemcsékkel a vödrök között.
De ne felejtsük el, hogy minél több PG van, annál több erőforrást igényel a helyük kiszámítása — elkezdődik a memória és a CPU kihasználása.
Egy nagyjából pontos elképzelés adhat , amelyet a CEPH dokumentáció fejlesztői biztosítanak.
Anyagok listája:
Forrás: habr.com
