Articolul este tradus în cadrul pregătirii pentru lansarea cursului .

Occasionally, questions arise regarding Gluster's recommendations on kernel configuration and whether this is necessary.
Such necessity arises rarely. In most workloads, the kernel performs quite well. However, there is also a downside. Historically, the Linux kernel tends to consume a lot of memory if provided the opportunity, including for caching as a primary means of enhancing performance.
In most cases, this works excellently, but under heavy load, it can lead to issues.
We have extensive experience with memory-intensive systems, such as CAD, EDA, and similar, which started to lag under heavy loads. We occasionally faced issues with Gluster. By closely monitoring memory usage and disk wait times over several days, we encountered overloads, significant iowait, kernel errors (kernel oops), freezes, and so on.
This article is the result of numerous experiments on parameter tuning conducted in various situations. Thanks to these parameters, not only did overall responsiveness improve, but the stability of the cluster also increased significantly.
When it comes to memory configuration, the first thing to look at is the virtual memory subsystem (VM), which has a vast number of options that can be bewildering.
vm.swappiness
Parametru vm.swappiness determines how the kernel utilizes swapping relative to physical memory. In the source code, it is also defined as "tendency to steal mapped memory." A high swappiness value means that the kernel is more likely to unload mapped pages. A low swappiness value indicates the opposite: the kernel will unload pages from memory less frequently. In other words, the higher the value vm.swappiness, the more the system will use swap.
Extensive use of swapping is undesirable, as large blocks of data are loaded and unloaded from physical memory. Many argue that the swappiness value should be high, but in my experience, setting it to "0" leads to improved performance.
You can read more about it here —
Însă, din nou, aceste setări trebuie aplicate cu precauție și doar după testarea aplicației specifice. Pentru aplicațiile de streaming cu încărcare mare, acest parametru ar trebui setat pe „0”. Schimbarea la „0” îmbunătățește capacitatea de răspuns a sistemului.
vm.vfs_cache_pressure
Acest parametru controlează memoria consumată de kernel pentru cache-ul obiectelor de catalog și descriptorii de index (dentry și inode).
Cu o valoare implicită de 100, kernelul va încerca să elibereze cache-ul dentry și inode pe „baza echității” în raport cu pagecache și swapcache. Reducerea vfs_cache_pressure determină kernel-ul să păstreze cache-urile dentry și inode. Când valoarea este „0”, kernelul nu va curăța niciodată cache-ul dentry și inode din cauza presiunii de memorie, ceea ce poate duce cu ușurință la o eroare de tip out-of-memory. Creșterea vfs_cache_pressure peste 100 determină kernelul să acorde prioritate descărcării dentry și inode.
Când utilizați GlusterFS, mulți utilizatori cu volume mari de date și multe fișiere mici pot consuma multă memorie RAM pe server din cauza cache-ului inode/dentry, ceea ce poate duce la o scădere a performanței, deoarece kernel-ul trebuie să proceseze structuri de date într-un sistem cu 40 GB de memorie. Setarea acestui parametru peste 100 a ajutat mulți utilizatori să obțină o cache mai echitabilă și să îmbunătățească capacitatea de răspuns a kernelului.
vm.dirty_background_ratio și vm.dirty_ratio
Primul parametru (vm.dirty_background_ratio) definește procentul de memorie cu pagini murdare, atingerea căruia trebuie să înceapă deversarea în fundal a paginilor murdare pe disc. Atâta timp cât acest procent nu este atins, paginile nu sunt deversate pe disc. Iar atunci când deversarea începe, aceasta se desfășoară în fundal, fără a întrerupe procesele în curs.
Al doilea parametru (vm.dirty_ratio) stabilește procentul de memorie care poate fi ocupată de paginile murdare până la începutul unui reset forțat (forced flash). Odată ce acest prag este atins, toate procesele devin sincrone (blocate) și nu le este permis să continue până când operația solicitată de intrare-ieșire nu este efectiv finalizată și datele nu ajung pe disc. În cazul unor cereri de intrare-ieșire intense, apare o problemă, deoarece caching-ul datelor este absent și toate procesele care efectuează intrare-ieșire sunt blocate așteptând intrarea-ieșire. Acest lucru duce la un număr mare de procese suspendate, o sarcină ridicată, funcționarea instabilă a sistemului și o performanță slabă.
Reducerea valorilor acestor parametrii duce la faptul că datele sunt scrise pe disc mai frecvent și nu sunt păstrate în RAM. Acest lucru poate ajuta sistemele cu o cantitate mare de memorie, pentru care este normal să scrie pe disc cache-ul paginilor de 45–90 GB, ceea ce duce la timpi enormi de așteptare pentru aplicațiile frontend, reducând răspunsul general și interactivitatea.
„1” > /proc/sys/vm/pagecache
Cache-ul pe pagini (page cache) este un cache în care sunt stocate datele fișierelor și programelor executabile, adică paginile cu conținutul efectiv al fișierelor sau dispozitivelor de bloc. Acest cache este utilizat pentru a reduce numărul de citiri de pe disc. Valorile „1” indică faptul că pentru cache este folosit 1% din RAM și că vor fi mai multe operații de citire de pe disc decât din RAM. Nu este obligatoriu să schimbi acest parametru, dar dacă ești foarte preocupat de controlul cache-ului paginilor, poți să-l utilizezi.
„deadline” > /sys/block/sdc/queue/scheduler
Programatorul de intrare-ieșire (I/O scheduler) este un component al nucleului Linux care se ocupă cu cozile de citire și scriere. Teoretic, pentru un controler RAID inteligent, este mai bine să folosești „noop”, deoarece Linux nu știe nimic despre geometria fizică a discului, deci este mai eficient să permiți controlerului, care cunoaște bine geometria discului, să proceseze cererea cât mai repede posibil. Dar se pare că „deadline” îmbunătățește performanța. Poți citi mai multe despre planificatori în documentația codului sursă al nucleului Linux: linux/Documentation/block/*osched.txt. Și am observat, de asemenea, o creștere a lățimii de bandă pentru citiri în timpul operațiunilor mixte (multe operațiuni de scriere).
„256” > /sys/block/sdc/queue/nr_requests
Numărul de cereri de citire-scriere în buffer înainte de a fi transmise planificatorului. Dimensiunea cozii interne a unor controlere (queue_depth) este mai mare decât nr_requests al planificatorului de citire-scriere, astfel că planificatorul de citire-scriere are puține șanse de a prioritiza corect și de a efectua o fuziune a cererilor. Pentru planificatoarele deadline și CFQ, este mai bine ca nr_requests să fie de două ori mai mare decât coada internă a controlerului. Fuzionarea și reorganizarea cererilor ajută planificatorul să fie mai receptiv la sarcini mari.
echo «16» > /proc/sys/vm/page-cluster
Parametrul page-cluster controlează numărul de pagini care sunt scrise în swap simultan. În exemplul de mai sus, valoarea este setată la „16” conform dimensiunii stripe-ului (stripe size) RAID de 64 KB. Acest lucru nu are sens când swappiness = 0, dar dacă ai setat swappiness la 10 sau 20, utilizarea acestei valori te va ajuta când dimensiunea stripe-ului RAID este de 64 KB.
blockdev —setra 4096 /dev/<devname> (-sdb, hdc sau dev_mapper)
Setările dispozitivelor bloc pe default pentru multe controlere RAID conduc adesea la o performanță groaznică. Adăugarea opțiunii de mai sus configurează citirea anticipată pentru sectoare de 4096 * 512 byte. Cel puțin pentru operațiuni de streaming, viteza crește, umplând cache-ul intern al discului prin citirea anticipată pe perioada utilizată de kernel pentru pregătirea I/O-ului. În cache pot fi plasate datele care vor fi solicitate la următoarea citire. Citirea anticipată prea mare poate distruge I/O-ul aleator pentru fișiere mari, dacă folosește timpul potențial util al discului sau încarcă date dincolo de cache.
Iată câteva recomandări suplimentare la nivel de sistem de fișiere. Dar acestea nu au fost testate încă. Asigură-te că sistemul tău de fișiere cunoaște dimensiunea stripe-ului și numărul de discuri din raion. De exemplu, că acesta este un raion raid5 cu dimensiunea stripe-ului de 64K din șase discuri (de fapt din cinci, deoarece un disc este utilizat pentru paritate). Aceste recomandări se bazează pe presupuneri teoretice și sunt adunate din diverse bloguri/articole ale experților în RAID.
-> ext4 fs, 5 discuri, 64K stripe, unități în 4K blocuri
mkfs -text4 -E stride=$((64/4))
-> xfs, 5 discuri, 64K stripe, unități în sectoare de 512 byte
mkfs -txfs -d sunit=$((64*2)) -d swidth=$((5*64*2))Pentru fișiere mari, se poate considera posibilitatea de a crește dimensiunile stripe-urilor menționate mai sus.
ATENȚIE! Tot ceea ce a fost descris mai sus este extrem de subiectiv pentru anumite tipuri de aplicații. Acest articol nu garantează îmbunătățiri fără testarea prealabilă a aplicațiilor corespunzătoare din partea utilizatorului. Ar trebui aplicat doar în cazul în care este necesară îmbunătățirea reacției generale a sistemului sau dacă rezolvă problemele curente.
Materiale suplimentare:
Citește mai mult
Sursa: habr.com
