Redis
高性能なインメモリキーバリューストア。データ構造サーバー、キャッシュ、メッセージブローカーとして機能。豊富なデータ型とAtomic操作をサポート。
Redis
Redisは、高性能なインメモリデータ構造ストアです。キャッシュ、データベース、メッセージブローカーとして使用され、豊富なデータ型とアトミック操作をサポートしています。
主な特徴
豊富なデータ構造
- String: 基本的な文字列、数値、バイナリデータ
- Hash: オブジェクトの表現に適したフィールド-値マップ
- List: 順序付きリスト、キューやスタックとして利用
- Set: 重複のない文字列集合
- Sorted Set: スコア付き順序集合
- Stream: ログライクなデータ構造
- Bitmap: ビット操作対応
- HyperLogLog: 近似カーディナリティ計算
パフォーマンス特性
- インメモリ処理による超高速アクセス
- 単一スレッドアーキテクチャによる一貫性保証
- パイプライニングによる大量操作の効率化
- 非同期レプリケーション
拡張機能
- 永続化(RDB、AOF)
- Master-Slave レプリケーション
- Redis Cluster による自動シャーディング
- Pub/Sub メッセージング
- Lua スクリプト実行
- Redis Modules による機能拡張
インストール
Ubuntu/Debian
# 公式リポジトリからインストール
sudo apt update
sudo apt install redis-server
# または最新版のインストール
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
CentOS/RHEL
# EPEL リポジトリの有効化
sudo dnf install epel-release
sudo dnf install redis
# または公式リポジトリから
sudo dnf install https://packages.redis.io/rpm/el9/x86_64/redis-8.0-1.el9.x86_64.rpm
Docker
# Redis 8.0の起動
docker run --name redis-cache \
-p 6379:6379 \
-d redis:8.0-alpine
# 設定ファイルとデータ永続化
docker run --name redis-cache \
-v redis_data:/data \
-v /path/to/redis.conf:/usr/local/etc/redis/redis.conf \
-p 6379:6379 \
-d redis:8.0-alpine redis-server /usr/local/etc/redis/redis.conf
ソースからのビルド
# 必要な依存関係
sudo apt-get install build-essential tcl
# Redis のダウンロードとビルド
wget https://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
make test
sudo make install
基本設定
redis.conf
# ネットワーク設定
bind 127.0.0.1 ::1
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
# 一般設定
daemonize yes
pidfile /var/run/redis/redis-server.pid
loglevel notice
logfile /var/log/redis/redis-server.log
# スナップショット設定
dir /var/lib/redis
dbfilename dump.rdb
save 60 1000
save 300 100
save 900 1
# AOF設定
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# メモリ設定
maxmemory 256mb
maxmemory-policy allkeys-lru
# セキュリティ
requirepass your_password_here
# rename-command FLUSHDB ""
# rename-command FLUSHALL ""
# レプリケーション設定
# replicaof <masterip> <masterport>
# masterauth <master-password>
# クライアント設定
maxclients 10000
基本操作
文字列操作
# 基本的なSet/Get
SET user:1000:name "John Doe"
GET user:1000:name
MSET user:1001:name "Jane Doe" user:1001:email "[email protected]"
MGET user:1001:name user:1001:email
# 数値操作
SET counter 10
INCR counter
INCRBY counter 5
DECR counter
DECRBY counter 2
# 期限付きキー
SETEX session:abc123 3600 "user_data"
SET temp_key "value" EX 300
TTL session:abc123
EXPIRE temp_key 600
ハッシュ操作
# ハッシュフィールドの設定
HSET user:1000 name "John Doe" email "[email protected]" age 30
HGET user:1000 name
HMGET user:1000 name email
HGETALL user:1000
# ハッシュ操作
HINCRBY user:1000 age 1
HEXISTS user:1000 email
HDEL user:1000 age
HKEYS user:1000
HVALS user:1000
リスト操作
# リストへの追加
LPUSH tasks "task1" "task2" "task3"
RPUSH queue "item1" "item2"
# リストからの取得
LPOP tasks
RPOP queue
LRANGE tasks 0 -1
LLEN tasks
# ブロッキング操作
BLPOP tasks 30
BRPOP queue 30
# リスト間の移動
RPOPLPUSH source destination
セット操作
# セットへの追加
SADD tags "redis" "cache" "database"
SMEMBERS tags
SISMEMBER tags "redis"
# セット演算
SADD set1 "a" "b" "c"
SADD set2 "b" "c" "d"
SINTER set1 set2
SUNION set1 set2
SDIFF set1 set2
# ランダム要素取得
SRANDMEMBER tags 2
SPOP tags
ソートセット操作
# スコア付きでメンバー追加
ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
ZRANGE leaderboard 0 -1 WITHSCORES
ZREVRANGE leaderboard 0 2 WITHSCORES
# スコア操作
ZINCRBY leaderboard 50 "player1"
ZSCORE leaderboard "player1"
ZRANK leaderboard "player1"
# 範囲クエリ
ZRANGEBYSCORE leaderboard 100 200
ZCOUNT leaderboard 100 200
ZREMRANGEBYSCORE leaderboard 0 99
高度な機能
Pub/Sub メッセージング
# パブリッシャー
PUBLISH news:tech "Redis 8.0 released!"
PUBLISH news:sports "World Cup final tonight"
# サブスクライバー
SUBSCRIBE news:tech news:sports
PSUBSCRIBE news:*
# チャンネル情報
PUBSUB CHANNELS
PUBSUB NUMSUB news:tech
PUBSUB NUMPAT
Redis Streams
# ストリームへのエントリ追加
XADD events * user "john" action "login" timestamp "2024-01-15T10:00:00Z"
XADD events * user "jane" action "logout" timestamp "2024-01-15T10:05:00Z"
# ストリーム読み取り
XRANGE events - +
XREAD COUNT 10 STREAMS events 0
# コンシューマーグループ
XGROUP CREATE events mygroup 0
XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS events >
XACK events mygroup 1642234567890-0
# ストリーム情報
XINFO STREAM events
XLEN events
Lua スクリプト
-- アトミックなインクリメント(Lua スクリプト)
local current = redis.call('GET', KEYS[1])
if current == false then
current = 0
else
current = tonumber(current)
end
current = current + tonumber(ARGV[1])
redis.call('SET', KEYS[1], current)
redis.call('EXPIRE', KEYS[1], ARGV[2])
return current
# スクリプトの実行
EVAL "local current = redis.call('GET', KEYS[1]); if current == false then current = 0 else current = tonumber(current) end; current = current + tonumber(ARGV[1]); redis.call('SET', KEYS[1], current); redis.call('EXPIRE', KEYS[1], ARGV[2]); return current" 1 counter 10 3600
# スクリプトの登録と実行
SCRIPT LOAD "script_content"
EVALSHA sha1_hash 1 counter 5 1800
クラスタリング
Redis Cluster設定
# 各ノードの設定 (redis.conf)
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
# クラスタ作成
redis-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1
# ノード追加
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
# スロット再分散
redis-cli --cluster reshard 127.0.0.1:7000
Redis Cluster操作
# クラスタ情報
CLUSTER INFO
CLUSTER NODES
CLUSTER SLOTS
# キーのスロット確認
CLUSTER KEYSLOT mykey
# ノード管理
CLUSTER MEET 127.0.0.1 7006
CLUSTER FORGET node_id
CLUSTER REPLICATE master_node_id
# 手動フェイルオーバー
CLUSTER FAILOVER
レプリケーション
Master-Slave設定
# Master設定 (redis.conf)
bind 0.0.0.0
port 6379
requirepass master_password
# Slave設定 (redis.conf)
replicaof master_ip 6379
masterauth master_password
replica-read-only yes
replica-serve-stale-data yes
レプリケーション操作
# レプリケーション情報
INFO replication
# スレーブの昇格
SLAVEOF NO ONE
# レプリケーション同期
PSYNC replication_id offset
パフォーマンス最適化
メモリ最適化
# メモリ使用量確認
INFO memory
MEMORY USAGE key_name
# メモリ統計
MEMORY STATS
# ガベージコレクション強制実行
DEBUG OBJECT key_name
パフォーマンス監視
# 操作ごとの統計
INFO stats
INFO commandstats
# スローログ確認
SLOWLOG GET 10
SLOWLOG LEN
SLOWLOG RESET
# リアルタイム監視
MONITOR
# レイテンシ監視
LATENCY LATEST
LATENCY HISTORY command
パイプライニング
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
# パイプライニングの使用
pipe = r.pipeline()
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.get('key1')
pipe.get('key2')
results = pipe.execute()
セキュリティ
認証設定
# パスワード認証
requirepass your_strong_password
# ACL (Redis 6.0+)
# ユーザー作成
ACL SETUSER alice on >alice_password ~* &* +@all
# 権限確認
ACL LIST
ACL WHOAMI
ACL CAT
ネットワークセキュリティ
# バインドアドレス制限
bind 127.0.0.1 192.168.1.100
# protected mode
protected-mode yes
# 危険なコマンドの無効化
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command EVAL ""
rename-command DEBUG ""
監視とメンテナンス
基本監視
# サーバー情報
INFO server
INFO clients
INFO memory
INFO persistence
INFO stats
# 接続中のクライアント
CLIENT LIST
CLIENT INFO
# キーの分析
SCAN 0 MATCH pattern* COUNT 1000
TYPE keyname
EXISTS key1 key2 key3
データベース管理
# データベース選択
SELECT 1
# データベースサイズ
DBSIZE
# キーの一括削除
FLUSHDB
FLUSHALL
# バックグラウンド保存
BGSAVE
BGREWRITEAOF
# 設定の動的変更
CONFIG GET maxmemory
CONFIG SET maxmemory 512mb
CONFIG REWRITE
トラブルシューティング
# ログファイル確認
tail -f /var/log/redis/redis-server.log
# プロセス確認
ps aux | grep redis
# ネットワーク接続確認
netstat -tlnp | grep 6379
# Redis CLI接続テスト
redis-cli ping
redis-cli --latency
redis-cli --stat
実用例
セッション管理
# セッションデータの保存
HSET session:user123 name "John Doe" email "[email protected]" last_activity "2024-01-15T10:00:00Z"
EXPIRE session:user123 1800
# セッション確認
HGETALL session:user123
TTL session:user123
分散ロック
# ロック取得 (NX: 存在しない場合のみ設定, EX: 期限秒数)
SET lock:resource:123 "process_id" NX EX 30
# ロック解放 (Luaスクリプトでアトミックに)
EVAL "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end" 1 lock:resource:123 process_id
カウンター・レート制限
# APIレート制限 (sliding window)
EVAL "local key = KEYS[1]; local window = tonumber(ARGV[1]); local limit = tonumber(ARGV[2]); local current = redis.call('INCR', key); if current == 1 then redis.call('EXPIRE', key, window) end; return current <= limit" 1 rate:api:user123 60 100
Redisは、その柔軟性と高性能により、キャッシング、セッション管理、リアルタイム分析、メッセージキューなど、様々な用途で活用されています。豊富なデータ構造とアトミック操作により、複雑なアプリケーション要件にも対応できます。