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 從公開儲存庫中收錄這些內容。

檢舉或申請下架