Scale · 05 · Osservabilità
Un’istanza che non sai osservare non è in produzione, è in speranza. Questa unità costruisce la catena diagnostica completa.
Prerequisito: istanza di lab su 6379 avviata con --enable-debug-command yes.
Esercizio 5.1 — INFO come fonte primaria
Sezione intitolata “Esercizio 5.1 — INFO come fonte primaria”redis-cli INFO server | grep -E 'redis_version|uptime_in_days|config_file'redis-cli INFO clients | grep -E 'connected_clients|blocked_clients|maxclients'redis-cli INFO memory | grep -E 'used_memory_human|used_memory_rss_human|maxmemory_human|mem_fragmentation_ratio'redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|aof_last_write_status|loading'redis-cli INFO stats | grep -E 'instantaneous_ops_per_sec|keyspace_hits|keyspace_misses|evicted_keys|expired_keys|rejected_connections|latest_fork_usec'redis-cli INFO replication | grep -E 'role|connected_slaves|master_link_status'Hit ratio calcolato al volo:
redis-cli INFO stats | awk -F: '/keyspace_hits/{h=$2} /keyspace_misses/{m=$2} END{printf "hit ratio: %.2f%%\n", h/(h+m)*100}'Verifica: su una cache un hit ratio sotto il 70–80% significa che il dataset non ci sta in memoria o che il TTL è troppo aggressivo. Su un data store, l’hit ratio non è una metrica significativa: sapere quale dei due casi hai davanti è il prerequisito di ogni allerta.
Esercizio 5.2 — SLOWLOG
Sezione intitolata “Esercizio 5.2 — SLOWLOG”redis-cli CONFIG GET slowlog-log-slower-than slowlog-max-lenredis-cli CONFIG SET slowlog-log-slower-than 1000 # µs, quindi 1 msredis-cli SLOWLOG RESETredis-cli DEBUG SLEEP 0.1redis-cli SLOWLOG GET 1redis-cli SLOWLOG LENOutput misurato:
1 # id1785845406 # timestamp100196 # durata in microsecondiDEBUG SLEEP 0.1 # comando127.0.0.1:60992 # clientVerifica: la soglia è in microsecondi, non millisecondi — l’errore più comune è impostare 10000 credendo di dire 10 s quando si stanno dicendo 10 ms. Lo slowlog vive in memoria e si perde al restart: se ti serve storico, scrapalo.
Comandi da cercare in uno slowlog reale: KEYS, FLUSHALL, SMEMBERS su set
enormi, HGETALL su hash da milioni di campi, script Lua lunghi.
Esercizio 5.3 — LATENCY monitor
Sezione intitolata “Esercizio 5.3 — LATENCY monitor”redis-cli CONFIG GET latency-monitor-thresholdredis-cli CONFIG SET latency-monitor-threshold 100 # msredis-cli LATENCY RESETredis-cli DEBUG SLEEP 0.3redis-cli LATENCY LATESTredis-cli LATENCY HISTORY commandredis-cli LATENCY DOCTOROutput misurato:
command 1785845406 300 3001. command: 1 latency spikes (average 300ms, mean deviation 0ms, period 1.00 sec). Worst all time event 300ms.Verifica: il monitor è disattivato di default
(latency-monitor-threshold 0) — se non lo abiliti, LATENCY LATEST restituisce
sempre vuoto e ti convinci che non ci siano spike. Attivarlo a 100 ms su tutta
la flotta è a costo trascurabile e ti dà l’evento quando serve.
Gli eventi che vedrai in produzione: command, fork, aof-fsync-always,
expire-cycle, eviction-del. Ognuno punta a una causa diversa.
Esercizio 5.4 — Memoria e chiavi patologiche
Sezione intitolata “Esercizio 5.4 — Memoria e chiavi patologiche”redis-cli INFO memory | grep -E 'used_memory_human|used_memory_rss_human|used_memory_peak_human|mem_fragmentation_ratio|mem_allocator'redis-cli MEMORY DOCTORredis-cli MEMORY STATS | head -20redis-cli MEMORY USAGE <chiave>Scansione delle chiavi grandi — safe in produzione, usa SCAN non KEYS:
redis-cli --bigkeysredis-cli --memkeys # ordina per memoria occupataredis-cli --hotkeys # richiede maxmemory-policy allkeys-lfuVerifica:
mem_fragmentation_ratio> 1.5 → frammentazione; valutaactivedefrag yes.mem_fragmentation_ratio< 1.0 → il processo sta swappando: è un’emergenza, non un tuning.used_memory_rssmolto sopraused_memorycon ratio alto emaxmemoryvicino → il prossimoBGSAVEpuò innescare l’OOM killer.
Eviction:
redis-cli CONFIG GET maxmemory maxmemory-policyredis-cli INFO stats | grep -E 'evicted_keys|expired_keys'maxmemory 0 (default) su un’istanza usata come cache significa: nessun limite,
crescita fino all’OOM del kernel. Su ogni istanza cache va impostato
maxmemory (tipicamente 60–70% della RAM del nodo, per lasciare spazio al fork)
più una policy allkeys-lru o allkeys-lfu.
Esercizio 5.5 — Monitoraggio live
Sezione intitolata “Esercizio 5.5 — Monitoraggio live”redis-cli --stat # una riga al secondo: keys, mem, clients, opsredis-cli --latency-history # serie di latenza nel temporedis-cli --latency-dist # distribuzione (spettro)redis-cli MONITOR # ogni comando, in tempo realeEsercizio 5.6 — Esporre le metriche a Prometheus
Sezione intitolata “Esercizio 5.6 — Esporre le metriche a Prometheus”# redis_exporter, binario singolo, nessuna dipendenzaREDIS_ADDR=redis://127.0.0.1:6379 ./redis_exporter --web.listen-address=:9121 &curl -s localhost:9121/metrics | grep -E '^redis_(up|connected_clients|memory_used_bytes|commands_processed_total|rejected_connections_total)'Regole di allerta minime, in ordine di priorità:
| Allerta | Espressione | Perché |
|---|---|---|
| Istanza giù | redis_up == 0 | ovvio, ma va scritta |
| Replica rotta | redis_master_link_up == 0 | HA compromessa in silenzio |
| Connessioni rifiutate | rate(redis_rejected_connections_total[5m]) > 0 | saturazione maxclients |
| Memoria | redis_memory_used_bytes / redis_memory_max_bytes > 0.85 | eviction imminente |
| Swap | redis_mem_fragmentation_ratio < 1 | il processo sta swappando |
| Persistenza | redis_rdb_last_bgsave_status == 0 | backup non funzionante |
| Fork lento | redis_latest_fork_usec > 500000 | spike di latenza da snapshot |
Verifica: l’allerta che manca quasi sempre è master_link_up. Una replica
scollegata non genera errori applicativi: te ne accorgi al failover, quando è
tardi.
Esercizio 5.7 — La catena diagnostica completa
Sezione intitolata “Esercizio 5.7 — La catena diagnostica completa”Da eseguire in ordine quando arriva “Redis è lento”:
redis-cli PING # 1. risponde?redis-cli --intrinsic-latency 5 # 2. è l'host?redis-cli --latency # 3. è la rete?redis-cli SLOWLOG GET 10 # 4. sono i comandi?redis-cli LATENCY LATEST # 5. sono gli eventi interni?redis-cli INFO memory | grep fragmentation # 6. è la memoria/swap?redis-cli INFO stats | grep -E 'rejected|evicted' # 7. è la saturazione?redis-cli INFO replication | grep master_link # 8. è la replica?Otto comandi, otto ipotesi escluse o confermate. Questa sequenza è il contenuto del runbook di primo livello.
Domande di verifica
Sezione intitolata “Domande di verifica”LATENCY LATESTè vuoto su un’istanza con spike evidenti. Perché?mem_fragmentation_ratioè 0.7. Cosa fai per primo?slowlog-log-slower-than 10000: quale soglia hai impostato davvero?- Quale singola allerta rileva un’HA rotta prima del failover?
Prossimo passo: 06 · Memoria e tuning.