Understanding Cache Avalanche
Cache avalanche refers to a scenario where a large number of cached items expire simultaneously or the cache service becomes unavailable, causing a sudden flood of requests to hit the underlying data base. This can lead to database overload, increased latency, or complete service failure.
Common Causes
- Identical expiration times set for multiple cache entries
- Cache server downtime or network issues
- Unexpected traffic spikes overwhelming cache capacity
Prevention Tecnhiques
Randomized Expiration Times
Add random variations to cache expiration times to prevent simultaneous invalidation:
import random
base_expiry = 3600 # 1 hour base TTL
random_offset = random.randint(0, 300) # 0 to 5 minutes variation
total_ttl = base_expiry + random_offset
cache_client.set("item_key", "cached_value", expire=total_ttl)
High Availability Setup
Implement Redis Cluster or Sentinel for automatic failover and data replication to avoid single points of failure.
Layered Caching Approach
Combine local in-memory cache with distributed Redis cache:
def get_cached_data(key):
# Check local cache first
local_value = local_cache.get(key)
if local_value:
return local_value
# Fall back to Redis
redis_value = redis_client.get(key)
if redis_value:
local_cache.set(key, redis_value, ttl=60) # Short local TTL
return redis_value
# Acquire lock to prevent cache stampede
lock_acquired = redis_client.set("lock:" + key, "1", nx=True, ex=10)
if lock_acquired:
try:
db_data = fetch_from_database(key)
redis_client.set(key, db_data, ex=3600)
local_cache.set(key, db_data, ttl=60)
return db_data
finally:
redis_client.delete("lock:" + key)
else:
time.sleep(0.1)
return get_cached_data(key) # Retry after delay
Rate Limiting and Fallbacks
Implement request throttling and graceful degradation when database pressure increases:
from circuitbreaker import circuit
@circuit(failure_threshold=5, recovery_timeout=30)
def protected_db_query(key):
return database.fetch(key)
def get_data_with_fallback(key):
try:
return protected_db_query(key)
except CircuitBreakerError:
return get_default_data(key) # Return cached or static data
Cache Preloading
Pre-populate cache with frequently accessed data during off-peak hours or before expected traffic surges.
Monitoring and Maintenance
Regularly monitor cache hit rates, expiration patterns, and data base load. Implement alerts for unusual cache behavior and conduct periodic failure simulations to validate recovery procedures.