Redis Best Practices

mindrally/skills/redis-best-practices

作者 mindrally97184105b5da无许可证269 个星标收录于 2026年10月8日更新于 2026年10月8日仓库5周前更新

Redis development best practices for caching, data structures, and high-performance key-value operations

AI 生成的概览

关于 Redis 开发最佳实践的参考指南,涵盖缓存、数据结构与键值操作。

功能
该技能是一份说明性参考文档,介绍 Redis 开发实践:键命名约定、数据结构(字符串、哈希、列表、集合、有序集合、流)、缓存模式、过期与内存管理、事务、发布订阅、高可用、持久化、安全、监控、连接管理与性能建议。内容以原则和带注释的命令示例呈现,而非可执行工具。它产出的是供代理在编写或审查 Redis 用法时参考的指导文本。
适用场景
在设计或审查基于 Redis 的缓存、会话存储、队列或实时数据功能,并希望采用成熟约定与命令模式时使用。在实现过程中核对键命名、TTL、内存策略或持久化选择时也适用。
运行要求
该技能不附带脚本或资源,仅为说明性内容。实践示例假定可访问 Redis 服务器,Python 片段还需 Redis 客户端库,但阅读这些指导本身不需要任何依赖。

Redis Best Practices

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

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
# Good key naming examplesuser:1234:profileuser:1234:sessionsorder:5678:itemscache:api:products:listqueue:email:pendingsession:abc123def456rate_limit:api:user:1234

Data Structures

Strings

  • Use for simple key-value storage, counters, and caching
  • Consider using MGET/MSET for batch operations
redis
# Simple cachingSET cache:user:1234 '{"name":"John","email":"[email protected]"}' EX 3600
# CountersINCR stats:pageviews:homepageINCRBY stats:downloads:file123 5
# Atomic operationsSETNX lock:resource:456 "owner:abc" EX 30

Hashes

  • Use for objects with multiple fields
  • More memory-efficient than multiple string keys
  • Supports partial updates
redis
# Store user profileHSET user:1234 name "John Doe" email "[email protected]" created_at "2024-01-15"
# Get specific fieldsHGET user:1234 emailHMGET user:1234 name email
# Increment numeric fieldsHINCRBY user:1234 login_count 1
# Get all fieldsHGETALL user:1234

Lists

  • Use for queues, recent items, and activity feeds
  • Consider blocking operations for queue consumers
redis
# Message queueLPUSH queue:emails '{"to":"[email protected]","subject":"Welcome"}'RPOP queue:emails
# Blocking pop for workersBRPOP queue:emails 30
# Recent activity (keep last 100)LPUSH user:1234:activity "viewed product 567"LTRIM user:1234:activity 0 99
# Get recent itemsLRANGE user:1234:activity 0 9

Sets

  • Use for unique collections, tags, and relationships
  • Supports set operations (union, intersection, difference)
redis
# User tags/interestsSADD user:1234:interests "technology" "music" "travel"
# Check membershipSISMEMBER user:1234:interests "music"
# Find common interestsSINTER user:1234:interests user:5678:interests
# Online users trackingSADD online:users "user:1234"SREM online:users "user:1234"SMEMBERS online:users

Sorted Sets

  • Use for leaderboards, priority queues, and time-series data
  • Elements sorted by score
redis
# LeaderboardZADD leaderboard:game1 1500 "player:123" 2000 "player:456" 1800 "player:789"
# Get top 10ZREVRANGE leaderboard:game1 0 9 WITHSCORES
# Get player rankZREVRANK leaderboard:game1 "player:123"
# Time-based data (score = timestamp)ZADD events:user:1234 1705329600 "login" 1705330000 "purchase"
# Get events in time rangeZRANGEBYSCORE events:user:1234 1705329600 1705333200

Streams

  • Use for event streaming and log data
  • Supports consumer groups for distributed processing
redis
# Add events to streamXADD events:orders * customer_id 1234 product_id 567 amount 99.99
# Read from streamXREAD COUNT 10 STREAMS events:orders 0
# Consumer groupsXGROUP CREATE events:orders order-processors $ MKSTREAMXREADGROUP GROUP order-processors worker1 COUNT 10 STREAMS events:orders >
# Acknowledge processed messagesXACK events:orders order-processors 1234567890-0

