redis-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRedis Best Practices
Redis开发最佳实践
Core Principles
核心原则
- Use Redis for caching, session storage, real-time analytics, and message queuing
- Choose appropriate data structures for your use case
- Implement proper key naming conventions and expiration policies
- Design for high availability and persistence requirements
- Monitor memory usage and optimize for performance
- 将Redis用于缓存、会话存储、实时分析和消息队列
- 根据使用场景选择合适的数据结构
- 实施规范的键命名约定和过期策略
- 针对高可用性和持久化需求进行设计
- 监控内存使用情况并优化性能
Key Naming Conventions
键命名规范
- Use colons as namespace separators
- Include object type and identifier in key names
- Keep keys short but descriptive
- Use consistent naming patterns across your application
undefined- 使用冒号作为命名空间分隔符
- 在键名中包含对象类型和标识符
- 保持键名简短但具有描述性
- 在整个应用中使用一致的命名模式
undefinedGood key naming examples
良好的键命名示例
user:1234:profile
user:1234:sessions
order:5678:items
cache:api:products:list
queue:email:pending
session:abc123def456
rate_limit:api:user:1234
undefineduser:1234:profile
user:1234:sessions
order:5678:items
cache:api:products:list
queue:email:pending
session:abc123def456
rate_limit:api:user:1234
undefinedData Structures
数据结构
Strings
字符串
- Use for simple key-value storage, counters, and caching
- Consider using MGET/MSET for batch operations
redis
undefined- 用于简单键值存储、计数器和缓存
- 考虑使用MGET/MSET进行批量操作
redis
undefinedSimple caching
简单缓存
SET cache:user:1234 '{"name":"John","email":"john@example.com"}' EX 3600
SET cache:user:1234 '{"name":"John","email":"john@example.com"}' EX 3600
Counters
计数器
INCR stats:pageviews:homepage
INCRBY stats:downloads:file123 5
INCR stats:pageviews:homepage
INCRBY stats:downloads:file123 5
Atomic operations
原子操作
SETNX lock:resource:456 "owner:abc" EX 30
undefinedSETNX lock:resource:456 "owner:abc" EX 30
undefinedHashes
哈希表
- Use for objects with multiple fields
- More memory-efficient than multiple string keys
- Supports partial updates
redis
undefined- 用于包含多个字段的对象存储
- 比多个字符串键更节省内存
- 支持部分更新
redis
undefinedStore user profile
存储用户资料
HSET user:1234 name "John Doe" email "john@example.com" created_at "2024-01-15"
HSET user:1234 name "John Doe" email "john@example.com" created_at "2024-01-15"
Get specific fields
获取指定字段
HGET user:1234 email
HMGET user:1234 name email
HGET user:1234 email
HMGET user:1234 name email
Increment numeric fields
递增数值字段
HINCRBY user:1234 login_count 1
HINCRBY user:1234 login_count 1
Get all fields
获取所有字段
HGETALL user:1234
undefinedHGETALL user:1234
undefinedLists
列表
- Use for queues, recent items, and activity feeds
- Consider blocking operations for queue consumers
redis
undefined- 用于队列、最近项和活动信息流
- 队列消费者可考虑使用阻塞操作
redis
undefinedMessage queue
消息队列
LPUSH queue:emails '{"to":"user@example.com","subject":"Welcome"}'
RPOP queue:emails
LPUSH queue:emails '{"to":"user@example.com","subject":"Welcome"}'
RPOP queue:emails
Blocking pop for workers
工作进程使用阻塞弹出
BRPOP queue:emails 30
BRPOP queue:emails 30
Recent activity (keep last 100)
最近活动(保留最后100条)
LPUSH user:1234:activity "viewed product 567"
LTRIM user:1234:activity 0 99
LPUSH user:1234:activity "浏览了商品567"
LTRIM user:1234:activity 0 99
Get recent items
获取最近项
LRANGE user:1234:activity 0 9
undefinedLRANGE user:1234:activity 0 9
undefinedSets
集合
- Use for unique collections, tags, and relationships
- Supports set operations (union, intersection, difference)
redis
undefined- 用于唯一集合、标签和关系存储
- 支持集合操作(并集、交集、差集)
redis
undefinedUser tags/interests
用户标签/兴趣
SADD user:1234:interests "technology" "music" "travel"
SADD user:1234:interests "technology" "music" "travel"
Check membership
检查成员资格
SISMEMBER user:1234:interests "music"
SISMEMBER user:1234:interests "music"
Find common interests
查找共同兴趣
SINTER user:1234:interests user:5678:interests
SINTER user:1234:interests user:5678:interests
Online users tracking
在线用户追踪
SADD online:users "user:1234"
SREM online:users "user:1234"
SMEMBERS online:users
undefinedSADD online:users "user:1234"
SREM online:users "user:1234"
SMEMBERS online:users
undefinedSorted Sets
有序集合
- Use for leaderboards, priority queues, and time-series data
- Elements sorted by score
redis
undefined- 用于排行榜、优先级队列和时间序列数据
- 元素按分数排序
redis
undefinedLeaderboard
游戏排行榜
ZADD leaderboard:game1 1500 "player:123" 2000 "player:456" 1800 "player:789"
ZADD leaderboard:game1 1500 "player:123" 2000 "player:456" 1800 "player:789"
Get top 10
获取前10名
ZREVRANGE leaderboard:game1 0 9 WITHSCORES
ZREVRANGE leaderboard:game1 0 9 WITHSCORES
Get player rank
获取玩家排名
ZREVRANK leaderboard:game1 "player:123"
ZREVRANK leaderboard:game1 "player:123"
Time-based data (score = timestamp)
基于时间的数据(分数=时间戳)
ZADD events:user:1234 1705329600 "login" 1705330000 "purchase"
ZADD events:user:1234 1705329600 "登录" 1705330000 "购买"
Get events in time range
获取时间范围内的事件
ZRANGEBYSCORE events:user:1234 1705329600 1705333200
undefinedZRANGEBYSCORE events:user:1234 1705329600 1705333200
undefinedStreams
流
- Use for event streaming and log data
- Supports consumer groups for distributed processing
redis
undefined- 用于事件流和日志数据
- 支持消费者组进行分布式处理
redis
undefinedAdd events to stream
向流中添加事件
XADD events:orders * customer_id 1234 product_id 567 amount 99.99
XADD events:orders * customer_id 1234 product_id 567 amount 99.99
Read from stream
从流中读取数据
XREAD COUNT 10 STREAMS events:orders 0
XREAD COUNT 10 STREAMS events:orders 0
Consumer groups
消费者组配置
XGROUP CREATE events:orders order-processors $ MKSTREAM
XREADGROUP GROUP order-processors worker1 COUNT 10 STREAMS events:orders >
XGROUP CREATE events:orders order-processors $ MKSTREAM
XREADGROUP GROUP order-processors worker1 COUNT 10 STREAMS events:orders >
Acknowledge processed messages
确认已处理的消息
XACK events:orders order-processors 1234567890-0
undefinedXACK events:orders order-processors 1234567890-0
undefinedCaching Patterns
缓存模式
Cache-Aside Pattern
旁路缓存模式
python
undefinedpython
undefinedPseudo-code for cache-aside
旁路缓存伪代码
def get_user(user_id):
# Try cache first
cached = redis.get(f"cache:user:{user_id}")
if cached:
return json.loads(cached)
# Cache miss - fetch from database
user = database.get_user(user_id)
# Store in cache with expiration
redis.setex(f"cache:user:{user_id}", 3600, json.dumps(user))
return userundefineddef get_user(user_id):
# 先尝试从缓存获取
cached = redis.get(f"cache:user:{user_id}")
if cached:
return json.loads(cached)
# 缓存未命中 - 从数据库获取
user = database.get_user(user_id)
# 存入缓存并设置过期时间
redis.setex(f"cache:user:{user_id}", 3600, json.dumps(user))
return userundefinedWrite-Through Pattern
写穿缓存模式
python
def update_user(user_id, data):
# Update database
database.update_user(user_id, data)
# Update cache
redis.setex(f"cache:user:{user_id}", 3600, json.dumps(data))python
def update_user(user_id, data):
# 更新数据库
database.update_user(user_id, data)
# 更新缓存
redis.setex(f"cache:user:{user_id}", 3600, json.dumps(data))Cache Invalidation
缓存失效
redis
undefinedredis
undefinedDelete specific cache
删除指定缓存
DEL cache:user:1234
DEL cache:user:1234
Delete by pattern (use with caution in production)
按模式删除(生产环境谨慎使用)
Use SCAN instead of KEYS for large datasets
大数据集下使用SCAN替代KEYS
SCAN 0 MATCH cache:user:* COUNT 100
SCAN 0 MATCH cache:user:* COUNT 100
Tag-based invalidation using sets
使用集合实现基于标签的失效
SADD cache:tags:user:1234 "cache:user:1234:profile" "cache:user:1234:orders"
SADD cache:tags:user:1234 "cache:user:1234:profile" "cache:user:1234:orders"
Invalidate all related caches
失效所有相关缓存
SMEMBERS cache:tags:user:1234
SMEMBERS cache:tags:user:1234
Then delete each key
然后逐个删除键
undefinedundefinedExpiration and Memory Management
过期策略与内存管理
TTL Best Practices
TTL最佳实践
- Always set TTL on cache keys
- Use jitter to prevent thundering herd
- Consider sliding expiration for session data
redis
undefined- 始终为缓存键设置TTL
- 使用抖动避免缓存雪崩
- 会话数据可考虑使用滑动过期
redis
undefinedSet with expiration
设置键并指定过期时间
SET cache:data:123 "value" EX 3600
SET cache:data:123 "value" EX 3600
Set expiration on existing key
为已存在的键设置过期时间
EXPIRE cache:data:123 3600
EXPIRE cache:data:123 3600
Check TTL
查看键的剩余TTL
TTL cache:data:123
TTL cache:data:123
Persist key (remove expiration)
持久化键(移除过期时间)
PERSIST cache:data:123
undefinedPERSIST cache:data:123
undefinedMemory Management
内存管理
redis
undefinedredis
undefinedCheck memory usage
查看内存使用情况
INFO memory
INFO memory
Get key memory usage
获取单个键的内存占用
MEMORY USAGE cache:large:object
MEMORY USAGE cache:large:object
Configure max memory policy
配置最大内存策略
CONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru
undefinedCONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru
undefinedTransactions and Atomicity
事务与原子性
MULTI/EXEC Transactions
MULTI/EXEC事务
redis
undefinedredis
undefinedTransaction block
事务块
MULTI
INCR stats:views
LPUSH recent:views "page:123"
EXEC
MULTI
INCR stats:views
LPUSH recent:views "page:123"
EXEC
Watch for optimistic locking
使用WATCH实现乐观锁
WATCH user:1234:balance
balance = GET user:1234:balance
MULTI
SET user:1234:balance (balance - 100)
EXEC
undefinedWATCH user:1234:balance
balance = GET user:1234:balance
MULTI
SET user:1234:balance (balance - 100)
EXEC
undefinedLua Scripts
Lua脚本
- Use for complex atomic operations
- Scripts execute atomically
lua
-- Rate limiting script
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local current = tonumber(redis.call('GET', key) or '0')
if current >= limit then
return 0
end
redis.call('INCR', key)
if current == 0 then
redis.call('EXPIRE', key, window)
end
return 1redis
undefined- 用于复杂原子操作
- 脚本执行具有原子性
lua
-- 限流脚本
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local current = tonumber(redis.call('GET', key) or '0')
if current >= limit then
return 0
end
redis.call('INCR', key)
if current == 0 then
redis.call('EXPIRE', key, window)
end
return 1redis
undefinedExecute Lua script
执行Lua脚本
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
undefinedEVAL "return redis.call('GET', KEYS[1])" 1 mykey
undefinedPub/Sub and Messaging
发布/订阅与消息队列
redis
undefinedredis
undefinedPublisher
发布者
PUBLISH channel:notifications '{"type":"alert","message":"New order"}'
PUBLISH channel:notifications '{"type":"alert","message":"新订单"}'
Subscriber
订阅者
SUBSCRIBE channel:notifications
SUBSCRIBE channel:notifications
Pattern subscription
模式订阅
PSUBSCRIBE channel:*
undefinedPSUBSCRIBE channel:*
undefinedHigh Availability
高可用性
Replication
主从复制
- Use replicas for read scaling
- Configure proper persistence on master
redis
undefined- 使用从节点实现读扩展
- 在主节点上配置合适的持久化策略
redis
undefinedOn replica
在从节点上配置主节点地址
REPLICAOF master_host 6379
REPLICAOF master_host 6379
Check replication status
查看复制状态
INFO replication
undefinedINFO replication
undefinedRedis Sentinel
Redis哨兵
- Use for automatic failover
- Deploy at least 3 Sentinel instances
- 用于自动故障转移
- 至少部署3个Sentinel实例
Redis Cluster
Redis集群
- Use for horizontal scaling
- Data automatically sharded across nodes
- Use hash tags for related keys
redis
undefined- 用于水平扩展
- 数据自动分片到各个节点
- 使用哈希标签确保相关键存储在同一个槽位
redis
undefinedHash tags ensure keys go to same slot
哈希标签确保相关键进入同一个槽位
SET {user:1234}:profile "data"
SET {user:1234}:settings "data"
undefinedSET {user:1234}:profile "data"
SET {user:1234}:settings "data"
undefinedPersistence
持久化
RDB Snapshots
RDB快照
redis
undefinedredis
undefinedManual snapshot
手动触发快照
BGSAVE
BGSAVE
Configure automatic snapshots
配置自动快照策略
CONFIG SET save "900 1 300 10 60 10000"
undefinedCONFIG SET save "900 1 300 10 60 10000"
undefinedAOF (Append-Only File)
AOF(仅追加文件)
redis
undefinedredis
undefinedEnable AOF
启用AOF
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec
Rewrite AOF
重写AOF文件
BGREWRITEAOF
undefinedBGREWRITEAOF
undefinedSecurity
安全
- Require authentication
- Use TLS for connections
- Bind to specific interfaces
- Disable dangerous commands
redis
undefined- 启用身份验证
- 使用TLS加密连接
- 绑定到特定网络接口
- 禁用危险命令
redis
undefinedSet password
设置密码
CONFIG SET requirepass "your_strong_password"
CONFIG SET requirepass "your_strong_password"
Authenticate
身份验证
AUTH your_strong_password
AUTH your_strong_password
Rename dangerous commands (in redis.conf)
重命名危险命令(在redis.conf中配置)
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
undefinedrename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
undefinedMonitoring
监控
redis
undefinedredis
undefinedServer info
查看服务器信息
INFO
INFO
Memory stats
查看内存统计
INFO memory
INFO memory
Client connections
查看客户端连接
CLIENT LIST
CLIENT LIST
Slow log
查看慢查询日志
SLOWLOG GET 10
SLOWLOG GET 10
Monitor commands (debug only)
监控命令执行(仅用于调试)
MONITOR
MONITOR
Key count per database
查看各数据库的键数量
INFO keyspace
undefinedINFO keyspace
undefinedConnection Management
连接管理
- Use connection pooling
- Set appropriate timeouts
- Handle reconnection gracefully
python
undefined- 使用连接池
- 设置合理的超时时间
- 优雅处理重连逻辑
python
undefinedPython example with connection pool
Python连接池示例
import redis
pool = redis.ConnectionPool(
host='localhost',
port=6379,
max_connections=50,
socket_timeout=5,
socket_connect_timeout=5
)
redis_client = redis.Redis(connection_pool=pool)
undefinedimport redis
pool = redis.ConnectionPool(
host='localhost',
port=6379,
max_connections=50,
socket_timeout=5,
socket_connect_timeout=5
)
redis_client = redis.Redis(connection_pool=pool)
undefinedPerformance Tips
性能优化技巧
- Use pipelining for batch operations
- Avoid large keys (>100KB values)
- Use SCAN instead of KEYS in production
- Monitor and optimize memory usage
- Consider using RedisJSON for complex JSON operations
redis
undefined- 使用流水线处理批量操作
- 避免使用大键(值大于100KB)
- 生产环境使用SCAN替代KEYS
- 监控并优化内存使用
- 复杂JSON操作可考虑使用RedisJSON
redis
undefinedPipeline example (pseudo-code)
流水线示例(伪代码)
pipe = redis.pipeline()
pipe.get("key1")
pipe.get("key2")
pipe.set("key3", "value")
results = pipe.execute()
undefinedpipe = redis.pipeline()
pipe.get("key1")
pipe.get("key2")
pipe.set("key3", "value")
results = pipe.execute()
undefined