ducdev
Database / Bài viết

Redis — Cache, Session Và Pub/Sub Trong Một Công Cụ

Redis là in-memory data store nhanh nhất thế giới — nhưng không chỉ là cache. Khám phá cách dùng Redis cho session management, pub/sub messaging và rate limiting.

a
admin
10/06/2026 · 2 phút đọc · 1 lượt xem
Chia sẻ

Redis thường được giới thiệu là "cache server" nhưng đó chỉ là bề nổi. Với hơn 10 data structure khác nhau và tốc độ đọc/ghi hàng triệu operations/giây, Redis giải quyết được nhiều bài toán mà SQL database không phù hợp.

Redis Data Structures

  • String: Cache, counter, session token
  • Hash: User profile, object cache
  • List: Message queue, activity feed
  • Set: Unique visitors, tags
  • Sorted Set: Leaderboard, rate limiting
  • Stream: Event log (như Kafka mini)

Caching Pattern Cơ Bản

import redis
import json
from functools import wraps

r = redis.Redis(host='localhost', port=6379, db=0)

def cache(ttl=300):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = f"{func.__name__}:{args}:{kwargs}"
            cached = r.get(key)
            if cached:
                return json.loads(cached)
            result = func(*args, **kwargs)
            r.setex(key, ttl, json.dumps(result))
            return result
        return wrapper
    return decorator

@cache(ttl=600)
def get_popular_posts():
    return list(Post.objects.order_by('-views')[:10].values()))

Django Với Redis Cache

# settings.py
CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
    }
}

# Trong view
from django.core.cache import cache

def homepage(request):
    posts = cache.get('homepage_posts')
    if not posts:
        posts = list(Post.objects.filter(status='published')[:6])
        cache.set('homepage_posts', posts, 300)
    return render(request, 'index.html', {'posts': posts})

Session Với Redis

# settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'

# Redis lưu session nhanh hơn DB, và tự expire theo SESSION_COOKIE_AGE

Rate Limiting Với Sorted Set

import time

def is_rate_limited(user_id: str, limit: int = 100, window: int = 3600) -> bool:
    key = f"rate:{user_id}"
    now = time.time()
    pipe = r.pipeline()
    # Xóa requests cũ ngoài window
    pipe.zremrangebyscore(key, 0, now - window)
    # Đếm requests trong window
    pipe.zcard(key)
    # Thêm request hiện tại
    pipe.zadd(key, {str(now): now})
    pipe.expire(key, window)
    _, count, *_ = pipe.execute()
    return count >= limit

Pub/Sub — Real-time Notifications

# Publisher
def publish_notification(user_id: int, message: str):
    r.publish(f'notifications:{user_id}', json.dumps({
        'message': message,
        'timestamp': time.time()
    }))

# Subscriber (chạy trong thread riêng)
def listen_notifications(user_id: int):
    pubsub = r.pubsub()
    pubsub.subscribe(f'notifications:{user_id}')
    for message in pubsub.listen():
        if message['type'] == 'message':
            data = json.loads(message['data'])
            print(f"Thông báo: {data['message']}")
Redis không phải là database chính — đừng lưu data quan trọng mà không có persistence. Dùng Redis cho những gì cần tốc độ và có thể tái tạo được: cache, session, queue.

Kết Luận

Redis là công cụ bổ trợ gần như bắt buộc cho bất kỳ web app nào muốn scale. Bắt đầu với caching đơn giản, sau đó khám phá session, rate limiting, và queue. Mỗi use case thêm vào sẽ giảm tải đáng kể cho PostgreSQL.

#Redis #Cache #database #backend #Python
a
Tác giả
admin

Lập trình viên, yêu thích chia sẻ kiến thức về công nghệ và phát triển phần mềm.

Bình luận

Chưa có bình luận. Hãy là người đầu tiên!

Để lại bình luận

Bình luận sẽ được duyệt trước khi hiển thị.