Bạn dùng Redis. Tại sao không dùng Memcached?
So sánh Redis vs Memcached: data structures, persistence, clustering, licensing — và khi nào Memcached thực sự là lựa chọn đúng.
Bạn dùng Redis. Tại sao không dùng Memcached?
Câu hỏi
Bạn đang dùng Redis làm cache. Tại sao không dùng Memcached?
Dành cho level
Interviewer expect bạn biết sự khác biệt kỹ thuật cơ bản: data structures, persistence, clustering. Trả lời được "Redis có gì Memcached không có" là đủ.
Điểm cộng: biết nêu use case cụ thể tại sao dự án mình cần Redis (session, rate limiting, sorted set leaderboard…).
Cốt lõi cần nhớ
Redis là một in-memory data structure store — không chỉ là cache. Memcached chỉ là cache thuần túy (key-string), còn Redis hỗ trợ List, Set, Sorted Set, Hash, Stream, HyperLogLog — giúp implement nhiều pattern phức tạp ngay trên cache layer.
Persistence và High Availability là lý do production quan trọng nhất. Redis có RDB + AOF để survive restart; có native replication và Redis Cluster. Memcached mất toàn bộ data khi restart và không có clustering native — phải dùng proxy ngoài (Twemproxy, mcrouter).
Câu trả lời trung thực hơn là: "Redis thắng 90% use case, nhưng Memcached vẫn có chỗ của nó." Memcached đơn giản hơn, multi-threaded native, và tốt hơn cho pure-string caching throughput cực cao. Biết khi nào Memcached phù hợp sẽ khiến interviewer ấn tượng hơn.
Câu trả lời mẫu
"Chúng tôi chọn Redis vì project không chỉ cần cache string đơn thuần — chúng tôi dùng Sorted Set để implement rate limiting theo user ID, dùng Hash để lưu session object, và dùng Pub/Sub để broadcast invalidation event giữa các service. Những thứ đó làm được ngay trong Redis mà không cần thêm dependency. Nếu chỉ cần cache thuần — ví dụ cache HTML fragment hoặc API response là string — Memcached thực ra nhẹ hơn và multi-threaded native nên throughput raw có thể cao hơn trên cùng hardware. Nhưng với use case của chúng tôi, việc chỉ dùng một tool làm được nhiều thứ giảm complexity ops đáng kể. Một điểm nữa về long-term: năm 2024 Redis đổi license sang RSALv2+SSPLv1, Linux Foundation fork ra Valkey — AWS ElastiCache hiện default sang Valkey rồi. Chúng tôi đang theo dõi sát, nhưng Valkey vẫn drop-in compatible nên migration nếu cần cũng không phức tạp."
Phân tích chi tiết
So sánh tổng quan
| Tiêu chí | Redis | Memcached |
|---|---|---|
| Data structures | String, List, Set, Sorted Set, Hash, Stream, HyperLogLog, Geo | String only |
| Persistence | RDB snapshots + AOF | Không — mất khi restart |
| Replication | Native master-replica | Không native |
| Clustering | Redis Cluster (native) | Cần proxy ngoài (Twemproxy, mcrouter) |
| Threading model | Single-threaded commands (multi-threaded I/O từ Redis 6) | Multi-threaded |
| Pub/Sub | Có | Không |
| Transactions | MULTI/EXEC | Không |
| Lua scripting | Có | Không |
| Max value size | 512 MB | 1 MB |
| License (2024+) | RSALv2 + SSPLv1 (không OSS) | BSD (OSS) |
| AWS managed | ElastiCache for Redis / Valkey (default mới) | ElastiCache for Memcached |
Tại sao Redis thắng phần lớn use case production
Use case 1 — Rate Limiting với Sorted Set
Làm điều này với Memcached: không thể — không có Sorted Set, phải dùng thêm DB hoặc implement distributed counter phức tạp.
Use case 2 — Session Storage với Hash
Với Memcached: phải serialize toàn bộ Java object → lưu string → đọc ra → deserialize → modify → serialize lại → ghi. Tốn CPU và network bandwidth hơn.
Use case 3 — Cache Invalidation Broadcast qua Pub/Sub
Memcached không có Pub/Sub — phải dùng message broker riêng (Kafka, SNS) cho pattern này.
Persistence — lý do quan trọng nhất trong production
Khi nào Memcached vẫn là lựa chọn đúng
Đây là điểm phân biệt Senior vs Mid: biết khi nào không dùng Redis mới là engineer tốt.
| Scenario | Tại sao Memcached phù hợp hơn |
|---|---|
| Cache HTML fragment / API response thuần string | Memcached multi-threaded native → throughput cao hơn cùng CPU |
| Cần scale horizontal đơn giản nhất | Memcached scale-out dễ hơn (client-side sharding đủ dùng) |
| Không cần persistence, không cần data structures phức tạp | Memcached ít ops overhead hơn — ít thứ phải tune |
| Stack đã có Memcached, team quen vận hành | Migration cost không justify nếu use case đơn giản |
| Compliance yêu cầu fully OSS license | Memcached là BSD — Redis 7.4+ không còn là OSS |
Licensing thay đổi 2024 — điểm quan trọng không nên bỏ qua
Nếu dùng Redis 7.4+ trên self-hosted, cần review license với legal team trước khi production. Valkey là lựa chọn an toàn hơn nếu cần fully OSS.
Architecture pattern: Two-Level Caching
Pattern thực tế tại các công ty lớn: dùng local cache (Caffeine) + Redis thay vì chỉ dùng Redis.
Memcached không hỗ trợ Pub/Sub → không thể broadcast L1 invalidation hiệu quả khi data thay đổi.
Bẫy thường gặp
❌ "Redis nhanh hơn Memcached"
→ Tại sao sai: Không đúng cho mọi trường hợp. Với pure string throughput, Memcached multi-threaded native có thể nhanh hơn Redis trên workload cực cao vì Redis xử lý commands single-threaded (dù I/O đã multi-thread từ Redis 6).
✅ Đúng hơn: "Redis và Memcached đều sub-millisecond cho most use cases. Redis thắng về feature richness và flexibility, không nhất thiết về raw throughput."
❌ "Memcached không dùng được nữa vì Redis tốt hơn"
→ Tại sao sai: Memcached vẫn được dùng tại Facebook (mcrouter), Slack, và các hệ thống cần simple string cache throughput cực cao. Stack đơn giản là lợi thế khi ops resources hạn chế.
✅ Đúng hơn: "Redis là lựa chọn mặc định tốt hơn cho phần lớn use case, nhưng Memcached vẫn có chỗ đứng trong các workload pure caching string với throughput yêu cầu cực cao và không cần features nâng cao."
❌ "Redis là open source nên không cần lo license"
→ Tại sao sai: Từ tháng 3/2024, Redis 7.4+ dùng RSALv2+SSPLv1 — không còn là OSS theo định nghĩa của Open Source Initiative. Dùng Redis trong commercial product cần review legal.
✅ Đúng hơn: Nếu cần fully OSS, dùng Valkey (fork của Redis, license BSD, do Linux Foundation quản lý). AWS ElastiCache đã default sang Valkey.
❌ "Thêm Redis là xong, không cần nghĩ gì thêm"
→ Tại sao sai: Redis cần được tune: maxmemory, maxmemory-policy, connection pool size, serialization format. Không tune → eviction storm, connection exhaustion, hoặc high latency khi serializing large objects.
✅ Đúng hơn: Sau khi chọn Redis, cần define rõ: max memory, eviction policy (allkeys-lru vs volatile-lru), TTL strategy (jitter để tránh thundering herd), và monitoring (keyspace hits/misses ratio).
Câu hỏi follow-up
1. Khi nào bạn dùng allkeys-lru vs volatile-lru?
volatile-lru chỉ evict key có TTL — an toàn hơn vì key không có TTL (session dài hạn) không bị xóa. Nhưng nếu tất cả key đều có TTL, hai policy này tương đương. allkeys-lru phù hợp khi Redis là pure cache (tất cả data có thể regenerate từ DB). noeviction (default) — Redis trả error khi đầy — không nên dùng trong production cache.
2. Redis Cluster vs Redis Sentinel khác gì?
Sentinel: High Availability cho single-shard Redis — tự động failover master → replica, nhưng data vẫn trên 1 node. Cluster: Sharding + HA — data phân tán trên nhiều node (16384 hash slots), mỗi shard có replica riêng. Cluster phù hợp khi dataset lớn hơn RAM của 1 node. Sentinel đủ dùng khi dataset nhỏ và chỉ cần HA.
3. Valkey có thật sự drop-in replacement cho Redis không?
Valkey fork từ Redis 7.2.4 — API, commands, protocol hoàn toàn tương thích. Application code không cần thay đổi. Chỉ cần đổi connection string endpoint. AWS ElastiCache và Google Cloud Memorystore đã hỗ trợ. Rủi ro migration rất thấp.
4. Làm sao tránh cache stampede (thundering herd) khi nhiều key expire cùng lúc?
Dùng TTL jitter — thêm random offset vào TTL: TTL = baseTTL + random(0, baseTTL * 0.1). Và dùng probabilistic early expiration — trước khi key thật sự expire, xác suất cao refresh sớm để 1 request đủ làm ấm cache trước khi request khác bị miss.
Xem thêm
- 2h sáng — Server production sập, 10,000 users online — Scenario 4 trong câu đó là Redis Eviction Storm, liên quan trực tiếp đến caching strategy.