Caching Patterns

Cache-Aside Pattern

python
# Pseudo-code for cache-asidedef 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 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))

Cache Invalidation

redis
# Delete specific cacheDEL cache:user:1234
# Delete by pattern (use with caution in production)# Use SCAN instead of KEYS for large datasetsSCAN 0 MATCH cache:user:* COUNT 100
# Tag-based invalidation using setsSADD cache:tags:user:1234 "cache:user:1234:profile" "cache:user:1234:orders"# Invalidate all related cachesSMEMBERS cache:tags:user:1234# Then delete each key

Expiration and Memory Management

TTL Best Practices

  • Always set TTL on cache keys
  • Use jitter to prevent thundering herd
  • Consider sliding expiration for session data
redis
# Set with expirationSET cache:data:123 "value" EX 3600
# Set expiration on existing keyEXPIRE cache:data:123 3600
# Check TTLTTL cache:data:123
# Persist key (remove expiration)PERSIST cache:data:123

Memory Management

redis
# Check memory usageINFO memory
# Get key memory usageMEMORY USAGE cache:large:object
# Configure max memory policyCONFIG SET maxmemory 2gbCONFIG SET maxmemory-policy allkeys-lru

Transactions and Atomicity

MULTI/EXEC Transactions

redis
# Transaction blockMULTIINCR stats:viewsLPUSH recent:views "page:123"EXEC
# Watch for optimistic lockingWATCH user:1234:balancebalance = GET user:1234:balanceMULTISET user:1234:balance (balance - 100)EXEC

Lua Scripts

  • Use for complex atomic operations
  • Scripts execute atomically
lua
-- Rate limiting scriptlocal 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 0end
redis.call('INCR', key)if current == 0 then    redis.call('EXPIRE', key, window)end
return 1
redis
# Execute Lua scriptEVAL "return redis.call('GET', KEYS[1])" 1 mykey

Pub/Sub and Messaging

redis
# PublisherPUBLISH channel:notifications '{"type":"alert","message":"New order"}'
# SubscriberSUBSCRIBE channel:notifications
# Pattern subscriptionPSUBSCRIBE channel:*

High Availability

Replication

  • Use replicas for read scaling
  • Configure proper persistence on master
redis
# On replicaREPLICAOF master_host 6379
# Check replication statusINFO replication

Redis Sentinel

  • Use for automatic failover
  • Deploy at least 3 Sentinel instances

Redis Cluster

  • Use for horizontal scaling
  • Data automatically sharded across nodes
  • Use hash tags for related keys
redis
# Hash tags ensure keys go to same slotSET {user:1234}:profile "data"SET {user:1234}:settings "data"

Persistence

RDB Snapshots

redis
# Manual snapshotBGSAVE
# Configure automatic snapshotsCONFIG SET save "900 1 300 10 60 10000"

AOF (Append-Only File)

redis
# Enable AOFCONFIG SET appendonly yesCONFIG SET appendfsync everysec
# Rewrite AOFBGREWRITEAOF

Security

  • Require authentication
  • Use TLS for connections
  • Bind to specific interfaces
  • Disable dangerous commands
redis
# Set passwordCONFIG SET requirepass "your_strong_password"
# AuthenticateAUTH your_strong_password
# Rename dangerous commands (in redis.conf)rename-command FLUSHALL ""rename-command FLUSHDB ""rename-command KEYS ""

Monitoring

redis
# Server infoINFO
# Memory statsINFO memory
# Client connectionsCLIENT LIST
# Slow logSLOWLOG GET 10
# Monitor commands (debug only)MONITOR
# Key count per databaseINFO keyspace

Connection Management

  • Use connection pooling
  • Set appropriate timeouts
  • Handle reconnection gracefully
python
# Python example with connection poolimport 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)

Performance 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
# Pipeline example (pseudo-code)pipe = redis.pipeline()pipe.get("key1")pipe.get("key2")pipe.set("key3", "value")results = pipe.execute()

来源与署名

来源:mindrally/skills位于redis-best-practices提交9718410

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架

Redis Best Practices · redis-best-practices 智能体技能 | SourceWeft