🖥️ Operacje IT — niezawodność usług (SRE) Model na żywo
Jesteś na dyżurze przy usłudze webowej: load balancer przed flotą instancji, pamięć podręczna przed bazą danych i cel dostępności 99,9 %. Co minutę model oblicza opóźnienie kolejkowe, przekroczenia czasu, trafienia w pamięci podręcznej i obciążenie bazy z podręcznikowych wzorów — oraz ile kosztują twoje decyzje.
Czego się nauczysz
Dlaczego opóźnienie gwałtownie rośnie przy pełnym wykorzystaniu (Erlang C) i dlaczego autoskalowanie z opóźnieniem rozruchu zawsze przychodzi za późno.
Jak SLO, budżety błędów i alerty tempa spalania decydują o wycofaniu wydania.
Jak zimna pamięć podręczna zamienia się w awarię bazy danych i które narzędzia kupują czas: odrzucanie, degradacja, rozgrzewanie.
Symulator
Czas 0 min
▶Instancja obsługuje
⚙Instancja się uruchamia
!Instancja ze złą wersją
·Wolne miejsce
•Przychodzące żądania
Sterowanie
Dolna granica floty. Podniesienie jej uruchamia instancje od razu — nadal potrzebują opóźnienia rozruchu, zanim zaczną obsługiwać.
Śledzenie wartości docelowej wykorzystania; brak nowego skalowania w górę, dopóki instancje się uruchamiają. Wyłączone = dokładnie minimum.
Niższe = większy zapas i większy koszt. Zmierzone wykorzystanie nie może przekroczyć 100 %, więc nasycona flota rośnie tylko krok po kroku.
Dłuższy TTL = więcej trafień, ale odpowiedzi mogą być starsze (średni wiek ≈ TTL/2).
Ładuje gorące klucze przez 6 minut (+12 % pamięci podręcznej na minutę) kosztem 600 dodatkowych zapytań do bazy na sekundę.
Część niskopriorytetowych 30 % (prefetch, wsadowe, roboty) odrzucana na load balancerze z komunikatem „spróbuj później”.
Ciężka funkcja dodaje 20 ms CPU i jedno zapytanie do bazy na żądanie. Wyłączona = łagodna degradacja.
Wdraża ostatnią dobrą wersję na nowej flocie (5 min, płatne podwójnie), po czym przełącza ruch. Ponowne naciśnięcie restartuje przygotowanie; bez wadliwej wersji na produkcji kosztuje tylko pieniądze.
Wskaźniki
Odsetek błędów
0,00%
normalny
Opóźnienie p99
342ms
normalny
Pozostały budżet błędów (30 dni)
50,0%
normalny
Wykorzystanie floty
52%
normalny
Tempo spalania (1 h)
0,0 ×
Żądania
1125 req/s
Instancje obsługujące
10
Instancje w trakcie uruchamiania
0
Współczynnik trafień pamięci podręcznej
77 %
Wykorzystanie bazy danych
19 %
Odrzucony ruch
0 %
Koszt floty
4,00 $/h
Dotychczasowy koszt
0,00 $
Średni wiek odpowiedzi w pamięci podręcznej
30 s
Ruch na złej wersji
0 %
Dostępne rekomendacje
100 %
Trend
Scenariusze kryzysowe
Poziom 1 · Zła wersja
Nowa wersja wychodzi o 09:10. Miesiąc już był ciężki: zostało tylko 20 % budżetu błędów. Kilka minut po wdrożeniu odzywa się alert tempa spalania. Chroń budżet.
Pozostały budżet błędów na końcu ≥ 18,5 %
Średni odsetek błędów ≤ 0,65 % po wdrożeniu
Koszt floty ≤ 9,50 USD
Poziom 2 · Nagły napływ tłumu
Link do usługi szybko się rozchodzi i spodziewany jest skok ruchu kiedyś tego ranka — nikt nie wie kiedy ani jak duży. Nowe instancje potrzebują dziś 8 minut na uruchomienie. Gdy nadejdzie, utrzymaj niski poziom błędów i opóźnień, nie spalając pieniędzy na bezczynną moc.
Średni odsetek błędów ≤ 0,2 %
Średnie opóźnienie p99 ≤ 400 ms
Średni odrzucony ruch ≤ 5 %
Łączny koszt ≤ 21 USD
Rekomendacje dostępne ≥ 85 % czasu
Poziom 3 · Zimna pamięć podręczna
W południowym szczycie skrypt konserwacyjny czyści całą pamięć podręczną. Każde żądanie trafia teraz do bazy, zaprojektowanej na zwykłe 85 % trafień. Przywróć usługę bez przeciążenia bazy danych.
Średni odsetek błędów ≤ 1,5 %
Wykorzystanie bazy nigdy powyżej 90 % po pierwszej minucie
Średni wiek odpowiedzi w pamięci podręcznej ≤ 90 s
Łączny koszt ≤ 9 USD
Rekomendacje dostępne ≥ 80 % czasu
Średni odrzucony ruch ≤ 5 %
Podstawa — model stojący za liczbami
Każda zależność używana przez symulator, wraz ze źródłem. Stałe oznaczone jako założenia to kalibracje poglądowe.
Żądania podążają za dobową krzywą plus zakłócenia; liczba na minutę jest losowa (Poisson, przybliżenie normalne) z niewielką zmiennością skokową.
λ(t) = base × (1 + 0.25·sin(2π(t + clock − 6 h)/24 h)) × surge(t), clock = time of day at the start (peak at 12:00); count/min ≈ N(60λ, √(60λ)) × (1 + N(0, 0.02))[6]Założenie: liczby workerów, czasy obsługi, wydajność bazy, rozmiar pamięci podręcznej, szybkość uzupełniania, ceny i odsetek błędów złej wersji to wartości poglądowe dla średniej usługi webowej.
Erlang C: prawdopodobieństwo, że żądanie musi czekać na wolnego workera w systemie M/M/N.
N = instances × 16 workers, a = λ·S; C(a, N) = B / (1 − (a/N)(1 − B)), B = Erlang B[3][6]
Ogon czasu oczekiwania: szansa czekania dłużej niż t maleje wykładniczo; żądania wciąż czekające przy 2-sekundowym limicie kończą się błędem. Powyżej przepustowości nadwyżka kończy się błędem.
Opóźnienie p99 z kwantyli czasu obsługi i czasu oczekiwania.
p99 ≈ S·ln 100 + ln(C/0.01)/(N/S − λ) (service + waiting quantile, an approximation)[3][6]Przybliżenie: dodanie kwantyli obsługi i oczekiwania nie daje dokładnego p99 ich sumy (może być nieco za wysokie lub za niskie); kolejka jest traktowana jako ustalona w obrębie każdej minuty, bo żądania trwają milisekundy.
Prawo Little’a: zajęci workerzy = tempo napływu × czas obsługi.
Pamięć podręczna z TTL: przy losowych żądaniach każde chybienie rozpoczyna okres TTL, w którym żądania trafiają.
hit = warm × rT/(1 + rT), r = λ / 20,000 objects; mean age of a cached answer ≈ T/2[5]
Chybienia pamięci podręcznej obciążają bazę; jej opóźnienie kolejkowe spowalnia każde żądanie, które jej dotyka, co też zapełnia workery aplikacji.
DB load = λ·q·(1 − hit); query time = 5 ms/(1 − ρ_db) (≤ 250 ms); S = S_app + (1 − hit)·q·query time[6]Założenie: liczby workerów, czasy obsługi, wydajność bazy, rozmiar pamięci podręcznej, szybkość uzupełniania, ceny i odsetek błędów złej wersji to wartości poglądowe dla średniej usługi webowej.
SLO i budżet błędów: tempo spalania mówi, ile razy szybciej niż dozwolono wydawany jest budżet.
budget = 1 − SLO = 0.1 %; burn = error rate / 0.1 %; Δbudget per min = burn / 43,200; burn (1 h) = mean error rate over the last 60 min / 0.1 % (window pre-filled with the opening minute)[1][2]
Autoskaler śledzący wartość docelową z opóźnieniem rozruchu i czasem odczekania.
desired = ⌈serving × utilization / target⌉ (utilization saturates at 100 %); new instances serve after the boot delay[6]Założenie: liczby workerów, czasy obsługi, wydajność bazy, rozmiar pamięci podręcznej, szybkość uzupełniania, ceny i odsetek błędów złej wersji to wartości poglądowe dla średniej usługi webowej.
Pozostałe stałe operacyjne używane w modelu.
16 workers/instance · app time 50 ms (+20 ms and +1 query with the feature on) · 2 queries/request · DB 4,000 queries/s · 20,000 hot objects · cache refill τ = 30 min (slower while the DB is saturated) · warm-up job +12 %/min for 6 min, +600 queries/s · timeout 2 s · 30 % low-priority traffic · bad build +5 % errors, ×1.25 CPU · rollback 5 min · $0.40 per instance-hour · scale-in by ≤ 20 % of the fleet after 10 quiet minutes · up to 40 instancesZałożenie: liczby workerów, czasy obsługi, wydajność bazy, rozmiar pamięci podręcznej, szybkość uzupełniania, ceny i odsetek błędów złej wersji to wartości poglądowe dla średniej usługi webowej.
Losowość: generator mulberry32 z ziarnem; użyte rozkłady — jednostajny, wykładniczy (odwrotna dystrybuanta), normalny (Box–Muller), Poissona (Knuth). Ziarno jest widoczne i można je udostępnić.
M. Harchol-Balter — Performance Modeling and Design of Computer Systems: Queueing Theory in Action (M/M/k, server farms, capacity provisioning) — Cambridge University Press, 2013