Performance / Infrastructure

    Strategie cache

    Cache-Aside, Write-Through, Redis eviction policies, multi-level CDN+Redis+aplikacja i cache invalidation — jak zbudować efektywną warstwę cache.

    Cache-Aside
    Najpopularniejszy
    Write-Through
    Najsilniejsza spójność
    80-95%
    Hit rate cel
    Redis / Memcached
    Distributed cache

    6 wzorców cache

    Każdy wzorzec optymalizuje inny aspekt — spójność, latencję zapisu, latencję odczytu lub zużycie pamięci.

    Wzorzec Kiedy Spójność Write latencja Read latencja Ryzyko
    Cache-Aside Ogólne użycie, read-heavy Eventual Normalna Miss = 3 ops Stale data, stampede
    Write-Through Wymagana spójność Silna Wyższa (2 ops) Niska (hit) Nadmiarowe dane w cache
    Read-Through Transparentny cache layer Eventual Normalna Miss = transparentne Vendor lock-in (DAX)
    Write-Behind Write-heavy, batch DB Eventual (ryzyko utraty) Najniższa Niska (hit) Data loss przy crash
    Write-Around Rzadko czytane po write Silna (DB source of truth) Normalna Miss = wyższa Cold cache po write
    Refresh-Ahead Predictable access patterns Silna (proaktywna) Normalna Zawsze hit Zbędne odświeżanie

    Często zadawane pytania

    Jakie są strategie cache i kiedy stosować Cache-Aside vs Write-Through?

    Cache-Aside (Lazy Loading): aplikacja najpierw sprawdza cache. Cache miss -> aplikacja czyta z DB, zapisuje do cache, zwraca dane. Cache hit -> zwraca dane z cache. Zalety: tylko potrzebne dane w cache. Odporny na awarie cache (fallback do DB). Wady: cache miss = 3 operacje (cache read, DB read, cache write). Stale data przy concurrent updates. Write-Through: przy każdym write do DB -> jednocześnie update cache. Gwarancja spójności cache i DB. Zalety: cache zawsze aktualny. Zero stale data. Wady: write latencja wyższa (dwie operacje). Dane w cache które nigdy nie są czytane. Read-Through: cache layer pośredniczy. Aplikacja pyta cache, cache pobiera z DB jeśli brak. Transparentne dla aplikacji. Używają: AWS DAX (DynamoDB), Redis Enterprise. Write-Behind (Write-Back): zapis do cache, asynchronicznie do DB. Najwyższa write performance. Ryzyko: dane zgubione przy crash cache przed write do DB. Write-Around: bezpośredni write do DB, pominięcie cache. Cache trafia tylko przy read. Dla write-heavy danych które rzadko czytane. Refresh-Ahead: cache odświeża dane zanim TTL wygaśnie. Predykcja co będzie potrzebne. Netflix używa dla film metadata.

    Cache invalidation — najtrudniejszy problem w informatyce?

    Phil Karlton: 'There are only two hard things in Computer Science: cache invalidation and naming things.' Strategie invalidacji: TTL (Time-To-Live): najprostsza. Cache entry wygasa po N sekund. Wada: stale data przez cały TTL. Dobra dla: statyczne dane, tolerancja stale data. Event-Based Invalidation: przy update DB -> wyślij event -> invalidate cache keys. Np. OrderUpdated event -> del cache:order:{id}. Bardziej aktualne dane, wyższa złożoność. Versioned Cache Keys: klucz zawiera wersję (user:123:v5). Przy update -> inkrementuj wersję. Stare klucze automatycznie wygasają przez TTL. Cache Stampede (Thundering Herd): problem gdy TTL wygasa dla popularnego klucza. Setki requestów jednocześnie na DB. Rozwiązania: Mutex Lock — tylko jeden request odświeża, reszta czeka. Probabilistic Early Expiration — losowe odświeżanie przed TTL. Stale-While-Revalidate — zwróć stale data, odświeżaj w tle. Cache rzadko = prawidłowo: cache powinien być warstwą optymalizacji, nie wymaganiem. Jeśli cache down -> aplikacja działa wolniej ale działa. Distributed Cache Invalidation: multi-region invalidacja. Redis pub/sub do powiadamiania innych node. Cache coherency problem.

    Multi-level caching — CDN, Nginx, Redis, aplikacja, DB?

    Hierarchia cache (od najszybszego do najwolniejszego): L1 — In-process cache (aplikacja): HashMap/ConcurrentHashMap. Caffeine (Java) — high-performance local cache z LRU/LFU. Node.js memory cache. Najszybszy (ns latencja), najmniejszy, per-instancja. L2 — Distributed cache: Redis, Memcached. Wspólny dla wszystkich instancji aplikacji. ms latencja, większy, współdzielony. L3 — HTTP cache (Nginx/Varnish/CDN proxy): Cache-Control headers, Vary headers. Nginx proxy_cache. Sub-ms do ms latencja, duży. L4 — CDN (Edge cache): Cloudflare, AWS CloudFront, Fastly. Geograficznie bliski użytkownikowi. ms latencja, ogromny, globalny. L5 — DB cache (query cache, buffer pool): PostgreSQL shared_buffers. MySQL InnoDB buffer pool. Read replicas jako cache. Cache-Control headers dla CDN: max-age=3600 — cache 1 godzinę. s-maxage=86400 — CDN cache 24h (nadpisuje max-age dla shared caches). public — można cachować przez CDN. private — tylko przeglądarka. no-cache — revalidate przed użyciem. no-store — nie cachuj. stale-while-revalidate=60 — użyj stale przez 60s podczas odświeżania.

    Redis jako cache — wzorce i best practices?

    Redis Data Structures dla cache: String: prosty key-value. SET user:123 '{json}' EX 3600. Hash: pola użytkownika jako hash. HSET user:123 name 'Jan' age 30. Efektywne dla partial updates. List: kolejka, session history. Set: unikalne wartości (np. visited pages). Sorted Set: leaderboard, rate limiting (sliding window). Redis pipelining: wysyłaj wiele komend bez czekania na odpowiedź każdej. PIPELINE [SET, GET, SET] w jednym round-trip. Lua scripting: atomowe operacje złożone z wielu komend. Check-and-set bez race condition. Redis Cluster: automatyczny sharding. 16384 hash slots. Każdy node obsługuje część slotów. Horizontal scaling. Redis Sentinel: wysokie dostępność dla single shard. Automatyczny failover. Cache Eviction Policies: noeviction — błąd przy braku miejsca. allkeys-lru — wyrzuć najmniej ostatnio używane. allkeys-lfu — wyrzuć najmniej używane (frequency-based). volatile-lru — LRU tylko dla kluczy z TTL. allkeys-random — losowe. Dla cache: allkeys-lru lub allkeys-lfu. Memory optimization: maxmemory 4gb. maxmemory-policy allkeys-lfu. Kompresja JSON w cache (msgpack, brotli). Key naming: namespace:entity:id (user:profile:123). Monitoring: hit rate (cel 80-95%). Eviction rate. Memory fragmentation.

    Jak mierzyć efektywność cache i optymalizować hit rate?

    Kluczowe metryki cache: Cache Hit Rate = hits / (hits + misses). Cel: 80-95% dla production. Poniżej 80% -> problem. Eviction Rate: czy cache wyrzuca dane przed TTL? Jeśli tak -> za mały cache lub za długi TTL. Miss Latency: latencja cache miss -> DB. Porównanie z latencją bez cache. Mierzenie Redis: redis-cli INFO stats. keyspace_hits, keyspace_misses. hit rate = keyspace_hits / (keyspace_hits + keyspace_misses). Narzędzia: RedisInsight (GUI). Prometheus redis_exporter. Grafana dashboard. Optymalizacja hit rate: TTL tuning: zbyt krótki TTL = dużo miss. Zbyt długi = stale data i duże zużycie pamięci. Analiza access patterns (jakie klucze są miss-owane). Prefetching: ładuj dane do cache zanim użytkownik ich potrzebuje. Warm-up cache po deploymencie. Cache Warming: przy deploymencie -> pre-load popular data do cache. AWS ElastiCache: Global Datastore (multi-region). Cluster Mode. Backup i restore. Memcached vs Redis: Memcached — prosty, wielowątkowy, tylko string, brak persistence. Redis — więcej struktur danych, single-threaded (Redis 6+ multi-threaded dla IO), persistence, pub/sub, streams. Wybór: Redis prawie zawsze lepszy dla nowych projektów.

    Czytaj dalej

    Powiązane artykuły

    Kontakt

    Skontaktuj się z nami

    Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

    Wyślij zapytanie

    Bezpłatna wycena w 24h
    Bez zobowiązań
    Indywidualne podejście
    Ekspresowa realizacja

    Telefon

    +48 790 814 814

    Pon-Pt: 9:00 - 18:00

    Email

    adam@fotz.pl

    Odpowiadamy w ciągu 24h

    Adres

    Plac Wolności 16

    61-739 Poznań

    Godziny pracy

    Pon - Pt9:00 - 18:00
    Sob - NdzZamknięte

    Wolisz porozmawiać?

    Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

    Zadzwoń teraz