Tag: caching, performance, redis, memcached, system-design
Livello: intermedio
TL;DR: Strategie per migliorare le performance di sistema riducendo il carico sui database tramite la memorizzazione temporanea. Copre pattern di accesso, policy di invalidazione e ottimizzazioni.
Cache Hit / Miss: Hit quando il dato è in cache, Miss quando deve essere recuperato dalla fonte originale (es. DB).
TTL (Time to Live): Finestra temporale di validità del dato in cache prima della sua invalidazione automatica.
Cache-Aside (Lazy Loading): L'applicazione interroga la cache. Se miss, legge dal DB e aggiorna la cache.
Write-Through: I dati vengono scritti in modo sincrono sia in cache che nel database. Alta consistenza, maggiore latenza.
Write-Behind (Write-Back): Scrittura immediata in cache e differita in modo asincrono sul database. Altissime performance, rischio perdita dati.
Read-Through: L'applicazione legge solo dalla cache; è il layer di cache a occuparsi del fetch dal DB in caso di miss.
CDN (Content Delivery Network): Rete distribuita di server cache per servire asset statici vicino all'utente.
Eviction Policies: Strategie di rimozione quando la memoria scarseggia (LRU, LFU, FIFO).
Cache Stampede: Effetto valanga sul DB quando una chiave molto richiesta scade e mille client tentano di ricrearla simultaneamente.
Q: Quali sono le differenze tra Redis e Memcached?
R: Scelgo Redis per strutture dati avanzate, persistenza su disco e pub/sub. Uso Memcached per un key-value store puramente in memoria, semplice e multithread.
Q: Come previeni una Cache Stampede (Thundering Herd)?
R: Aggiungo un "jitter" (valore casuale) al TTL per evitare scadenze simultanee di dati in batch, oppure implemento un lock distribuito in modo che solo un thread aggiorni la cache.
Q: Quando preferiresti il pattern Write-Behind?
R: Lo uso in scenari con un volume massivo di scritture dove la latenza deve essere minima (es. contatori di views), accettando il rischio di perdere dati se il nodo cache va in crash prima del sync.
Stale Data: Configurare TTL troppo lunghi in sistemi dinamici, mostrando agli utenti informazioni non più allineate con il database.
Hot Keys: Una singola chiave viene richiesta con frequenza tale da saturare CPU e larghezza di banda del singolo shard/nodo che la ospita.
Mancanza di Jitter nei TTL: Inserire elementi in batch con lo stesso TTL esatto, causando un picco anomalo di cache miss (e sovraccarico DB) quando scadranno tutti insieme.
// Pattern Cache-Aside con Jitter per evitare Stampede
async function getUserData(userId: string) {
const key = `user:${userId}`;
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const data = await database.users.findById(userId);
// TTL base 1 ora + random jitter (0-5 minuti)
const ttl = 3600 + Math.floor(Math.random() * 300);
await redis.setex(key, ttl, JSON.stringify(data));
return data;
}
[ ] Meccanismi di distributed locking con Redis (es. algoritmo Redlock).
[ ] Implementazione e differenze pratiche tra policy LRU e LFU.
Modifica direttamente o con Gemini Fai clic in un punto qualsiasi per digitare e modificare direttamente oppure seleziona il testo per chiedere a Gemini di apportare modifiche.
Ho generato il file Markdown pronto per essere importato nel sistema di Jarvis Interviews. Rispetta rigorosamente i limiti di lunghezza, il formato dei tag e l'assenza di riferimenti esterni indesiderati.