Redis
Redis konfigurace a správa
Přehled
Redis v Turtor plní tři hlavní role:
- Cache -- Ukládání výsledků dotazů s TTL a stampede ochranou
- Fronty úloh (BullMQ) -- Asynchronní zpracování emailů, notifikací, generování kurzů
- Pub/Sub -- Koordinace cache invalidace přes eventy
Konfigurace
Lokální vývoj
# Spuštění Redis (součást docker:up)
pnpm docker:up
# Redis je dostupný na offsetovaném portu
REDIS_HOST=localhost
REDIS_PORT=6380 # Standardní port 6379 je offsetovaný
REDIS_PASSWORD= # Bez hesla pro devProdukce
V produkci Redis běží jako Docker služba s persistentním úložištěm:
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- turtor_redis_data:/data
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 10s
timeout: 5s
retries: 5Příznak --appendonly yes zapíná AOF (Append Only File) persistenci pro obnovu dat po restartu.
CacheService
Redis-backed cache s ochranou proti stampede efektu. Implementace je v apps/api/src/common/cache/.
TTL konstanty
| Konstanta | Hodnota | Použití |
|---|---|---|
CACHE_TTL.STATIC | 1 hodina | Regiony, specializace, lokace, konfigy |
CACHE_TTL.GEO | 24 hodin | Města (seed data, nemění se) |
CACHE_TTL.ENTITY_DETAIL | 15 minut | Certifikace instruktorů, lokace kurzů |
CACHE_TTL.STATS | 5 minut | Statistické endpointy |
CACHE_TTL.GENERATION_LOG | 30 minut | Logy generování (immutable) |
Cache skupiny
Invalidace probíhá po skupinách při změnových eventech:
| Skupina | Invalidační event |
|---|---|
regions | region.changed |
specializations | specialization.changed |
courses | course.changed, booking.changed |
instructors | instructor.changed, booking.changed |
bookings | booking.changed |
companies | company.changed |
Stampede ochrana
Metoda getOrSet() používá Redis mutex (SET NX EX 5) -- pouze jeden caller spouští factory funkci, ostatní čekají max 1 sekundu na výsledek:
const data = await this.cache.getOrSet(
this.cache.buildKey(CACHE_GROUP.REGIONS, 'all'),
CACHE_TTL.STATIC,
() => this.regionsService.findAll(),
);BullMQ fronty
Redis slouží jako backend pro BullMQ job queue systém:
| Fronta | Účel | Retry |
|---|---|---|
email | Odesílání emailů přes Resend | 3x, exponential backoff |
notifications | In-app notifikace + cleanup | 3x, exponential backoff |
course-generation | Automatické generování kurzů | 1x (idempotentní) |
replacement | Automatická náhrada instruktorů | 1x |
course-daily-scan | Denní sken návrhů kurzů | 1x |
sms-reminders | SMS připomínky kurzů | Repeatable, denně 9:00 |
Plánované úlohy
| Úloha | Cron | Fronta |
|---|---|---|
| SMS připomínky | 0 9 * * * (denně 9:00) | sms-reminders |
| Cleanup notifikací | 0 3 * * 0 (neděle 3:00) | notifications |
| Kontrola náhrad | */15 * * * * (každých 15 min) | replacement |
SMS připomínky se automaticky plánují při startu API, ale pouze pokud je TWILIO_ENABLED=true.
Správa Redis
Kontrola stavu
# Ping test
ssh deploy@<VPS_IP> "cd /opt/apps/turtor && docker compose exec redis redis-cli ping"
# PONG
# Informace o paměti
ssh deploy@<VPS_IP> "cd /opt/apps/turtor && docker compose exec redis redis-cli info memory"
# Počet klíčů
ssh deploy@<VPS_IP> "cd /opt/apps/turtor && docker compose exec redis redis-cli dbsize"Promazání cache (bez ovlivnění front)
# Smazání všech cache klíčů (prefix "cache:")
ssh deploy@<VPS_IP> "cd /opt/apps/turtor && \
docker compose exec redis sh -c \"redis-cli --scan --pattern 'cache:*' | xargs -r redis-cli del\""Příkaz FLUSHALL smaže vše včetně BullMQ front a naplánovaných úloh. Používejte cílené mazání podle prefixu.
Troubleshooting
| Příznak | Příčina | Řešení |
|---|---|---|
| Joby se nespouštějí | Redis nedostupný | Kontrola docker compose ps redis |
| Staré cache hodnoty | Chybí invalidační event | Manuální promazání cache skupiny |
| Redis OOM | Plná paměť | Nastavení maxmemory a maxmemory-policy |
| AOF rewrite chyba | Nedostatek disku | docker system df, úklid starých obrazů |