Câu hỏi này đã cũ và câu trả lời thường là "Redis, vì nó làm được nhiều hơn". Bài này đo cả hai trên đúng cùng một bài toán bộ đệm.
Cùng bài toán khoá–giá trị 100 byte
| Redis | Memcached | |
|---|---|---|
SET, không đường ống |
20.136/s | 20.854/s |
GET, không đường ống |
20.894/s | 20.970/s |
SET, đường ống 100 |
376.063/s | 388.538/s |
GET, đường ống 100 |
608.120/s | 944.119/s |
| Bộ nhớ 100.000 khoá | 40,37 MB | 15,82 MB |
| CPU khi 4 khách song song | 73,94% | 100,16% |
Không đường ống, hai hệ thống bằng nhau — 20.000 ops/s cho cả hai. Đúng như đo ở phần 2: nút thắt là lượt đi về, không phải máy chủ.
Có đường ống, Memcached GET nhanh hơn 55%.
Vì sao Memcached nhanh hơn khi đẩy mạnh
Dòng CPU nói rõ: Redis dùng 73,94% — tức chưa hết một nhân, và nó không thể vượt 100% vì xử lý lệnh chỉ có một luồng. Memcached dùng 100,16%, tức nó đang dùng nhiều hơn một nhân.
Memcached đa luồng thật sự: -t 4 cho bốn luồng worker, mỗi luồng xử lý lệnh độc lập. Với máy nhiều nhân và tải cao, đó là lợi thế kiến trúc mà Redis không có.
Redis chọn một luồng để đổi lấy tính nguyên tử miễn phí và mã đơn giản. Với phần lớn hệ thống — dưới 100.000 ops/s — lựa chọn đó không tốn gì. Trên ngưỡng đó, nó là trần cứng, và cách vượt duy nhất là Cluster (phần 23).
Và tốn ít bộ nhớ hơn 61%
Redis 40,37 MB
Memcached 15,82 MB
Cho cùng 100.000 khoá × 100 byte.
Lý do đã đo ở phần 3: Redis tốn khoảng 64 byte phụ trội mỗi khoá cho robj, dictEntry, tiêu đề chuỗi và bộ cấp phát. Memcached dùng bộ cấp phát slab đơn giản hơn và không có lớp đối tượng đa kiểu — nó chỉ biết chuỗi.
Với bộ đệm hàng chục triệu khoá nhỏ, chênh lệch 2,6 lần là tiền thật.
Nhưng Memcached đổi lấy điều đó bằng gì
khởi động lại -> curr_items 0
SET giá trị 2 MB -> SERVER_ERROR object too large for cache
SET giá trị 900 KB -> STORED
Không có lưu trữ. Khởi động lại là mất sạch, không có RDB, không có AOF. Với bộ đệm thuần thì không sao — nhưng nó nghĩa là mỗi lần triển khai là một lần bão cache (phần 27).
Trần 1 MB mỗi giá trị (chỉnh được bằng -I, nhưng mặc định là vậy). Redis cho tới 512 MB.
Và danh sách những gì hoàn toàn không có:
- Kiểu dữ liệu: List, Set, Sorted Set, Hash, Stream, Bitmap, HyperLogLog
- Pub/Sub, Lua, giao dịch
- Sao chép, chuyển đổi tự động
- Lệnh chặn như
BLPOP - TTL đọc lại được (
TTLtrả về thời gian còn lại)
Mỗi mục trong danh sách này là một phần của sê-ri này. Nếu bạn dùng bất kỳ cái nào, câu hỏi đã có câu trả lời.
Chọn thế nào
Memcached khi: bộ đệm thuần khoá–giá trị, dữ liệu dựng lại được, tải rất cao trên máy nhiều nhân, và bạn muốn ít thứ để hỏng nhất có thể.
Redis khi: cần bất kỳ thứ gì trong danh sách ở trên — và với phần lớn ứng dụng, bạn sẽ cần ít nhất một.
Điều đáng nói: hai hệ thống này không cạnh tranh nhau như người ta tưởng. Memcached làm đúng một việc và làm rất tốt. Redis làm nhiều việc, mỗi việc tốt vừa đủ, và giá trị của nó nằm ở chỗ bạn không phải chạy năm hệ thống.
Một góc nhìn thực dụng
Nếu đang chọn mới: bắt đầu bằng Redis. Không phải vì nó nhanh hơn — đo được là không — mà vì xác suất bạn cần thêm một kiểu dữ liệu, một hàng đợi, hoặc một khoá phân tán trong sáu tháng tới là rất cao, và lúc đó việc thêm Memcached-thứ-hai tốn hơn nhiều.
Nếu đang chạy Memcached và nó ổn: đừng đổi. Chênh lệch hiệu năng nghiêng về phía nó, và việc di chuyển một bộ đệm đang chạy tốt không mang lại gì.
Nếu đang chạy Redis chỉ để làm bộ đệm khoá–giá trị và bộ nhớ là vấn đề: 61% là con số đáng cân nhắc. Nhưng hãy đo trên dữ liệu thật trước — con số đó phụ thuộc kích thước giá trị, và với giá trị lớn phụ trội của Redis trở nên không đáng kể.
Thử ba mươi giây
Xem bạn có đang dùng gì ngoài khoá–giá trị không:
redis-cli info commandstats | sed 's/cmdstat_//' | cut -d: -f1 | \
grep -vE '^(get|set|del|exists|expire|ttl|mget|mset|ping|info|config|client|command)$' | sort
Danh sách in ra là những lệnh Memcached không có. Trống nghĩa là bạn đang dùng Redis như một Memcached đắt hơn 2,6 lần về bộ nhớ.
Và kiểm kiểu dữ liệu đang lưu:
redis-cli --scan --count 500 | head -2000 | while read k; do redis-cli type "$k"; done | sort | uniq -c
Chỉ toàn string thì cùng kết luận. Có hash, zset, stream thì câu hỏi đã được trả lời.
Phần sau: danh sách kiểm trước khi đưa Redis lên chạy thật.