Học Redis: Hướng Dẫn Toàn Diện Cho Người Mới

Giới Thiệu
Redis (Remote Dictionary Server) là một hệ thống lưu trữ cấu trúc dữ liệu trong bộ nhớ mã nguồn mở, hoạt động như database, cache, message broker, và streaming engine. Đây là một trong những công cụ phổ biến nhất trong phát triển phần mềm hiện đại, hỗ trợ mọi thứ từ quản lý session đến phân tích real-time.
Trước khi đi sâu vào Redis caching với Spring Boot hay bất kỳ tích hợp framework nào khác, việc hiểu các kiến thức nền tảng của Redis là rất quan trọng. Hướng dẫn này sẽ cung cấp cho bạn một nền tảng vững chắc.
Những Gì Bạn Sẽ Học:
✅ Redis là gì và tại sao nó nhanh như vậy
✅ Các cấu trúc dữ liệu cốt lõi (Strings, Lists, Sets, Hashes, Sorted Sets)
✅ Các lệnh Redis thiết yếu
✅ Các tùy chọn persistence (RDB vs AOF)
✅ Pub/Sub messaging patterns
✅ Các use cases thực tế
✅ Best practices cho production
Yêu Cầu:
- Kiến thức cơ bản về command line
- Docker đã được cài đặt (để chạy Redis locally)
- Hiểu biết về khái niệm key-value
Tại Sao Chọn Redis?
Tốc Độ Quan Trọng
Redis lưu trữ toàn bộ dữ liệu trong bộ nhớ, đạt được:
- Độ trễ dưới millisecond cho hầu hết các operations
- 100.000+ operations mỗi giây trên phần cứng modest
- Hàng triệu ops/giây với cấu hình phù hợp
So sánh với các databases truyền thống:
| Operation | PostgreSQL | Redis |
|---|---|---|
| Simple Read | 1-10ms | 0.1-0.5ms |
| Simple Write | 5-20ms | 0.1-0.5ms |
| Complex Query | 10-100ms+ | N/A* |
*Redis không hỗ trợ complex queries - nó được tối ưu cho các operations đơn giản, nhanh.
Không Chỉ Là Cache
Mặc dù caching là use case phổ biến nhất của Redis, nó cực kỳ đa năng:
- Session Store: User sessions với automatic expiration
- Rate Limiter: Theo dõi API requests theo user/IP
- Leaderboards: Sorted sets cho rankings real-time
- Message Queue: Pub/Sub cho messaging real-time
- Real-time Analytics: Counters và HyperLogLog cho thống kê
- Geospatial: Location-based queries và radius searches
Bắt Đầu
Cài Đặt Redis với Docker
Cách dễ nhất để chạy Redis locally:
# Chạy Redis container
docker run -d \
--name redis-local \
-p 6379:6379 \
redis:7-alpine
# Kiểm tra đang chạy
docker ps | grep redis
# Kết nối đến Redis CLI
docker exec -it redis-local redis-cliBạn sẽ thấy Redis prompt:
127.0.0.1:6379>Những Commands Đầu Tiên
Hãy bắt đầu với các operations cơ bản:
# Set một key
SET greeting "Hello, Redis!"
# Get một key
GET greeting
# Trả về: "Hello, Redis!"
# Kiểm tra key có tồn tại không
EXISTS greeting
# Trả về: 1 (true)
# Xóa một key
DEL greeting
# Kiểm tra lại
EXISTS greeting
# Trả về: 0 (false)Các Cấu Trúc Dữ Liệu Cốt Lõi
Redis không chỉ là key-value store - nó hỗ trợ các cấu trúc dữ liệu phong phú cho phép các operations mạnh mẽ.
1. Strings
Kiểu dữ liệu đơn giản và đa năng nhất. Có thể lưu text, numbers, hoặc binary data lên đến 512MB.
# Basic string operations
SET user:1:name "John Doe"
GET user:1:name
# Set với expiration (giây)
SET session:abc123 "user_data" EX 3600 # Hết hạn sau 1 giờ
# Set chỉ khi key chưa tồn tại (hữu ích cho locks)
SETNX lock:resource "locked"
# Increment/Decrement (atomic operations)
SET counter 0
INCR counter # Trả về: 1
INCR counter # Trả về: 2
INCRBY counter 10 # Trả về: 12
DECR counter # Trả về: 11
# Multiple operations
MSET user:1:name "John" user:1:email "[email protected]"
MGET user:1:name user:1:emailUse Cases:
- Caching serialized objects
- Counters và statistics
- Rate limiting
- Distributed locks
2. Lists
Collections có thứ tự của strings. Hoàn hảo cho queues và recent items.
# Thêm items vào list
LPUSH notifications "New message" # Thêm vào trái (head)
RPUSH notifications "Friend request" # Thêm vào phải (tail)
# Lấy độ dài list
LLEN notifications
# Lấy items theo range (0-indexed, -1 nghĩa là cuối)
LRANGE notifications 0 -1 # Lấy tất cả items
LRANGE notifications 0 4 # Lấy 5 items đầu tiên
# Pop items (xóa và trả về)
LPOP notifications # Xóa từ trái
RPOP notifications # Xóa từ phải
# Blocking pop (chờ items)
BLPOP queue:jobs 30 # Chờ tối đa 30 giây để có itemUse Cases:
- Message queues (producer/consumer pattern)
- Recent activity feeds
- Undo/redo stacks
- Task queues
3. Sets
Collections không có thứ tự của các strings unique. Tuyệt vời cho membership testing và set operations.
# Thêm members vào set
SADD tags:post:1 "redis" "database" "caching"
# Kiểm tra membership
SISMEMBER tags:post:1 "redis" # Trả về: 1 (true)
SISMEMBER tags:post:1 "python" # Trả về: 0 (false)
# Lấy tất cả members
SMEMBERS tags:post:1
# Set operations
SADD tags:post:2 "redis" "spring" "java"
SINTER tags:post:1 tags:post:2 # Giao: ["redis"]
SUNION tags:post:1 tags:post:2 # Hợp: tất cả tags unique
SDIFF tags:post:1 tags:post:2 # Hiệu: tags trong post:1 nhưng không có trong post:2
# Random member
SRANDMEMBER tags:post:1
# Đếm members
SCARD tags:post:1Use Cases:
- Tags và categories
- Unique visitors tracking
- Friend lists và social connections
- Voting systems (ngăn chặn duplicate votes)
4. Hashes
Maps giữa string fields và values. Hoàn hảo cho objects.
# Set hash fields
HSET user:1 name "John Doe" email "[email protected]" age 30
# Get single field
HGET user:1 name
# Get multiple fields
HMGET user:1 name email
# Get tất cả fields và values
HGETALL user:1
# Increment numeric field
HINCRBY user:1 age 1 # Bây giờ là 31
# Kiểm tra field existence
HEXISTS user:1 email
# Lấy tất cả field names
HKEYS user:1
# Xóa field
HDEL user:1 ageUse Cases:
- User profiles và sessions
- Product details
- Configuration settings
- Object caching (tiết kiệm memory hơn JSON strings)
5. Sorted Sets
Giống sets, nhưng mỗi member có một score để sắp xếp. Cực kỳ mạnh mẽ cho rankings.
# Thêm members với scores
ZADD leaderboard 100 "player:1" 85 "player:2" 92 "player:3"
# Lấy rank (0-indexed, score thấp nhất trước)
ZRANK leaderboard "player:1" # Trả về vị trí
# Lấy reverse rank (score cao nhất trước)
ZREVRANK leaderboard "player:1"
# Lấy score
ZSCORE leaderboard "player:1"
# Lấy range theo rank (với scores)
ZRANGE leaderboard 0 2 WITHSCORES # Top 3 (tăng dần)
ZREVRANGE leaderboard 0 2 WITHSCORES # Top 3 (giảm dần)
# Lấy range theo score
ZRANGEBYSCORE leaderboard 80 95 WITHSCORES
# Increment score
ZINCRBY leaderboard 10 "player:2" # player:2 bây giờ có 95
# Đếm members trong score range
ZCOUNT leaderboard 80 100
# Xóa members
ZREM leaderboard "player:3"Use Cases:
- Leaderboards và rankings
- Priority queues
- Time-based data (dùng timestamp làm score)
- Rate limiting với sliding windows
Key Expiration và TTL
Redis có thể tự động expire keys sau một thời gian nhất định - thiết yếu cho caching.
# Set key với expiration
SET session:token "user_data" EX 3600 # Hết hạn sau 3600 giây
SET session:token "user_data" PX 60000 # Hết hạn sau 60000 milliseconds
# Set expiration cho key hiện có
EXPIRE session:token 1800 # 30 phút từ bây giờ
EXPIREAT session:token 1735689600 # Unix timestamp
# Kiểm tra TTL còn lại
TTL session:token # Trả về giây, -1 nếu không có expiry, -2 nếu key không tồn tại
PTTL session:token # Trả về milliseconds
# Xóa expiration (làm cho persistent)
PERSIST session:tokenBest Practices:
- Luôn set TTL cho cache entries
- Sử dụng TTL phù hợp dựa trên mức độ biến động của dữ liệu
- Cân nhắc memory limits khi set TTL dài
- Sử dụng
SCANthay vìKEYS *trong production (non-blocking)
Các Tùy Chọn Persistence
Redis lưu dữ liệu trong memory, nhưng cung cấp persistence cho durability.
RDB (Redis Database)
Point-in-time snapshots lưu vào disk.
# Manual snapshot
BGSAVE # Background save
# Configuration (redis.conf)
# save 900 1 # Lưu nếu 1 key thay đổi trong 900 giây
# save 300 10 # Lưu nếu 10 keys thay đổi trong 300 giây
# save 60 10000 # Lưu nếu 10000 keys thay đổi trong 60 giâyƯu Điểm:
- File đơn, compact
- Restarts nhanh
- Tốt cho backups
Nhược Điểm:
- Có thể mất dữ liệu (đến snapshot cuối cùng)
- Fork có thể chậm với datasets lớn
AOF (Append-Only File)
Logs mọi write operation.
# Configuration (redis.conf)
# appendonly yes
# appendfsync everysec # Sync mỗi giây (khuyến nghị)
# appendfsync always # Sync mỗi write (chậm hơn nhưng an toàn hơn)
# appendfsync no # Để OS quyết định (nhanh nhất nhưng rủi ro)Ưu Điểm:
- Bền hơn (mất dữ liệu tối thiểu)
- Log readable bởi người
- Auto-rewrite để compact size
Nhược Điểm:
- Files lớn hơn RDB
- Restarts chậm hơn
Hybrid Approach (Khuyến Nghị)
Sử dụng cả RDB và AOF:
# redis.conf
appendonly yes
appendfsync everysec
save 900 1
save 300 10Pub/Sub Messaging
Redis hỗ trợ publish/subscribe messaging cho real-time communication.
# Terminal 1: Subscribe channel
SUBSCRIBE news:tech
# Terminal 2: Publish message
PUBLISH news:tech "Redis 7.2 released!"
# Pattern subscription
PSUBSCRIBE news:* # Subscribe tất cả news channels
# Unsubscribe
UNSUBSCRIBE news:techUse Cases:
- Real-time notifications
- Chat applications
- Live updates (sports scores, stock prices)
- Cache invalidation giữa các servers
Limitations:
- Không có message persistence (bị miss nếu subscriber offline)
- Không có acknowledgment mechanism
- Cân nhắc Redis Streams cho messaging robust hơn
Transactions
Redis hỗ trợ atomic transactions với MULTI/EXEC.
# Bắt đầu transaction
MULTI
# Queue commands
SET user:1:balance 100
DECRBY user:1:balance 25
INCRBY user:2:balance 25
# Thực thi tất cả commands atomically
EXEC
# Hủy transaction
DISCARDWatch cho Optimistic Locking:
WATCH user:1:balance
val = GET user:1:balance
MULTI
SET user:1:balance (val - 25)
EXEC # Thất bại nếu user:1:balance thay đổi từ khi WATCHLua Scripting
Cho các complex atomic operations, sử dụng Lua scripts.
# Simple script
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
# Transfer funds atomically
EVAL "
local from = KEYS[1]
local to = KEYS[2]
local amount = tonumber(ARGV[1])
local balance = tonumber(redis.call('GET', from))
if balance >= amount then
redis.call('DECRBY', from, amount)
redis.call('INCRBY', to, amount)
return 1
end
return 0
" 2 user:1:balance user:2:balance 50Lợi Ích:
- Atomic execution
- Giảm network round trips
- Complex logic trong single call
Các Use Cases Thực Tế
1. Session Management
# Lưu session
HSET session:abc123 user_id 1 username "john" role "admin"
EXPIRE session:abc123 3600
# Validate session
EXISTS session:abc123
HGET session:abc123 user_id
# Extend session
EXPIRE session:abc123 3600
# Logout
DEL session:abc1232. Rate Limiting
# Simple rate limiter (10 requests mỗi phút)
local key = "ratelimit:" .. user_id
local count = redis.call('INCR', key)
if count == 1 then
redis.call('EXPIRE', key, 60)
end
if count > 10 then
return 0 -- Rate limited
end
return 1 -- Allowed3. Caching với Cache-Aside Pattern
# Kiểm tra cache trước
cached = GET cache:user:1
if cached is nil then
# Cache miss - fetch từ database
data = fetch_from_database(1)
# Lưu vào cache với TTL
SET cache:user:1 data EX 300
return data
else
return cached
end4. Real-Time Leaderboard
# Update score khi có action
ZINCRBY game:leaderboard 10 "player:123"
# Lấy top 10 players
ZREVRANGE game:leaderboard 0 9 WITHSCORES
# Lấy player rank
ZREVRANK game:leaderboard "player:123"5. Job Queue
# Producer: Thêm job
LPUSH jobs:pending '{"type":"email","to":"[email protected]"}'
# Consumer: Process job (blocking)
job = BRPOP jobs:pending 30
# Process job...
# Khi thất bại, push vào retry queue
LPUSH jobs:retry jobBest Practices Cho Production
1. Memory Management
# Kiểm tra memory usage
INFO memory
# Set max memory limit
CONFIG SET maxmemory 2gb
# Set eviction policy
CONFIG SET maxmemory-policy allkeys-lruEviction Policies:
noeviction: Trả về error khi memory limit reachedallkeys-lru: Evict least recently used keysvolatile-lru: Evict LRU keys có TTL setallkeys-random: Random evictionvolatile-ttl: Evict keys có TTL ngắn nhất
2. Key Naming Conventions
Sử dụng colons để tạo namespaces:
user:1:profile
user:1:sessions
cache:products:123
queue:emails:pending3. Tránh Anti-Patterns
# ❌ Không bao giờ dùng KEYS trong production (blocks server)
KEYS user:*
# ✅ Sử dụng SCAN thay thế (cursor-based, non-blocking)
SCAN 0 MATCH user:* COUNT 1004. Connection Pooling
Luôn sử dụng connection pools trong ứng dụng của bạn:
// Spring Boot example
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128);
poolConfig.setMaxIdle(64);
poolConfig.setMinIdle(16);5. Monitoring
Các metrics thiết yếu cần monitor:
- Memory usage (
used_memory) - Connected clients
- Commands per second
- Cache hit rate
- Keyspace statistics
Tổng Kết
Redis là một công cụ mạnh mẽ, đa năng mà mọi backend developer nên biết:
Những Điểm Chính:
✅ Redis là in-memory data structure store với sub-millisecond latency
✅ Năm kiểu dữ liệu cốt lõi: Strings, Lists, Sets, Hashes, Sorted Sets
✅ Sử dụng TTL cho automatic key expiration
✅ Chọn persistence dựa trên nhu cầu durability (RDB vs AOF)
✅ Pub/Sub cho phép real-time messaging
✅ Lua scripts cho atomic complex operations
✅ Tuân theo best practices cho production deployments
Các Bước Tiếp Theo:
- Thực Hành: Chạy Redis locally và thử nghiệm với commands
- Xây Dựng: Tạo một rate limiter hoặc session store đơn giản
- Tích Hợp: Thêm Redis caching vào ứng dụng của bạn
- Học Thêm: Khám phá Redis Streams, Cluster, và Sentinel
Tài Nguyên Bổ Sung
Tài Liệu Chính Thức:
Các Hướng Dẫn Liên Quan:
- Spring Boot Caching với Redis - Triển khai Redis caching trong ứng dụng Java
- Learning Docker: Why It Matters - Containerize Redis setup của bạn
Công Cụ:
- RedisInsight - Redis GUI chính thức
- redis-cli - Command-line interface
Sẵn sàng triển khai Redis trong ứng dụng của bạn? Xem Spring Boot Caching với Redis để có hướng dẫn tích hợp đầy đủ!
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.