mcpField
R
redis-best-practices

redis-best-practices

github.com/mindrally数据与数据库2872.2k 次安装3 周前更新
代码仓库

关于 redis-best-practices

redis-best-practices 是面向 Redis 应用开发与运维的实践指南,涵盖数据结构、缓存、可靠性、安全和性能,并提供命令示例。

主要功能

  1. 01Redis 数据结构选择建议
  2. 02键命名与过期策略
  3. 03缓存与失效模式
  4. 04事务与原子操作
  5. 05高可用、持久化与安全
  6. 06监控与性能实践

适用场景

  1. 01为队列或排行榜选择数据结构
  2. 02设计缓存 TTL 与失效策略
  3. 03规划 Redis 复制与持久化
  4. 04检查 Redis 内存和连接设置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mindrally/skills --skill redis-best-practices

安装后在 Claude Code 中输入/redis-best-practices确认已加载。

详细介绍

Redis 最佳实践

核心原则

  • 使用 Redis 进行缓存、会话存储、实时分析和消息队列
  • 根据使用场景选择合适的数据结构
  • 制定恰当的键命名规范和过期策略
  • 根据高可用性和持久化需求进行设计
  • 监控内存使用情况并优化性能

键命名规范

  • 使用冒号分隔命名空间
  • 在键名中包含对象类型和标识符
  • 键名应简短且具有描述性
  • 在整个应用中使用一致的命名模式
# Good 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

数据结构

字符串
  • 用于简单的键值存储、计数器和缓存
  • 可考虑使用 MGET/MSET 进行批量操作
# Simple caching
SET cache:user:1234 '{"name":"John","email":"[email protected]"}' EX 3600

# Counters
INCR stats:pageviews:homepage
INCRBY stats:downloads:file123 5

# Atomic operations
SETNX lock:resource:456 "owner:abc" EX 30
哈希
  • 用于包含多个字段的对象
  • 比使用多个字符串键更节省内存
  • 支持部分更新
# Store user profile
HSET user:1234 name "John Doe" email "[email protected]" created_at "2024-01-15"

# Get specific fields
HGET user:1234 email
HMGET user:1234 name email

# Increment numeric fields
HINCRBY user:1234 login_count 1

# Get all fields
HGETALL user:1234
列表
  • 用于队列、最近项目和活动动态
  • 可考虑为队列消费者使用阻塞操作
# Message queue
LPUSH queue:emails '{"to":"[email protected]","subject":"Welcome"}'
RPOP queue:emails

# Blocking pop for workers
BRPOP queue:emails 30

# Recent activity (keep last 100)
LPUSH user:1234:activity "viewed product 567"
LTRIM user:1234:activity 0 99

# Get recent items
LRANGE user:1234:activity 0 9
集合
  • 用于唯一值集合、标签和关系
  • 支持集合运算(并集、交集、差集)
# User tags/interests
SADD user:1234:interests "technology" "music" "travel"

# Check membership
SISMEMBER user:1234:interests "music"

# Find common interests
SINTER user:1234:interests user:5678:interests

# Online users tracking
SADD online:users "user:1234"
SREM online:users "user:1234"
SMEMBERS online:users
有序集合
  • 用于排行榜、优先级队列和时间序列数据
  • 元素按分数排序
# Leaderboard
ZADD leaderboard:game1 1500 "player:123" 2000 "player:456" 1800 "player:789"

# Get top 10
ZREVRANGE leaderboard:game1 0 9 WITHSCORES

# Get player rank
ZREVRANK leaderboard:game1 "player:123"

# Time-based data (score = timestamp)
ZADD events:user:1234 1705329600 "login" 1705330000 "purchase"

# Get events in time range
ZRANGEBYSCORE events:user:1234 1705329600 1705333200
流
  • 用于事件流和日志数据
  • 支持消费者组,以便进行分布式处理
# Add events to stream
XADD events:orders * customer_id 1234 product_id 567 amount 99.99

# Read from stream
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 >

# Acknowledge processed messages
XACK events:orders order-processors 1234567890-0

缓存模式

Cache-Aside 模式
# Pseudo-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 user
Write-Through 模式
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))
缓存失效
# Delete specific cache
DEL cache:user:1234

# Delete by pattern (use with caution in production)
# Use SCAN instead of KEYS for large datasets
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"
# Invalidate all related caches
SMEMBERS cache:tags:user:1234
# Then delete each key

过期与内存管理

TTL 最佳实践
  • 始终为缓存键设置 TTL
  • 使用随机抖动,避免惊群效应
  • 会话数据可考虑使用滑动过期
# Set with expiration
SET cache:data:123 "value" EX 3600

# Set expiration on existing key
EXPIRE cache:data:123 3600

# Check TTL
TTL cache:data:123

# Persist key (remove expiration)
PERSIST cache:data:123
内存管理
# Check memory usage
INFO memory

# Get key memory usage
MEMORY USAGE cache:large:object

# Configure max memory policy
CONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru

事务与原子性

MULTI/EXEC 事务
# Transaction block
MULTI
INCR stats:views
LPUSH recent:views "page:123"
EXEC

# Watch for optimistic locking
WATCH user:1234:balance
balance = GET user:1234:balance
MULTI
SET user:1234:balance (balance - 100)
EXEC
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 1
# Execute Lua script
EVAL "return redis.call('GET', KEYS[1])" 1 mykey

发布/订阅与消息传递

# Publisher
PUBLISH channel:notifications '{"type":"alert","message":"New order"}'

# Subscriber
SUBSCRIBE channel:notifications

# Pattern subscription
PSUBSCRIBE channel:*

高可用性

复制
  • 使用副本扩展读取能力
  • 在主节点上配置恰当的持久化
# On replica
REPLICAOF master_host 6379

# Check replication status
INFO replication
Redis Sentinel
  • 用于自动故障转移
  • 至少部署 3 个 Sentinel 实例
Redis Cluster
  • 用于水平扩展
  • 数据会自动分片到各节点
  • 为相关键使用哈希标签
# Hash tags ensure keys go to same slot
SET {user:1234}:profile "data"
SET {user:1234}:settings "data"

持久化

RDB 快照
# Manual snapshot
BGSAVE

# Configure automatic snapshots
CONFIG SET save "900 1 300 10 60 10000"
AOF(仅追加文件)
# Enable AOF
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec

# Rewrite AOF
BGREWRITEAOF

安全

  • 要求进行身份验证
  • 使用 TLS 连接
  • 绑定到指定接口
  • 禁用危险命令
# Set password
CONFIG SET requirepass "your_strong_password"

# Authenticate
AUTH your_strong_password

# Rename dangerous commands (in redis.conf)
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""

监控

# Server info
INFO

# Memory stats
INFO memory

# Client connections
CLIENT LIST

# Slow log
SLOWLOG GET 10

# Monitor commands (debug only)
MONITOR

# Key count per database
INFO keyspace

连接管理

  • 使用连接池
  • 设置恰当的超时时间
  • 妥善处理重新连接
# Python example with connection pool
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)

性能提示

  • 使用流水线进行批量操作
  • 避免使用大型键(值超过 100 KB)
  • 在生产环境中使用 SCAN,而不是 KEYS
  • 监控并优化内存使用情况
  • 复杂的 JSON 操作可考虑使用 RedisJSON
# Pipeline example (pseudo-code)
pipe = redis.pipeline()
pipe.get("key1")
pipe.get("key2")
pipe.set("key3", "value")
results = pipe.execute()

评论

支持 Markdown