Buforowanie CDN i optymalizacja TTL
Krótkie podsumowanie
Pamięć podręczna CDN jest „akceleratorem + tarczą” między użytkownikiem a pochodzeniem. Działa dobrze, gdy:1. Klucz pamięci podręcznej jest stabilny i nie zawiera „hałasu”.
2. Polityka TTL pod obciążeniem: 's-maxage '/' max-age' + 'stale-while-escalate/if-error'.
3. Niepełnosprawność jest zarządzana: przez znaczniki/prefiksy + „miękkie” oczyszczenie.
4. Włącza się pamięć podręczną wielopoziomową/tarczę pochodzenia i pamięć podręczną ujemną.
5. Obserwowalność: współczynnik trafienia według warstw, p95 TTFB, udział zwrotu 304.
Nagłówki podstawy i co mają na myśli
„Cache-Control”:- 'max-age =
' - TTL dla przeglądarki. - s-maxage =
'- TTL dla CDN/proxy (nakłada się' max-age '). - 'stale-while-revalidate =
' - rozdawać przestarzałe, aktualizować równolegle. - 'stale-if-error =
' - zwracamy przestarzałą, gdy wystąpi błąd pochodzenia. - „wymienny” - zasób nie zmienia się (nadaje się do przekształconych aktywów).
- „ETag ”/„ Last-Modified” - warunki dla 304, z wyjątkiem bajtów/CPU pochodzenia.
- 'Vary' - lista nagłówków, które wpływają na klucz pamięci podręcznej (używać z przytrzymaniem!).
- „Surrogate-Control” - „extended” Cache-Control dla CDN (jeśli jest obsługiwany).
- „Wygasa” - przestarzałe, ale nadal rozliczane przez klientów.
Cache-Control: public, max-age=31536000, immutable
Przykład (półgłośnik z bezpieczną przestarzałością):
Cache-Control: public, s-maxage=300, max-age=60, stale-while-revalidate=600, stale-if-error=86400
ETag: "a1c3..."
Konstrukcja i normalizacja klucza pamięci podręcznej
Celem jest, aby zasadniczo te same prośby wpadły do tego samego obiektu.
Normalizacja URL: case, double slashes, trailing slash, order of query parameters.
Ignoruj „hałas”: 'utm _',' fbclid', 'gclid', arbitralne znaczniki ref.
Limited Vary: tylko bardzo znaczące tytuły ('Accept-Encoding', sometimes 'Accept', 'Accept-Language' dla locale).
Klasa urządzenia: w razie potrzeby użyj 2-3 klas (mobilny/pulpit/tablet), a nie niekończących się gałęzi agenta użytkownika.
Auth kontekst: nie buforować prywatne domyślnie; używać podpisanych adresów URL/plików cookie-bypass lub oddzielnych publicznych/prywatnych ścieżek.
Surrogate-Key: product:123 catalog
Cache-Control: public, s-maxage=300, stale-while-revalidate=600
Vary: Accept-Encoding
Strategie TTL według typu treści
Polityka w zakresie niepełnosprawności
Adres URL/Prefix: „zmień wszystko pod '/static/2025-11-05/'”.
Przez Tag/Key: „Usuń wszystkie 'katalog' i 'produkt: 123'”.
Miękkie oczyszczenie: zaznaczyć jako przestarzałe, nie wymazać obiektu - szybsze napełnianie.
Event-driven: CI/CD lub admin event wywołuje webhook „unieważnić tagi”.
Zalecenie: połączyć obie taktyki: ścieżki wersioning dla aktywów + tag-purge dla treści/stron.
Tiered-cache, pochodzenie-tarcza przedgrzewalna
Wielopoziomowa pamięć podręczna: regionalne warstwy CDN → mniej wniosków o pochodzenie.
Tarcza pochodzenia: jedna „tarcza” POP do pochodzenia - poprawia lokalizację i współczynnik trafienia.
Prewarm (pre-fetch): Rozgrzać gorące adresy URL/bufory przed wydarzeniem/zwolnieniem.
Pamięć podręczna ujemna: 5xx/Timeout pamięci podręcznej przez krótki czas (30-120 s), aby nie przytłaczać pochodzenia burzą retras.
Pamięć podręczna API: Kiedy można
Tylko GET/HEAD i idempotent.
Klucz: ścieżka + zasadnicze zapytania (na przykład, '? kategoria =... & page =... ').
Walidacja: 'ETag '/' Last-Modified' i 's-maxage'.
Filtry przez użytkownika: przynieś personalizację do funkcji klienta/krawędzi lub użyj podpisanych żądań + „publicznych” odpowiedzi.
Cache-Control: public, s-maxage=30, max-age=5, stale-while-revalidate=120, stale-if-error=600
ETag: "feed-v42"
Ochrona przed zatruciem pamięci podręcznej
Twardy URL/normalizacja nagłówka; biała lista parametrów w kluczu.
Kliknięcie podejrzanych nagłówków/duplikatów ('X-Forwarded-', rozszerzone 'Accept').
Limit 'Vary' i kontroluj rozmiar/liczbę nagłówków.
Separacja domeny: private/admin - na osobnej nazwie bez pamięci podręcznej.
Walidacja odpowiedzi: nie buforuj 4xx (z wyjątkiem 404 dla statycznych), nie buforuj stron „użytkownika” bez wyraźnej zasady.
Kompresja i formaty
Brotli dla tekstu (js/css/json), gzip - fallback; aktywa wstępnie sprężone są dopuszczalne.
Zdjęcia: webp/avif gdzie wsparcie; użycie 'Vary: Accept' + derivatives.
Zakres żądań dla wideo/audio: CDN caches kawałki.
Content-Negotiation: Zachować niską kardynalność klucza (klasa urządzenia zamiast surowych UA).
Obserwowalność i SLO
Kluczowe mierniki
Współczynnik trafienia (według bajtów/żądań) krawędź на/tier/shield.
p50/95/99 TTFB według regionu i typu (statyczny/API).
Fill-rate/Origin egress - ile idzie do pochodzenia.
304 szybkość i średni rozmiar odpowiedzi.
Budżet błędu: udział w kwestiach związanych z „ciągłym błędem ”/„ SWR”; częstotliwość oczyszczania.
Przykłady SLO
"p95 TTFB 'statics regionalnie ≤ 120-150 ms, API GET buforowany ≤ 200-250 ms.
Współczynnik uderzenia krawędzi ≥ 90%, półgłośniki ≥ 60%.
Odsetek odpowiedzi z gałęzi stałej z błędami ≤ 0. 5% w ciągu 30 dni.
Config oszukać arkusze
Nginx (reverse-proxy przed CDN lub w self-PoP)
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CDN:512m max_size=100g inactive=7d;
map $args $clean_args {
"~(^ &)(utm_ gclid fbclid) """; # default $ args simplified example;
}
server {
listen 443 ssl http2;
set $cache_key "$scheme$request_method$host$uri?$clean_args $http_accept $http_accept_encoding";
location /static/ {
proxy_cache CDN;
proxy_cache_key $cache_key;
proxy_ignore_headers Set-Cookie;
add_header Cache-Control "public, s-maxage=86400, max-age=3600, stale-while-revalidate=600" always;
proxy_pass https://origin_static;
}
location /api/public/ {
proxy_cache CDN;
proxy_cache_key $cache_key;
proxy_cache_valid 200 30s;
add_header Cache-Control "public, s-maxage=30, max-age=5, stale-while-revalidate=120, stale-if-error=600" always;
proxy_set_header If-None-Match $upstream_http_etag;
proxy_pass https://origin_api;
}
}
Wysłannik (SWR + pamięć podręczna, koncepcja)
yaml http_filters:
- name: envoy. filters. http. cache typed_config:
"@type": type. googleapis. com/envoy. extensions. filters. http. cache. v3. CacheConfig typed_config:
"@type": type. googleapis. com/envoy. extensions. cache. simple_http_cache. v3. SimpleHttpCacheConfig
Cache-Control/Surrogate-Control Header Cache Policies
We cache 5xx errors briefly via route/retry policy + local_rate_limit
Nagłówki dla „szybkich” aktywów
Cache-Control: public, max-age=31536000, immutable
ETag: "hash"
Content-Encoding: br
Nagłówki półgłośników (katalogi)
Cache-Control: public, s-maxage=600, max-age=120, stale-while-revalidate=1800, stale-if-error=86400
Vary: Accept-Encoding, Accept
FinOps: Jak gotówka oszczędza pieniądze
Pochodzenie Egress, mniejszy ładunek procesora/DB → niższe koszty infrastruktury.
Mniej żądań do płatnych backendów (wyszukiwanie/indeks/obrazy).
Metryka docelowa: $/spadek w p95 i $/spadek w egress o 1 GB - śledź efekt po uruchomieniu.
iGaming/specyficzne dla fintechu
Katalogi/aktywa dostawcy: ścieżki wersjonowane + TTL roczne.
Lądowania imprezy/turnieju: 1-5 min 's-maxage' + 'SWR' przez 10-30 min; tag-purge na aktualizacji.
Strony Liv (współczynniki/tabele): częściowy pamięć podręczna bloków JSON, krótki TTL (5-30 s), dla bloków osobistych - render klienta.
Punkty końcowe PSP/płatności: nie przechowywać w pamięci podręcznej, ścisłe „nie przechowywać”; Cache tylko książki referencyjne (tabele BIN, statusy).
Przeciwciała: buforowanie statyczne/GET, szare drogi dla podejrzanych ASN; Trzymaj „Varary” z dala od głośnych nagłówków.
Lista kontrolna implementacji
- Klucz pamięci podręcznej opisany: normalizacja adresu URL, lista dozwolonych zapytań, 'Vary' tylko dla żądanego.
- Drogi publiczne/prywatne oddzielone; prywatne - „bez sklepu” i obejście CDN.
- Wprowadzono drabiny TTL według typu zawartości; skonfigurowane 'SWR/if-error'.
- wielopoziomowa pamięć podręczna + tarcza pochodzenia skonfigurowana; ujemne-cache 5xx (krótkie) włączone.
- Istnieje znacznik/URL purge, miękkie oczyszczanie; integracja z CI/CD.
- Zawiera kompresję (br/gzip), formaty obrazu internetowego i odpowiedzi zakresu.
- Wskaźniki: współczynnik trafienia według warstwy, p95 TTFB, wskaźnik 304, wyjście pochodzenia; wpisy do awarii.
- Playbooks: cache heat-up przed szczytami, awaryjna czystka, degradacja pochodzenia.
Częste błędy
Nieversio aktywa z dużym TTL → „lepkie” wiązki od użytkowników.
Nadmierne 'Vary' (przez 'User-Agent', wszystkie nagłówki) → eksplozja kardynalności i niski współczynnik trafienia.
Buforowanie 4xx/401/403/zawartość prywatna.
Brak negatywnej pamięci podręcznej → lawina wniosków o zdegradowane pochodzenie.
No tag-purge → Massive point purge i storm re-fill.
Klucz pamięci podręcznej zawiera „hałaśliwe” parametry UTM/ref.
Zbyt krótki TTL dla statyków → dodatkowe obciążenie na CDN i pochodzenie.
Mini playbooks
1) Rozgrzać pamięć podręczną przed wydarzeniem
1. Zbieranie adresów URL top-N przez dzienniki → 2) Prefetch równoległy (wskaźnik ograniczony) według regionu → 3) Sprawdź stosunek hitu do p95.
2) Awaryjni katolicy miękko-oczyszczający
1. Wyślij 'PURGE '/tag-clear → 2) CDN daje stale i ściąga świeże z tłem → 3) Sprawdź, czy nie ma kolców na pochodzenie.
3) Awaria pochodzenia
1. 'stale-if-error' pomaga X godziny → 2) Włączyć baner „praca techniczna” na krawędzi → 3) Po odzyskaniu - cel rozgrzewka.
Wynik
Silna strategia CDN = poprawny klucz pamięci podręcznej + znaczący TTL z SWR/if-error + managed disability + level/shield + observability. Naprawić politykę w nagłówkach i IaC, zmierzyć współczynnik hitu i p95, planować ogrzać do szczytów - a użytkownicy zawsze otrzymają szybką odpowiedź, a pochodzenie pozostanie przy życiu nawet w najgorętszej godzinie.