redis-best-practices
mindrally/skills
キャッシュ、データ構造、および高性能なキーバリュー操作に関するRedis開発のベストプラクティス
...すべて拡張します概要redis-best-practices
「Redis ベストプラクティス」スキルは、Redis をインメモリデータストアとして効果的に活用するための包括的なガイダンスを提供します。キャッシュ、セッションストレージ、リアルタイム分析、メッセージキューイングにおける最適なパターンを網羅するとともに、開発者がよくある落とし穴やパフォーマンス上の問題を回避できるよう支援します。 このスキルでは、適切なデータ構造の選択、キーの命名規則、およびスケーラビリティと保守性を確保するためのアーキテクチャパターンを解説することで、Redisの潜在能力を最大限に引き出すという課題に取り組んでいます。
本スキルでは、Redisの5つの主要なデータ構造(文字列、ハッシュ、リスト、セット、ソート済みセット)に加え、イベント処理のための新しい機能であるストリームに焦点を当てています。各構造について実践的なコード例を提供し、アトミック操作、バッチコマンド、ブロッキング操作をいつ、どのように使用すべきかを実演します。 主なトピックには、効率的なキャッシュ・アサイド・パターンの実装、ソートセットを用いたリーダーボードの設計、リストを用いたメッセージキューの構築、およびコンシューマーグループを用いた分散イベント処理の処理が含まれます。このガイドでは、メモリ効率、適切な有効期限ポリシー、およびRedisアプリケーションのデバッグとスケーリングを容易にする一貫性のある命名パターンを重視しています。
このスキルは、高速なデータアクセスを必要とする高性能アプリケーションを扱うバックエンド開発者、キャッシュ層を設計するDevOpsエンジニア、およびリアルタイムシステムを構築するアーキテクトに最適です。 セッション管理の実装、レートリミッターの構築、アクティビティフィードの作成、分散タスクキューの設計など、どのような場面においても、このスキルでは本番環境のシステムに直接適用できる、実戦で実証済みのパターンと具体的な例を提供します。
よくある質問
リーダーボードにはどのデータ構造を使用すべきですか?
スコアがプレイヤーの順位を表す場合は、ソート済みセット(ZADD、ZREVRANGE)を使用してください。ソート済みセットは自動的に順序を維持し、効率的な順位クエリやスコアに基づく範囲操作をサポートします。
適切なキャッシュの有効期限をどのように実装すればよいですか?
SET コマンドの EX パラメータを使用して有効期限を設定するか、SETEX を使用してください。データの変動性に基づいて TTL 値を選択します。頻繁に変化するデータには短い値(数秒から数分)、静的なコンテンツには長い値(数時間から数日)を設定します。
複数の文字列キーの代わりにハッシュを使用すべき場合はいつですか?
複数のフィールドを持つオブジェクトを格納する場合は、ハッシュを使用します。ハッシュは、フィールドごとに個別の文字列キーを作成するよりもメモリ効率が高く、オブジェクト全体を取得することなく部分的な更新を行うことができます。
キューにおける RPOP と BRPOP の違いは何ですか?
RPOPは、リストが空の場合はnullを返し、それ以外の場合は値を即座に返します。BRPOPは、アイテムが利用可能になるまで指定されたタイムアウト時間まで待機するブロッキング操作であるため、新しいタスクを効率的に待機する必要があるワーカープロセスに最適です。
Redis Streams を使用した分散処理はどのように行えばよいですか?
XGROUP CREATE および XREADGROUP を使用してコンシューマーグループを利用します。複数のコンシューマーがメッセージを並行して処理でき、Redis は各コンシューマーがどのメッセージを受信したかを追跡します。処理の成功を通知するには XACK を使用します。
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:1234Data Structures
Strings
- Use for simple key-value storage, counters, and caching
- Consider using MGET/MSET for batch operations
# 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 30Hashes
- Use for objects with multiple fields
- More memory-efficient than multiple string keys
- Supports partial updates
# 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:1234Lists
- Use for queues, recent items, and activity feeds
- Consider blocking operations for queue consumers
# 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 9Sets
- Use for unique collections, tags, and relationships
- Supports set operations (union, intersection, difference)
# 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:usersSorted Sets
- Use for leaderboards, priority queues, and time-series data
- Elements sorted by score
# 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 1705333200Streams
- Use for event streaming and log data
- Supports consumer groups for distributed processing
# 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-0Caching Patterns
Cache-Aside Pattern
# 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
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
# 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 keyExpiration and Memory Management
TTL Best Practices
- Always set TTL on cache keys
- Use jitter to prevent thundering herd
- Consider sliding expiration for session data
# 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:123Memory Management
# Check memory usageINFO memory# Get key memory usageMEMORY USAGE cache:large:object# Configure max memory policyCONFIG SET maxmemory 2gbCONFIG SET maxmemory-policy allkeys-lruTransactions and Atomicity
MULTI/EXEC Transactions
# 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)EXECLua Scripts
- Use for complex atomic operations
- Scripts execute atomically
-- 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 0endredis.call('INCR', key)if current == 0 then redis.call('EXPIRE', key, window)endreturn 1
# Execute Lua scriptEVAL "return redis.call('GET', KEYS[1])" 1 mykeyPub/Sub and Messaging
# 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
# On replicaREPLICAOF master_host 6379# Check replication statusINFO replicationRedis 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
# Hash tags ensure keys go to same slotSET {user:1234}:profile "data"SET {user:1234}:settings "data"Persistence
RDB Snapshots
# Manual snapshotBGSAVE# Configure automatic snapshotsCONFIG SET save "900 1 300 10 60 10000"AOF (Append-Only File)
# Enable AOFCONFIG SET appendonly yesCONFIG SET appendfsync everysec# Rewrite AOFBGREWRITEAOFSecurity
- Require authentication
- Use TLS for connections
- Bind to specific interfaces
- Disable dangerous commands
# 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
# Server infoINFO# Memory statsINFO memory# Client connectionsCLIENT LIST# Slow logSLOWLOG GET 10# Monitor commands (debug only)MONITOR# Key count per databaseINFO keyspaceConnection Management
- Use connection pooling
- Set appropriate timeouts
- Handle reconnection gracefully
# Python example with connection poolimport redispool = 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
# Pipeline example (pseudo-code)pipe = redis.pipeline()pipe.get("key1")pipe.get("key2")pipe.set("key3", "value")results = pipe.execute() redis-best-practicesをインストール
スキルファイルをダウンロードし、.claude/skills/ ディレクトリに解凍してください。
ZIPをダウンロードリポジトリをクローンし、スキルファイルをプロジェクトにコピーしてください。
git clone https://github.com/Mindrally/skills/blob/main/redis-best-practices/SKILL.md # Copy SKILL.md to your .claude/skills/ directory
コピー





家
