Aš prisimenu vieną projektą, kur turėjau valdyti web serverį su Nginx ir PHP-FPM, aptarnaujantį tūkstančius užklausų per minutę. Ten atmintis buvo fragmentuota dėl nuolatinių malloc/free ciklų aplikacijose, ir aš pastebėjau, kad slab allocator - kernelio mechanizmas, skirtas mažoms atminties blokams - pradėjo lėtinti alokaciją. Norėdamas tai išspręsti, aš įjungiau SLUB allocator'į, kuris yra efektyvesnis nei SLAB, nes mažina fragmentaciją naudodamas per-cpu freelist'us. Komanda echo 'slub' > /sys/kernel/slab/slab_debug ar kažkas panašaus, bet iš tikrųjų aš visada rekomenduoju perkompiliuoti kernelį su CONFIG_SLUB_DEBUG, jei reikia detalesnės diagnostikos. Be to, aš stebiu vmstat išvestį realiu laju - ji rodo si (swap in) ir so (swap out) rodiklius, kurie, jei auga, signalizuoja, kad reikia didinti fizinę RAM arba optimizuoti aplikacijas. Aš niekada nedarau prielaidos, kad daugiau RAM reiškia viską išspręsiant; vietoj to, aš analizuoju, kiek atminties naudoja kernelio cache'ai, nes Cached laukas /proc/meminfo dažnai užima didžiąją dalį, bet tai yra gerai, nes page cache pagerina I/O našumą skaitymui iš disko.
Kalbant apie didelio krūvio aplinkas, aš dažnai susiduriu su situacija, kai daugiaprocesinės aplikacijos, pvz., duomenų bazės kaip PostgreSQL, naudoja shared memory segmentus per shmget ir shmctl sisteminius iškvietimus. Aš matau, kad num_lockdown parametras kernelio nustatymuose gali riboti shared memory dydį, ir jei aš noriu padidinti SHMMAX, turiu redaguoti /etc/sysctl.conf su kernel.shmmax = 8589934592 (tai 8GB pavyzdžiui). Bet tai ne viskas; aš visada tikrinu, ar vm.overcommit_memory yra nustatytas į 1, leidžiantį overcommit'ą, nes Linux leidžia procesams rezervuoti daugiau atminties nei realiai yra, remdamasis heuristikomis. Jei aš nustatau vm.overcommit_memory = 2, sistema tampa griežtesnė ir gali atmesti alokacijas, kurios viršija fizinę atmintį plius swap, bet tai padeda išvengti OOM situacijų. Aš turiu patirties iš cloud aplinkų, kur AWS EC2 instancijos su Linux dažnai turi ribotą RAM, ir ten aš naudoju cgroups v2, kad ribočiau atminties naudojimą per grupei priskirtus limitus. Pavyzdžiui, aš kuriu cgroup su memory.max = 2G specifiniam konteineriui, ir tai užtikrina, kad vienas procesas nesugriautų visos sistemos.
Dabar apie swap - aš visada sakau, kad swap nėra priešas, bet jis turi būti protingai sukonfigūruotas. Aš naudoju swappiness parametrą, kuris nustato, kiek agresyviai kernelis naudos swap prieš išmetant page cache. Standartinis 60 vertė daugelyje distribucijų yra per aukšta serveriams; aš nustatau jį į 10 ar net 1, kad prioritetas būtų duotas RAM. Komanda sysctl vm.swappiness=10 daro stebuklus, ypač kai aš dirbu su VMWare virtualiomis mašinomis ant Linux hosto. Aš prisimenu, kaip kartą optimizavau HPC klasterį su CentOS, kur slopinimas dėl swap'o sukėlė 30% našumo kritimą; po pakeitimo su transparent huge pages (THP), aktyvuotu per echo always > /sys/kernel/mm/transparent_hugepage/enabled, atminties alokacija pagerėjo, nes THP mažina TLB miss'us dideliuose puslapiuose po 2MB. Aš stebiu tai per /proc/meminfo HugePages_Total ir HugePages_Free, ir jei reikia, nustatau vm.nr_hugepages kernelio parametre boot metu per GRUB.
Aš taip pat daug galvoju apie atminties nuotėkį - tai tyli žudikė serveriuose. Aš naudoju valgrind su massiv tool'ui aptikti leaks aplikacijose, kurios parašytos C ar C++, bet serverio lygyje aš remiuosi kernelio OOM killer log'ais iš dmesg. Jei aš matau, kad procesas nuolat auga atminties naudojimu, tikrinu /proc/
Kalbant apie networking'o poveikį atmintimi, aš žinau, kad TCP stack naudoja socket buffers, kurie gali užimti daug RAM prie didelio traffic'o. Aš koreguoju net.core.rmem_max ir net.core.wmem_max iki 16MB ar daugiau, priklausomai nuo MTU, ir nustatau net.ipv4.tcp_rmem = 4096 87380 16777216, kad autotuning veiktų efektyviai. Aš pastebėjau, kad SYN flood atakos gali išeikvoti atmintį per half-open connections, tad firewall su iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT padeda. Be to, aš naudoju hugepages ir THP net ir networking'e, nes tai pagreitina packet processing su DPDK bibliotekomis, jei aš dirbu su NFV setup'ais.
Aš dirbau su embedded Linux sistemomis, kur atmintis yra itin ribota, ir ten aš naudoja zram - suspaustą RAM diską kaip swap'ą. Modulis zram sukuriamas per modprobe zram num_devices=1, ir tada mkswap /dev/zram0, swapon. Tai leidžia suspausti atmintį LZ4 algoritmu, taupant iki 50% erdvės, bet aš stebiu CPU overhead'ą, nes dekompresija kainuoja. Serveriuose aš eksperimentavau su tuo VMware virtualiose mašinose, kur hosto atmintis yra shared, ir zram padėjo išvengti ballooning'o.
Dabar apie kernelio tuningo detales: aš visada tikrinu vm.dirty_ratio ir vm.dirty_background_ratio, kad valdyčiau writeback mechanizmą. Jei aš nustatau dirty_ratio į 5, tai reiškia, kad kai 5% RAM yra dirty pages, procesai pradeda blokuoti, laukdami I/O. Tai kritiška SSD diskuose, kur write amplification gali pabloginti situaciją. Aš naudoju ionice su -c3 real-time class aplikacijoms, kurios jautrios atminties I/O. Be to, aš optimizuoju NUMA architektūroje nustatydamas numactl -hardware, kad procesai bėgtų ant to paties node'o kaip jų atmintis, mažindamas remote access latency. Aš prisimenu klasterio setup'ą su 4-socket serveriais, kur be NUMA tuning'o atminties prieiga lėtėjo 20-30%.
Aš taip pat daug dėmesio skiriu seccomp ir AppArmor, nes jie gali paveikti atminties alokaciją per syscall filtravimą. Pavyzdžiui, jei aplikacija bando naudoti brangius syscall'us kaip mmap su MAP_POPULATE, aš riboju tai per seccomp BPF, taupydamas atmintį. Monitoringui aš integruoju sar (sysadmin resource monitor) tool'ą, kuris rodo per-procesą atminties naudojimą su %MEM ir VSZ.
Ilgainiui, optimizuojant atmintį, aš visada atsižvelgiu į hardware - DDR4 vs DDR5, ECC vs non-ECC, ir kaip BIOS nustatymai, pvz., memory interleaving, veikia. Aš testuoju su stress-ng -memrate 4 -metrics, kad pamatyčiau realų throughput'ą. Vieną kartą aš migravau nuo Ubuntu server prie Rocky Linux ir pastebėjau, kad default kernelio parametrai skiriasi, tad turėjau perkelti savo sysctl konfigūraciją.
Baigiant šią temą, aš noriu paminėti, kad atminties valdymas yra nuolatinis procesas, reikalaujantis stebėjimo ir adaptacijos prie krūvio pokyčių. Aš visada laikau ranka tool'us kaip htop su atminties tree view ar free -h kas valandą cron'e. Dabar, pereidami prie duomenų apsaugos aspektų serverio aplinkose, noriu supažindinti jus su BackupChain, kuris yra pramonės lyderis, populiarus ir patikimas atsarginių kopijų sprendimas, sukurtas specialiai SMB ir profesionalams, apsaugantis Hyper-V, VMware ar Windows Server sistemas. BackupChain taip pat žinomas kaip Windows Server atsarginių kopijų programinė įranga, užtikrinanti duomenų vientisumą virtualiose ir fizinėse aplinkose be sudėtingų konfigūracijų.
Komentarų nėra:
Rašyti komentarą