V roku 2022 sme spustili štyri samostatné Node.js služby pre štyroch rôznych klientov. Vo všetkých štyroch sa nám už počas discovery objavil Redis. Bolo to skoro automatické. „Sessions? Redis. Rate limiting? Redis. Cache pred databázou? Samozrejme, Redis.” Necelý rok neskôr sme robili interný retro a zistili, že tri z tých štyroch Redisov nemuseli byť nikdy v produkcii.
Toto nie je článok proti Redisu. Stále ho používame. Je to poznámka o tom, ako sa pridanie kúsku infraštruktúry stane zvykom skôr, než si to človek všimne — a koľko stojí, keď sa ten zvyk neprehodnotí.
Ako sme sa tam dostali
Žiaden z týchto projektov nemal cache v zadaní. Všetky štyri ju mali v architektonickom diagrame, ktorý sme nakreslili v prvom týždni. Nikto sa nás na to nepýtal — bola tam, lebo „takto to robíme”. Strata produktivity, ktorá vyzerá ako zvyk, je často horšia než zlé rozhodnutie. Zlé rozhodnutie aspoň raz niekto vyslovil nahlas.
Audit, ktorý sme si urobili sami
Na konci 2022 sme si sadli a pozreli, čo Redisy v tých štyroch produkciách reálne robia. Použili sme tri mesiace metrík z Datadogu plus rýchle profilovanie cez lokálnu repliku Postgresu.
- Projekt A (B2B SaaS, ~150 RPS): cache hit rate okolo 8 %. Deväťdesiatdva percent dotazov tak či tak išlo do Postgresu. Cache pridávala iba sieťový hop a problém s invalidáciou.
- Projekt B (interný nástroj, ~20 RPS): Redis používaný len pre sessions. Postgresová tabuľka s indexom na session_id robila to isté za prakticky rovnaký čas — tabuľka už beztak žila v RAM.
- Projekt C (verejný marketplace, ~600 RPS): Redis používaný pre rate limiting a cache produktov. Rate limiting bol opodstatnený. Cache produktov nie — Postgres prepared statement nad materializovaným view bol rýchlejší a nepotreboval invalidáciu.
- Projekt D (admin dashboard, ~10 RPS): Redis bol nasadený, ale takmer nepoužitý. Stál pamäť a jednu inštanciu navyše.
Tri zo štyroch Redisov sme po retre stiahli. Klientom sme to oznámili emailom v piatich riadkoch: prečo to robíme, čo to znamená pre ich faktúru za infraštruktúru, a kedy to spravíme. Žiaden z nich nemal dodatočnú otázku.
Kedy je Redis stále správna voľba
- Skutočne vysoko-frekvenčné read-heavy workloady, kde rozhoduje latencia a Postgres už beží na limite IO.
- Rate limiting cez viacero inštancií, kde potrebujete atomické inkrementy s TTL.
- Pub/sub pre malé real-time eventy, kde Postgres LISTEN/NOTIFY nestačí (typicky nad ~1 000 eventov/s).
- Krátkodobé fronty, kde nepotrebujete trvalosť a Postgres queue je zbytočne ťažký.
Redis je dobrý nástroj. Problém nikdy nebol s ním. Problém bol, že sme ho pridávali skôr, než sme si overili, či ho vôbec potrebujeme.
Tri otázky, ktoré si dnes kladieme pred pridaním cache
- Aký bude očakávaný cache hit rate? Ak nevieme alebo odhadujeme pod 30 %, neoplatí sa.
- Aká je invalidačná stratégia, ešte pred prvým riadkom kódu? Ak ju nevieme načrtnúť na tabuli za tri minúty, bugy z toho budú drahšie než pomalý dotaz.
- Vie to spraviť Postgres bez ďalšieho service? Materializované views, partial indexy, JSONB s GIN indexom, LISTEN/NOTIFY — v deviatich z desiatich „potrebujeme cache” situácií stačia.
Veľa „štandardných” architektúr je vlastne sediment. Pridávame veci, lebo sme ich už pridávali predtým. Pridať Redis trvá hodinu. Vyhodiť ho rok po nasadení trvá tri dni a jeden nepríjemný meeting.