redis-best-practices について
redis-best-practices は、Redis を使うアプリケーションの開発・運用向けガイドです。データ構造、キャッシュ、信頼性、セキュリティ、性能をコマンド例とともに扱います。
主な機能
- 01Redis データ構造の選択指針
- 02キー命名と有効期限の方針
- 03キャッシュと無効化のパターン
- 04トランザクションと原子操作
- 05高可用性、永続化、セキュリティ
- 06監視と性能改善の実践
活用シーン
- 01キューやランキング向け構造の選定
- 02キャッシュ TTL と無効化の設計
- 03Redis のレプリケーションと永続化の計画
- 04Redis のメモリと接続設定の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
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
キャッシュパターン
キャッシュ・アサイドパターン
# 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
ライトスルーパターン
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
Pub/Sub とメッセージング
# 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
- 自動フェイルオーバーに使用します
- Sentinel インスタンスを少なくとも 3 つデプロイします
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)
パフォーマンスのヒント
- 一括操作にはパイプラインを使用します
- 大きなキー(値が 100KB を超えるもの)は避けます
- 本番環境では KEYS の代わりに SCAN を使用します
- メモリ使用量を監視し、最適化します
- 複雑な JSON 操作には RedisJSON の使用を検討します
# Pipeline example (pseudo-code)
pipe = redis.pipeline()
pipe.get("key1")
pipe.get("key2")
pipe.set("key3", "value")
results = pipe.execute()
コメント
Markdown 対応