Caching Strategies with Redis
Caching is the most impactful optimization in web applications. The right pattern depends on read/write ratio, consistency requirements, and freshness needs.
import redis, json
r = redis.Redis(decode_responses=True)
def get_post(post_id: int) -> dict:
key = f"post:{post_id}"
cached = r.get(key)
if cached: return json.loads(cached)
post = db.query('SELECT * FROM posts WHERE id=?', [post_id])
if post:
r.setex(key, 3600, json.dumps(post))
return post
def update_post(post_id: int, data: dict):
db.update('posts', data, {'id': post_id})
r.delete(f"post:{post_id}") # invalidate cache
Advanced Redis Patterns
# Rate limiting
def is_limited(user_id, limit=100, window=60):
key = f"rl:{user_id}"
count = r.incr(key)
if count == 1: r.expire(key, window)
return count > limit
# Leaderboard with sorted set
r.zadd('scores', {'Rahul': 950, 'Priya': 1200, 'Amit': 880})
top = r.zrevrange('scores', 0, 9, withscores=True)
# Distributed lock
import uuid
def acquire_lock(resource, ttl=30):
lock_id = str(uuid.uuid4())
acquired = r.set(f"lock:{resource}", lock_id, nx=True, ex=ttl)
return lock_id if acquired else None
Q: What is a cache stampede?
When a popular key expires, thousands of requests simultaneously hit the database to regenerate it. Prevention: mutex lock (first request locks, others wait), probabilistic early expiration (randomly regenerate before expiry), or background refresh (never let hot keys expire under load).
Comments (0)
No comments yet. Be the first!
Leave a Comment