Presja pamięci w jądrze systemu Linux ma bezpośredni wpływ na systemy hostingowe: gdy presja rośnie, czas procesora i operacje wejścia/wyjścia przenoszą się na bardziej zasobochłonne Odzyskać, wydłuża się czas odpowiedzi i rośnie ryzyko wystąpienia błędu OOM. Wyraźnie pokazuję, w jaki sposób rozpoznaję, mierzę i łagodzę obciążenie pamięci, aby Hosting- stale reagować na obciążenia.
Punkty centralne
Skupiam się na kluczowych czynnikach, które w środowiskach hostingowych decydują o wydajności i awariach. Poniższe punkty stanowią główną oś, wokół której ukierunkowuję proces diagnostyki i optymalizacji. Dzięki temu przeglądowi unikam błędnej interpretacji komunikatu „pełna pamięć RAM“ i rozpoznaję rzeczywiste Ciśnienie w odpowiednim czasie.
- Wskaźniki PSI pokazują czasy oczekiwania zamiast samego obłożenia i pozwalają wcześnie wykrywać opóźnienia.
- Obciążenie swapowe wskazuje na problemy z funkcją Reclaim, które nasilają obciążenie wejścia/wyjścia i opóźnienia.
- Limity cgroups Sterowanie ograniczaniem przepustowości, zabezpieczeniami i zachowaniem w przypadku wyczerpania pamięci (OOM) dla poszczególnych usług.
- Wypieranie z pamięci podręcznej ma bezpośredni wpływ na wydajność stron internetowych i baz danych.
- Planowanie wydajności a regulacja pozwala zachować rezerwę mocy i zapobiega przeciążeniom.
W ten sposób organizuję swoje analizy – od jądra systemu aż po aplikację – i wdrażam odpowiednie działania zgodnie z ustalonymi priorytetami. Skupiam się na mierzalnych efekty, a nie na pracę na raty.
Co oznacza pojęcie „memory pressure” w jądrze systemu Linux?
Obciążenie pamięci oznacza, że jądro poświęca zauważalną ilość czasu na zwolnienie pamięci zamiast kontynuować pracę procesów użytkownika; procesor poświęca wówczas więcej czasu na operacje skanowania, zapisu i usuwania danych, podczas gdy żądania pozostają w kolejce. Wyraźnie rozróżniam pojęcia „pełna pamięć RAM“ i „brak dostępnej pamięci”. Headroom“: „Zapełniona“ pamięć podręczna to nic złego; wąskie gardła pojawiają się dopiero wtedy, gdy wzrastają nakłady na odzyskiwanie pamięci. Jądro skanuje listy nieaktywnych elementów, zapisuje brudny-usuwa strony, kasuje pamięć podręczną plików i przenosi strony anonimowe, gdy tylko wartość spadnie poniżej progu Watermarks. Decydujące znaczenie ma czas poświęcony na te czynności; znajduje on odzwierciedlenie w fazach oczekiwania zadań i wydłużonych czasach odpowiedzi. Host może działać płynnie przy obciążeniu na poziomie 95 %, o ile pamięć podręczna jest łatwa do odzyskania, ale przy niższym obciążeniu może ulegać poważnym zacięciom, gdy konieczne jest wyparcie aktywnych stron anonimowych.
Zrozumienie i pomiar PSI
System Pressure Stall Information (PSI) pozwala nam namacalnie ocenić obciążenie pamięci, ponieważ mierzę nie zajętość, lecz opóźnienia. W /proc/pressure/memory Widzę „some“ i „full“: „some“ opisuje okresy, w których co najmniej jedno zadanie oczekuje na pamięć, natomiast „full“ sygnalizuje fazy, w których wszystkie zadania czekają jednocześnie. Przykład: „some avg10=4.67“ oznacza, że w ciągu ostatnich 10 sekund 4,67 % czasu stanowiły zastoje spowodowane niedoborem pamięci; „full avg10=0.30“ wskazuje na rzadkie sytuacje całkowitego zablokowania. Wcześnie koreluję rosnące wartości „some“ z czasami odpowiedzi i skaluję, dostrajam lub odciążam system, zanim pojawią się poważne sytuacje OOM. Takie podejście pozwala mi nie dać się zwieść pozornie „dużej ilości wolnej“ pamięci RAM, ponieważ wolne strony bez szybkiego Odzyskać-rzadko korzystają z tej możliwości.
| Mierzona zmienna | Wartość orientacyjna | Objaw | Działanie |
|---|---|---|---|
| Pamięć PSI (średnia z 10 pomiarów) | > 2–3 % w trybie ciągłym | Wydłużają się czasy odpowiedzi | Sprawdź rezerwę pamięci RAM, precyzyjnie dostosuj limity grup Cgroup |
| Pamięć PSI zapełniona (avg10) | > 0,1 % odczuwalne | Krótkie czasy przestoju | Zidentyfikować przyczynę, zakończyć thrashing |
| MemAvailable | < 10 % pamięci RAM | Niewielki zapas bezpieczeństwa | Odciążenie pamięci podręcznej/obciążenia, planowanie wydajności |
| vmstat si/so | stałe > 0 | Ciśnienie wymiany | Swappiness/Dostosuj swap, chroń zestaw hot |
Objawy występujące w środowiskach hostingowych
Na obciążonych serwerach najpierw dostrzegam skoki opóźnień, podczas gdy obciążenie procesora wydaje się pozostawać na umiarkowanym poziomie; jądro tkwi w pętlach odzyskiwania, operacje wejścia/wyjścia kumulują się, a żądania czekają. Średnie obciążenie rośnie, mimo że jądra wydają się być wolne, ponieważ wiele zadań blokuje się w pamięci lub na operacjach wejścia/wyjścia; jest to kluczowa oznaka zwiększonego Ciśnienie. Utrzymujące się wartości si/so w vmstat wskazują, że system aktywnie korzysta z pamięci wymiany, co spowalnia nawiązywanie połączeń TLS, ładowanie treści dynamicznych oraz przetwarzanie zapytań. Jeśli problem nie zostanie rozwiązany, system popada w stan thrashingu: procesor spędza większość czasu na stronicowaniu i zamianie danych, zamiast wykonywać użyteczną pracę. W miarę eskalacji sytuacji wkracza OOM-Killer i kończy procesy o wysokim wyniku; ukierunkowane Analiza programu OOM-Killer pomaga mi rozpoznawać wzorce i błędne konfiguracje.
Znaczenie dla obciążeń hostingowych i grup Cgroup
W środowiskach współdzielonych wystarczy kilka aplikacji wymagających dużej ilości pamięci, aby zwiększyć opóźnienia dla wielu klientów; grupy C (cgroups) łagodzą te skutki, ale nie rozwiązują problemu niewłaściwie dobranych rozmiarów Wystąpienia. W przypadku serwerów VPS i instancji w chmurze zbyt mała ilość pamięci RAM lub nieodpowiednia strategia wykorzystania pamięci wymiany szybciej prowadzi do skoków obciążenia; izolacja chroni inne usługi, ale nie własną. Bazy danych opierają się na dużych pulach buforów; gdy funkcja Reclaim je zwalnia lub uruchamia się wymiana, wydłuża się czas realizacji zapytań, a przepustowość znacznie spada. Systemy orkiestracji kontenerów wykorzystują parametry memory.low, memory.high i memory.max, aby chronić kluczowe usługi, ograniczać zacięcia i w razie potrzeby celowo je zamykać. Dlatego świadomie dobieram limity i monitoruję wskaźnik PSI dla każdej usługi, aby móc na czas podjąć odpowiednie działania i zapewnić rezerwy dla krytycznych Obciążenia należy utrzymywać w stanie wolnym.
Strategia monitorowania i wskaźniki
Sprawdzam wartości MemAvailable, Buffers i Cached, aby zorientować się, ile pamięci można odzyskać w krótkim czasie; same wartości MemFree mogą łatwo wprowadzać w błąd. Równolegle sprawdzam vmstat: utrzymujące się wartości si/so wskazują na obciążenie pamięci wymiany, co znacznie przyspiesza operacje wejścia/wyjścia i zwiększa opóźnienia; aby poznać kontekst Wykorzystanie swapów Korzystam ze sprawdzonych schematów diagnostycznych. PSI dostarcza mi brakujący element, ponieważ „some“ i „full“ pozwalają określić rzeczywiste opóźnienia; generuję alerty przy przekroczeniu progów i oddzielam szczyty obciążenia od chronicznych wąskich gardeł. Szeregi czasowe uzyskane za pomocą sar lub stosu obserwowalności uwidaczniają wzorce i pomagają mi potwierdzić skuteczność optymalizacji. dmesg ujawnia zdarzenia OOM, które wskazują na twarde ograniczenia lub błędne konfiguracje; w ten sposób tworzę spójny obraz z perspektywy jądra, zachowania operacji wejścia/wyjścia oraz Zastosowanie.
Typowe obciążenia w warunkach stresu
Serwery WWW, takie jak Nginx czy Apache, dostarczają treści wolniej, gdy w tle działają procesy Reclaim i Swap; połączenia Keep-Alive pozostają otwarte dłużej, co powoduje wydłużenie kolejek. Stosy PHP i Python zajmują pamięć RAM poprzez pamięci podręczne frameworków, elementy JIT oraz dane sesji; w przypadku wyparcia dane te przemieszczają się między pamięcią RAM a pamięcią masową, co znacznie wydłuża czas odpowiedzi. Bazy danych tracą na szybkości, gdy tylko puli buforów się zmniejszają lub ich części trafiają do pamięci swapowej; nawet niewielkie dodatkowe opóźnienie na operację wejścia/wyjścia kumuluje się przy dużej liczbie Zapytania. Usługi buforujące, takie jak Redis czy Memcached, wymagają trafień w pamięci RAM; jeśli obszary kluczy trafią do pamięci wymiany, korzyść ta znika, a wzrasta ryzyko zakończenia działania w sytuacji obciążenia. We wszystkich przypadkach wskaźniki PSI i swap dostarczają najjaśniejszych sygnałów, że pamięć stała się wąskim gardłem, a nie CPU.
Optymalizacja systemu i parametry jądra
Zaczynam od vm.swappiness: umiarkowanie obniżone ustawienie zapobiega nadmiernemu wykorzystywaniu pamięci wymiany, nie blokując przy tym niezbędnego odzyskiwania pamięci; skutki konsekwentnie mierzę za pomocą PSI. Następnie optymalizuję vm.dirty_ratio i powiązane limity, aby nie wywoływać długich fal operacji flush, a jednocześnie nie powodować nadmiernego zapisu danych; oba te czynniki mają zauważalny Efekty w zakresie opóźnień. W Cgroups v2 ustawiam memory.low dla usług krytycznych, memory.high do ograniczania wydajności w przypadku przeciążenia oraz memory.max jako sztywny limit z kontrolowanymi sytuacjami OOM. Zwracam szczególną uwagę na topologie NUMA: może pojawić się lokalny nacisk, mimo że w skali globalnej pamięć RAM jest nadal wolna; Powiązania procesów z pamięcią pozwalają uniknąć takich pułapek. Na koniec sprawdzam zachowanie pamięci podręcznej stron; niepotrzebne wypieranie obniża współczynniki trafień i bezpośrednio kosztuje czas w przypadku obciążeń związanych z siecią i bazami danych, do czego przyczynia się Optymalizacja pamięci podręcznej stron dostarcza przydatnych spostrzeżeń.
Dogłębna analiza ścieżek Reclaim
Aby trafnie dobrać środki, rozróżniam kswapd oraz Bezpośrednie odzyskiwanie. kswapd działa asynchronicznie, gdy wartość nie osiąga poziomu watermarków; działa stosunkowo łagodnie, o ile dostępna jest wystarczająca ilość pamięci podręcznej, którą można łatwo odzyskać. Direct Reclaim ingeruje synchronicznie w konteksty wykonywania, gdy wątki pilnie potrzebują stron – to właśnie wtedy pojawiają się zauważalne dla użytkowników spowolnienia. Obserwuję, czy odzyskiwanie dotyczy raczej pamięci podręcznej plików, czy stron anonimowych: jeśli jądro wypiera przede wszystkim pamięć podręczną plików, wzrasta liczba nieudanych odwołań do pamięci podręcznej; jeśli wypiera pamięć anonimową (np. stertę), grożą gwałtowne zatrzymania i aktywność wymiany. Nowoczesne mechanizmy zestawu roboczego uwzględniają odległości ponownego odwołania, aby dłużej utrzymywać przydatne strony; jeśli mimo to widzę wiele powtarzających się ponownych odwołań, wiem, że zestawy gorące są większe niż dostępna Headroom stały się.
Ponadto zwracam uwagę na zagęszczanie i defragmentację: kcompactd stara się tworzyć spójne obszary, na przykład dla dużych przydziałów lub THP. Jeśli proces zagęszczania nie nadąża, obserwuję wzrost wykorzystania procesora przez kcompactd, rosnące opóźnienia oraz zwiększony udział stanu „full“ w PSI podczas szczytów obciążenia. W takich przypadkach często sensowniejsze jest obniżenie obciążenia lub dostosowanie zasad THP, zamiast po prostu zwiększać ilość pamięci wymiany.
Strategie swapowe w szczegółach
Swap nie jest wrogiem, lecz narzędziem – jednak niewłaściwie zastosowany może zwiększać opóźnienia. Rozróżniam:
- Brak swapu: Bezpieczne w przypadku opóźnień w wymianie, ale ryzykowne przy szczytach – sytuacje OOM pojawiają się wcześniej, a funkcja Reclaim nie ma bufora rezerwowego.
- Umiarkowany swap na szybkim dysku SSD: Dobrze nadaje się do przenoszenia rzadko odwiedzanych, anonimowych stron; chroni często używane zestawy w pamięci RAM, o ile parametry swappiness i limity cgroup są odpowiednio ustawione.
- zswap/zram: Kompresja odciąża operacje wejścia/wyjścia; nadaje się do hostów o mniejszym obciążeniu operacjami wejścia/wyjścia lub jako bufor chroniący przed krótkotrwałymi skokami obciążenia. Sprawdzam dostępność mocy obliczeniowej procesora oraz współczynnik kompresji, aby uniknąć spowolnienia spowodowanego obciążeniem procesora.
Nie ustawiam wartości swappiness na niski poziom w każdym przypadku; w przypadku obciążeń z dużą pamięcią podręczną plików warto zastosować nieco wyższą wartość swappiness, aby odsunąć „zimne” strony anonimowe i utrzymać stabilność pamięci podręcznej plików. Usługi krytyczne (np. bazy danych) zabezpieczam za pomocą opcji `memory.low`, a w razie potrzeby również poprzez zablokowanie ich zestawów aktywnych w pamięci RAM, aby pamięć wymiany nie dotknęła niewłaściwych elementów. Kluczowe jest to, że vmstat si/so a wskaźnik PSI konsekwentnie spada, gdy dostosowuję strategię; w przeciwnym razie wprowadzam korektę.
THP, zagęszczanie i fragmentacja
Transparent Huge Pages (THP) Oszczędzają operacje TLB i wspomagają aplikacje obciążające procesor oraz wymagające dużej ilości pamięci. Jednak w warunkach obciążenia powodują one operacje kompaktowania; opcja „always“ może wówczas prowadzić do znacznych opóźnień. Korzystam z „madvise“ celowo w przypadku obciążeń, które na tym zyskują (np. niektóre silniki działające w pamięci), a w przypadku stosów internetowych wrażliwych na opóźnienia raczej celowo wyłączam THP lub zezwalam na nie wyłącznie za pośrednictwem madvise. Dodatkowo obserwuję vm.compaction_proactiveness i sprawdź, czy proaktywne zagęszczanie opóźnia powstawanie zasypów, czy też faktycznie je ogranicza. Jeśli boki THP są często rozcinane lub proces zagęszczania przebiega zbyt intensywnie, oznacza to, że jest go za mało Headroom lub nieodpowiednie schematy alokacji w aplikacji.
Pułapki NUMA i presja lokalna
Na hostach NUMA globalna „wolna pamięć RAM“ może być myląca: jeden gniazdo może być obciążone, podczas gdy inne pozostaje niewykorzystane. Sprawdzam statystyki NUMA i przypisuję procesy lokalnie (przypisanie do procesora/pamięci), aby zestawy obciążone pozostawały blisko źródła obciążenia obliczeniowego. Wykorzystanie funkcji Direct Reclaim na jednym węźle pomimo globalnych rezerw sygnalizuje nierównowagę w sieci NUMA; w takich przypadkach pomocne są alokacje przeplatane dla usług o szerokim zasięgu lub ścisłe przypisanie dla obciążeń monolitycznych. Wskaźnik PSI na cgroup w połączeniu ze statystykami NUMA pokazuje mi, czy pojedynczy węzeł generuje kolejki.
Działania związane z zastosowaniem
Analizuję profile pamięci za pomocą narzędzi ps, top, htop i Profiler, aby wykryć prawdziwe „pożeracze” pamięci i wycieki; przy tym obserwuję, jak zmieniają się zestawy „hot” w miarę upływu czasu. Pamięć podręczną aplikacji dobieram świadomie: zbyt duża powoduje obciążenie, zbyt mała obniża wydajność; dostosowuję je, kierując się wskaźnikami PSI i czasami odpowiedzi, a nie intuicją. W przypadku wykrycia sygnałów obciążenia aplikacja może dobrowolnie zwolnić mniej krytyczne pamięci podręczne lub dane tymczasowe; w ten sposób ograniczam zablokowania bez ingerowania w limity globalne. Parametry startowe i tuning GC (np. dla JVM) dostosowuję tak, aby zestawy robocze (Working Sets) mieściły się w pamięci RAM; agresywne wzorce alokacji łagodzę poprzez przetwarzanie wsadowe. Mam również na uwadze artefakty kompilacji i symbole debugowania, ponieważ przeoczone resztki kosztują w sposób niewidoczny Pamięć i zwiększają ryzyko późniejszych przeciągnięć.
Subtelności Cgroups v2 i strategie OOM
Dzięki Cgroups v2 wyraźnie rozdzielam ochronę, ograniczanie i twarde limity: memory.low rezerwuje headroom dla usług krytycznych; pozostały headroom jest przydzielany grupom o mniejszym znaczeniu. memory.high w przypadku przekroczenia limitu ogranicza wydajność w sposób ukierunkowany i zmusza aplikacje do zwolnienia pamięci, zanim system zacznie odczuwać negatywne skutki. memory.max to ostatnia linia obrony – jej przekroczenie oznacza OOM w kontrolowanych warunkach. Ustawiam PSI dla każdej grupy cgroup, aby alarmy uruchamiały się tam, gdzie dochodzi do zablokowań; globalny wskaźnik PSI pozostaje stabilny, podczas gdy pojedyncza usługa ulega awarii – właśnie ten wzorzec chcę wykrywać. W połączeniu z priorytetami OOM ustalam jasne zasady poświęcania procesów: nieistotne procesy wsadowe są zamykane jako pierwsze, a podstawowe interfejsy API zachowują swoje Headroom.
Wirtualizacja: ballooning, KSM i overcommit
W środowiskach wirtualnych mam do czynienia z podwójną presją: system-gość widzi pozornie wolną pamięć RAM, podczas gdy hiperwizor poprzez Baloniarstwo . Ta gra zwiększa koszty odzyskiwania po obu stronach. Mierzę wskaźnik PSI w systemie-gościu i koreluję go z metrykami hiperwizora; jeśli wskaźnik PSI rośnie podczas zdarzeń typu „ballooning”, maszyna wirtualna potrzebuje większej gwarantowanej pojemności lub lepszych zasad cgroup w systemie-gospodarzu. KSM oszczędza pamięć RAM dzięki deduplikacji identycznych stron, ale obciąża procesor; w konfiguracjach hostingowych z wieloma podobnymi maszynami wirtualnymi może to być opłacalne, o ile dodatkowe obciążenie procesora nie zagraża SLO. Overcommit (np. agresywne przydzielanie wielu małych maszyn wirtualnych) planuję wyłącznie przy stałych rezerwach SLO i ścisłym memory.low dla systemów, w których opóźnienia mają kluczowe znaczenie.
Decyzje architektoniczne w zakresie hostingu
Stawiam na rozkład horyzontalny, dzięki czemu poszczególne instancje są mniej narażone na skoki obciążenia; skalowalne pule łagodzą skrajne wartości i ograniczają opóźnienia. Wyraźnie rozdzielam role: bazy danych, aplikacje i buforowanie otrzymują własne pule zasobów, dzięki czemu procesy odzyskiwania nie powodują nieoczekiwanych skutków ubocznych wykraczających poza granice systemu. Wybieram pamięć masową pod kątem opóźnienia zapisu, ponieważ operacje czyszczenia brudnych stron mają bezpośredni wpływ na czasy odpowiedzi; szybka ścieżka odczuwalnie skraca czas odzyskiwania zasobów. W klastrach planuję rezerwy pamięci RAM na każdy węzeł i steruję za pomocą zasad harmonogramu, aby obciążenie i zużycie pamięci pozostawały równomiernie rozłożone. Automatyzuję skalowanie za pomocą progów PSI, tak aby rosnące wartości „some“ wyzwalały działania, zanim dojdzie do gwałtownego spowolnienia i Zabić-zdarzeń.
Planowanie wydajności i modele rezerwy wydajności
Headroom definiuję w sposób mierzalny: utrzymuję wystarczające rezerwy, aby „some“ PSI podczas normalnych szczytów pozostawało poniżej określonych progów, a stan „full“ praktycznie nie występował. W tym celu wykorzystuję percentyle (np. 99. percentyl obciążenia godzinowego) i planuję 10–30 % dodatkowej pamięci RAM w zależności od zmienności obciążenia. Bazy danych otrzymują większe stałe rezerwy, podczas gdy interfejsy internetowe skalują się bardziej dynamicznie. Kalibruję czasy odbicia: jak szybko spadają wskaźniki PSI i si/so po szczycie? Jeśli pozostają podwyższone, jest to oznaka zbyt małych rezerw lub nieodpowiedniej strategii swapowania/oczyszczania pamięci. W ten sposób planowanie wydajności staje się procesem ciągłym, a nie corocznym szacowaniem.
Alarmowanie i dostrajanie sterowane przez SLO
Łączę PSI z SLO użytkowników: jeśli wartość „some avg10“ rośnie równocześnie z opóźnieniami API, podejmuję działania. Alarmy dzielę na „żółte“ (utrzymujące się 2–3 % „some“, „full“ bliskie 0) i „czerwone“ (ponad 5 % „some“ lub „full“ > 0,1 %). Alarmy oparte na cgroupach pomagają wyodrębnić „głośną mniejszość”. Dodatkowo generuję alarmy dotyczące rosnących kolejek brudnych i czasów oczekiwania na zapis, aby móc na czas wygładzać fale brudnych danych. Celem jest, aby działania optymalizacyjne (swappiness, memory.high, rozmiary pamięci podręcznej) były obserwowalne i odwracalne; wprowadzam zmiany stopniowo i porównuję stan przed i po zmianach na podstawie tych samych wskaźników.
Diagnoza krok po kroku w codziennym życiu
Najpierw sprawdzam `free -h` i `MemAvailable`: jeśli wartość wyraźnie spada, szukam pamięci podręcznych, które można sensownie zwolnić, oraz usług o rosnących zestawach aktywnych. Następnie uruchamiam `vmstat` w krótkich odstępach czasu, aby zidentyfikować trendy si/so; utrzymujące się swappowanie potwierdza obciążenie i prowadzi mnie do ścieżki I/O. Następnie przeglądam /proc/pressure/memory i analizuję wartości „some“ oraz „full“ w przedziałach 10, 60 i 300 sekund; rosnące średnie wartości bezpośrednio powiązuję z zaobserwowanymi opóźnieniami. dmesg pokazuje mi ślady OOM i ujawnia, które procesy ostatnio wywołały lub doświadczyły kryzysów pamięciowych; na tej podstawie ustalam limity i priorytety dla grup C. Na podstawie tego wszystkiego formułuję hipotezę, wprowadzam niewielkie poprawki, weryfikuję je za pomocą PSI i zachowuję Czas reakcji w skrócie.
Podręczniki postępowania i typowe łańcuchy przyczynowo-skutkowe
Niektóre wzorce powtarzają się u mnie wielokrotnie:
- Zadania tworzenia kopii zapasowych lub skanowania wypierają pamięć podręczną stron: Nagle spada współczynnik trafień w pamięci podręcznej, a działanie sieci i baz danych ulega spowolnieniu. Działania: ograniczyć zadania (priorytet operacji wejścia/wyjścia), przesunąć przedziały czasowe, ustawić parametr `memory.high` dla grupy cgroup zadań, zabezpieczyć budżet pamięci podręcznej stron dla krytycznych usług.
- Luki w procesach typu worker: Powoli rosnąca pamięć anonimowa, wskaźnik PSI „some“ wzrasta przez wiele godzin. Działania: zidentyfikować wyciek, wdrożyć zasady automatycznego restartu i odzyskiwania pamięci, ustawić limity pamięci, aby wycieki nie zagrażały całemu hostowi.
- Zatrzymania spowodowane przez THP: Obciążenie kcompactd wzrasta w okresach szczytowego ruchu. Działanie: ustawić THP na „madvise“, dostosować odpowiednie usługi, sprawdzić parametry kompresji, zwiększyć rezerwę wydajności.
- Lokalne ciśnienie NUMA: Gniazdo ulega przeciążeniu, mimo że w pamięci RAM jest wolne miejsce. Działania: skorygować przypisania, zastosować interleave w przypadku szeroko rozłożonych obciążeń, dostosować rozkład obciążenia w harmonogramie.
- Wymiana danych na wolnych dyskach: jeśli si/so rośnie, czasy odpowiedzi gwałtownie wzrastają. Działania: przenieść pamięć wymiany na szybszy nośnik, rozważyć zastosowanie zswap/zram, doprecyzować ustawienia swappiness i polityki cgroup.
Każdy runbook kończy się weryfikacją: czy pojawiają się komunikaty „some/full“ i czy opóźnienia się stabilizują? Jeśli nie, to założenie było błędne lub niekompletne – w takim przypadku kontynuuję iterację.
Narzędzia i śledzenie w trakcie eksploatacji
Oprócz klasycznych narzędzi stawiam na bardziej dogłębną analizę: obserwuję stosunki pamięci podręcznej stron i pamięci anonimowej, wskaźniki błędów stron, wzorce ponownych błędów oraz kolejki zapisu zwrotnego. Podejścia oparte na eBPF i śledzeniu (tracing) pozwalają mi precyzyjnie zlokalizować miejsca, w których powstają opóźnienia – na przykład wzdłuż ścieżek odzyskiwania pamięci, w procesie zapisu zwrotnego lub podczas alokacji dużych bloków. Ważna jest dla mnie oszczędna instrumentacja nadająca się do środowiska produkcyjnego: krótkie okna aktywacji, próbkowanie zamiast ciągłego monitorowania oraz wyraźna korelacja z metrykami aplikacji. W ten sposób znajduję przyczyny, zanim zacznę na szeroką skalę zmieniać parametry.
Najważniejsze kwestie i kolejne kroki
Pojęcie „ Memory Pressure” odnosi się do czasu straconego z powodu niedoboru pamięci, a nie tylko do zajętej pamięci RAM; mierzę je za pomocą PSI, wcześnie rozpoznaję trendy i podejmuję działania w oparciu o dane. Kto połączy w całość dane z MemAvailable, vmstat si/so, PSI i dmesg, ten odkryje prawdziwe przyczyny skoków opóźnień i thrashingu. Dzięki dostosowaniu parametrów swappiness, dirty oraz cgroup celowo ograniczam zablokowania i zapewniam ważnym usługom ich Headroom. Na poziomie architektury rozkład obciążenia w płaszczyźnie poziomej, jasno określone role oraz szybkie ścieżki dostępu do pamięci masowej łagodzą skutki każdego szczytu obciążenia. Ostatecznie liczy się to, że nieustannie łączę diagnostykę z działaniami zaradczymi: mierzę, dostosowuję, ponownie mierzę – aż do momentu, gdy wydajność i Stabilność znów pasować.


