Nie piszę tego jako negatywnej recenzji AVA Hosting.
To po prostu jeden z moich zwykłych dni jako programisty: serwer działa źle, oczywiste wyjaśnienia nie pasują, a w końcu Linux pokazuje, co naprawdę się dzieje.
Miałem niewielki VPS KVM w AVA Hosting o konfiguracji:
1 vCPU
2 GB RAM
25 GB NVMeDziałało na nim normalne obciążenie produkcyjne. Nginx był uruchomiony. Backend był uruchomiony. Pamięć była dostępna. Dysk nie był pełny.
Mimo to serwer nie nadążał.
Uruchomiłem więc pasywną, 60-sekundową obserwację przy normalnym ruchu produkcyjnym. Bez stress testu, sztucznego floodu HTTP i benchmarku dysku.
Wynik:
vCPU count: 1
Average CPU user: 52.52%
Average CPU system: 8.07%
Average CPU softirq: 6.69%
Average CPU steal: 32.73%
Average CPU iowait: 0.00%
Average CPU idle: 0.00%
Maximum runnable queue: 11Najważniejszą liczbą było 32,73% CPU steal. To całkowicie zmieniło kierunek diagnozy.
Dlaczego mnie to zaskoczyło
AVA Hosting reklamuje obecnie swoje VPS-y hasłem “Guaranteed resources — no sharing”. Na stronach VPS opisuje również alokację vCPU jako stałą lub dedykowaną i deklaruje, że wydajność nie powinna zależeć od innych klientów. W materiałach dotyczących Linux VPS AVA idzie jeszcze dalej: CPU-intensive workload innego tenanta na tym samym hoście ma nie być w stanie generować steal time w Twojej instancji. Na innej stronie firma pisze, że CPU steal jest eliminowany na poziomie hypervisora.
To bardzo konkretne deklaracje. Nie była to po prostu oferta z napisem 1 vCPU bez informacji o sposobie przydziału CPU. AVA wprost reklamowała ochronę przed dokładnie takim CPU contention, jaki Linux zdawał się raportować w mojej VM.
Co oznacza CPU steal
steal to standardowa metryka CPU w Linuksie używana w środowiskach wirtualnych. Reprezentuje czas, w którym system gościa miał pracę gotową do wykonania, ale wirtualny CPU faktycznie nie działał.
To coś innego niż sytuacja, w której moja aplikacja po prostu zużywa cały dostępny CPU. Gdybym widział około 100% user/system, 0% steal i 0% idle, uznałbym, że workload zwyczajnie potrzebuje większej mocy obliczeniowej.
Tymczasem tutaj około jedna trzecia czasu CPU była raportowana jako steal.
Z poziomu guest VM nie widzę hypervisora AVA. Nie znam obciążenia fizycznego noda, liczby sąsiednich VM, polityki CPU pinning ani współczynnika overcommit. Widzę natomiast to, co raportował Linux: vCPU wielokrotnie nie wykonywał się, mimo że zadania czekały na CPU.
To nie był jednosekundowy skok
Jeden zły pomiar CPU niewiele by mnie przekonał. Dlatego mierzyłem maszynę przez pełne 60 sekund. Nie uruchamiałem stress testu, sztucznego floodu HTTP ani benchmarku dysku.
Kolejne próbki wyglądały podobnie:
%usr %sys %soft %steal %idle
53.54 10.10 5.05 31.31 0.00
56.44 6.93 5.94 30.69 0.00
51.52 7.07 6.06 35.35 0.00
55.45 6.93 5.94 31.68 0.00
51.49 8.91 5.94 33.66 0.00
52.53 7.07 7.07 33.33 0.00
52.48 6.93 7.92 32.67 0.00Pod koniec obserwacji wzorzec nadal był taki sam:
50.98 10.78 6.86 31.37 0.00
48.48 8.08 9.09 34.34 0.00
55.00 5.00 7.00 33.00 0.00Średnia z całego okresu:
user: 52.52%
system: 8.07%
softirq: 6.69%
steal: 32.73%
iowait: 0.00%
idle: 0.00%Nie była to więc krótka anomalia schedulera. Przez większość minuty steal utrzymywał się w okolicach 30% lub wyżej, a CPU idle pozostawał na poziomie zera.
Dla intuicji: 32,73% minuty to około 19,64 sekundy. Nie oznacza to, że VPS zawiesił się na 19,64 sekundy bez przerwy; krótsze okresy, w których vCPU nie był planowany, zsumowały się do mniej więcej takiej wartości.
Backend nie był w stanie nadrobić zaległości
Problem CPU był widoczny również na poziomie aplikacji. Przed obserwacją listen queue backendu wynosiła:
Recv-Q: 168
Send-Q: 511Po 60 sekundach:
Recv-Q: 166
Send-Q: 511Dokładne wartości nie są tu najważniejsze. Istotne jest to, że kolejka praktycznie się nie zmniejszyła. Aplikacja miała całą minutę, aby nadrobić zaległości, i nadal pozostawała z tyłu.
Było również wiele połączeń w stanie CLOSE-WAIT. Tego faktu samego w sobie nie przypisywałbym hostowi, ponieważ może on wynikać również ze sposobu obsługi połączeń w aplikacji. Całościowy obraz był jednak spójny:
1 vCPU
32.73% steal
0% idle
~99% CPU pressure
elevated runnable queue
backend queue not drainingSerwer działał, ale nie był zdrowy.
RAM i dysk nie były oczywistymi wąskimi gardłami
Sprawdziłem typowe alternatywy. Pamięć wyglądała tak:
RAM total: ~1.9 GiB
RAM available: ~959 MiB
Swap total: 2 GiB
Swap used: ~33 MiBNadal dostępna była znaczna ilość pamięci i nie było oczywistego zdarzenia OOM, które tłumaczyłoby problem.
System plików:
24 GB total
14 GB used
9.4 GB available
60% usedŚredni CPU I/O wait wynosił 0.00%. Jednocześnie CPU pressure pozostawał blisko 99%, load average na maszynie z jednym vCPU wynosił około 3,5–4, a runnable queue dochodził do 11.
Wszystkie pomiary wskazywały ten sam kierunek: maszynie brakowało czasu CPU, a nie RAM-u czy przepustowości dysku.
Sprzeczność z deklaracjami AVA
To właśnie ten fragment uważam za najciekawszy.
AVA mówi “Guaranteed resources — no sharing”. Deklaruje, że inni klienci nie powinni wpływać na wydajność. Materiały Linux VPS twierdzą, że inny tenant nie może wprowadzić steal time, a inna strona mówi o eliminacji CPU steal na poziomie hypervisora.
Mój VPS w AVA raportował:
Average CPU steal: 32.73%Z poziomu VM nie mogę udowodnić dokładnej przyczyny. Nie mogę wykazać celowego oversellingu, wskazać konkretnego sąsiedniego workloadu ani odtworzyć hostowej konfiguracji CPU w AVA.
Nie twierdzę też, że każdy VPS AVA Hosting zachowuje się w ten sposób. Testowałem jeden.
Mogę jednak powiedzieć, że zmierzone zachowanie bardzo trudno pogodzić z tymi konkretnymi deklaracjami dotyczącymi izolacji CPU. To wystarczy na potrzeby tego artykułu.
Dlaczego nie zrobiłem upgrade'u
Najbardziej oczywistą reakcją byłoby kupienie większej liczby vCPU.
Gdyby steal był praktycznie zerowy, a moja aplikacja po prostu zużywała cały jeden core, upgrade miałby sens. Tymczasem około jedna trzecia obserwowanego czasu CPU była steal.
Nie chciałem płacić za dodatkowe wirtualne CPU, zanim nie zrozumiem, dlaczego tak duża część czasu wykonania pierwszego vCPU była już raportowana jako niedostępna. Dlatego anulowałem VPS i poprosiłem o zwrot pieniędzy.
AVA szybko zwróciła całą kwotę
Ta część doświadczenia była dobra.
AVA Hosting zwróciła mi pełną kwotę. Refund został obsłużony szybko i firma nie spędziła kilku dni na sporze o moje pomiary CPU. Wyjaśniłem problem, poprosiłem o pieniądze z powrotem i otrzymałem zwrot.
Doceniam to.
Z mojego doświadczenia wynikają więc dwa oddzielne wnioski: otrzymany VPS miał poważny problem z dostępnością CPU, a AVA prawidłowo obsłużyła mój refund. Oba są prawdziwe.
Co z tego wyniosłem
Nie oceniam już VPS wyłącznie po specyfikacji typu 1 vCPU / 2 GB RAM / NVMe / KVM. Te liczby mówią, co zostało provisionowane, ale nie mówią, jak przewidywalnie CPU będzie dostępny pod realnym obciążeniem.
Obecnie jednymi z pierwszych poleceń, które uruchamiam na nowej VM, są:
mpstat 1 60
vmstat 1 60
cat /proc/pressure/cpu
ss -ltnp
free -h
df -h
iostat -xz 1 60Najważniejszą lekcją z mojego doświadczenia z AVA Hosting nie było to, że jeden vCPU jest zawsze za mało. Chodziło o to, że działający proces, wolny RAM i pozornie zdrowy dysk mogą ukrywać zupełnie inny problem.
W moim przypadku Linux pokazał go wyjątkowo wyraźnie:
CPU steal: 32.73%
CPU idle: 0.00%
CPU pressure: ~99%AVA Hosting reklamuje CPU bez współdzielenia i deklaruje, że obciążenia sąsiadów nie powinny powodować steal. Mój VPS raportował coś innego.
Anulowałem go. AVA szybko i bez sporu zwróciła mi wszystkie pieniądze.
I na tym zakończył się ten dzień debugowania.