Thiết kế hệ thống Đếm Lượt Xem (View Counter) chính xác cho video YouTube không làm nghẽn DB
Thử thách: 100.000 người cùng xem một video mỗi giây Khi một MV ca nhạc mới của một ca sĩ nổi tiếng ra mắt, lượt xem có thể tăng hàng trăm ngàn lượt mỗi giây. Nếu bạn xử lý theo cách ngây thơ: Hàng c…
☰ Mục lục bài viết (5 phần) Mở / Đóng mục lục
Thử thách: 100.000 người cùng xem một video mỗi giây#
Khi một MV ca nhạc mới của một ca sĩ nổi tiếng ra mắt, lượt xem có thể tăng hàng trăm ngàn lượt mỗi giây.
Nếu bạn xử lý theo cách ngây thơ:
-- CÁCH NÀY SẼ LÀM SẬP DATABASE TRONG 3 GIÂY:
UPDATE videos SET view_count = view_count + 1 WHERE id = 'mv_hot_2026';
Hàng chục ngàn câu lệnh UPDATE cùng tranh chấp khóa hàng (row-level lock) trên cùng một dòng trong bảng, khiến CPU database chạm 100% và treo toàn bộ hệ thống.
Làm thế nào để các nền tảng như YouTube hay TikTok đếm lượt xem mượt mà?
Kiến trúc 3 tầng: Bộ đệm phân tán và Gom lô (Batching)#
Người dùng xem video
│
▼
[ Ingestion API (Go) ] ──> Đẩy event vào Kafka
│
▼
[ Redis Sharded Counters ] (Bộ đệm đếm siêu tốc in-memory)
│ (Tăng lượt xem bằng INCR, cực nhanh 0.1ms)
▼
[ Aggregator Worker ] (Chạy định kỳ mỗi 10 giây)
│ (Gom 50.000 lượt view thành 1 câu SQL duy nhất)
▼
Database PostgreSQL (Ghi nhẹ nhàng, không nghẽn lock)
Kỹ thuật Sharded Counter trong Redis#
Nếu một video quá hot, ngay cả một key duy nhất trong Redis cũng có thể bị nghẽn CPU lõi đơn (Hot Key issue). Giải pháp là chia key thành $N$ mảnh nhỏ:
// Chia ngẫu nhiên thành 10 sub-counters
const shardIndex = Math.floor(Math.random() * 10);
const redisKey = `video:views:${videoId}:shard_${shardIndex}`;
await redis.incr(redisKey);
Khi cần lấy tổng lượt view hiển thị: Chỉ cần đọc giá trị của 10 shard và cộng lại.
Chống gian lận (Anti-fraud View Validation)#
Lượt view chỉ được tính hợp lệ khi:
- Người dùng xem video tối thiểu 30 giây.
- Mỗi địa chỉ IP / User ID chỉ được tính tối đa $X$ view trong 1 giờ (dùng Redis HyperLogLog để đếm số lượng người xem duy nhất - Unique Viewers).
Góc thảo luận#
Hệ thống của bạn có tính năng đếm lượt xem bài viết hoặc đếm lượt click không? Bạn đang ghi trực tiếp vào DB hay gom lô qua Redis?
Xem thêm nội dung liên quan:
Thảo luận
1 phản hồi
Tham gia thảo luận
Bài liên quan trong #Backend & Microservices
-
Áp dụng Model Context Protocol (MCP) của Anthropic để kết nối AI với Postgres và Docker
Hoàng Nam (Tech Lead) · 💬 1 -
So sánh mô hình Embedding đa ngữ: OpenAI text-embedding-3 vs BGE-M3 vs Cohere
Minh Trí (AI Engineer) · 💬 1 -
Xây dựng Voice AI Agent thời gian thực với WebRTC và Whisper Live: Độ trễ dưới 500ms
Lan Anh (Senior Frontend) · 💬 1 -
Cấu hình Rate Limiting ở tầng Nginx và API Gateway: Chống DDOS Layer 7 hiệu quả
Đức Huy (DevOps Specialist) · 💬 1 -
Tokenization tiếng Việt của các LLM: Tại sao chi phí tiếng Việt đắt gấp 3 lần tiếng Anh?
Minh Trí (AI Engineer) · 💬 1