Redis はインメモリのキーと値のストアで、豊富なデータ構造をサポートしています。キャッシュ、メッセージキュー、分散ロック、ランキングなど様々な用途で活用されます。本文はインストールから始まり、すべてのコアデータタイプと実践的な使い方を網羅します。
インストールと接続
macOS
brew install redis
brew services start redis # バックグラウンドで起動
redis-cli # 対話式クライアントを開く
Linux(Ubuntu / Debian)
sudo apt update && sudo apt install redis-server
sudo systemctl start redis
redis-cli
Docker(推奨、クリーンな環境)
# コンテナを起動
docker run -d --name redis -p 6379:6379 redis:7-alpine
# CLI を開く
docker exec -it redis redis-cli
基本的な接続と確認
redis-cli -h 127.0.0.1 -p 6379
# 疎通確認
PING # PONG が返ってくる
# パスワードが設定されている場合
AUTH your_password
# データベースを選択(デフォルト 0、合計 16 個)
SELECT 1
# 現在のデータベースの key 数を確認
DBSIZE
# すべての key を取得(本番環境では避けること)
KEYS *
# パターン検索(本番では KEYS の代わりに SCAN を推奨)
SCAN 0 MATCH user:* COUNT 100
データ型一覧
| 型 | 主な用途 |
|---|---|
| String | キャッシュ、カウンター、分散ロック |
| Hash | オブジェクト保存(ユーザー情報、商品詳細) |
| List | メッセージキュー、アクティビティフィード |
| Set | 重複排除、共通の友人、抽選 |
| ZSet(ソート済み集合) | ランキング、重み付きキュー |
| Stream | 永続メッセージキュー(軽量 Kafka 代替) |
| Bitmap | ユーザー出席管理、ブルームフィルター |
| HyperLogLog | 大規模 UV 推計(近似値) |
String(文字列)
String は最も基本的な型で、テキスト・数値・バイナリを保存できます(最大 512 MB)。
# 保存と取得
SET name "Alice"
GET name # "Alice"
# 有効期限付きで保存(秒)
SET token "abc123" EX 3600
# キーが存在しない場合のみ設定(分散ロックの基礎)
SET lock "1" NX EX 10
# 一括操作
MSET k1 v1 k2 v2 k3 v3
MGET k1 k2 k3
# 値に追記
APPEND name " Smith" # "Alice Smith"
# 数値操作
SET counter 0
INCR counter # 1
INCRBY counter 5 # 6
DECR counter # 5
DECRBY counter 2 # 3
# 浮動小数点の加算
SET price 9.99
INCRBYFLOAT price 0.5 # 10.49
# 文字列の長さを取得
STRLEN name
# 旧値を取得し新値を設定
GETSET name "Bob" # "Alice Smith" を返し、"Bob" を設定
Hash(ハッシュ)
Hash は構造化されたオブジェクトの保存に適しており、シリアライズ/デシリアライズを繰り返す必要がありません。
# フィールドを設定
HSET user:1 name "Alice" age 25 email "alice@example.com"
# 単一フィールドを取得
HGET user:1 name # "Alice"
# すべてのフィールドと値を取得
HGETALL user:1
# すべてのフィールド名を取得
HKEYS user:1
# すべての値を取得
HVALS user:1
# フィールド数を取得
HLEN user:1
# フィールドの存在確認
HEXISTS user:1 email # 1(存在する)
# フィールドを削除
HDEL user:1 email
# 複数フィールドを一度に取得
HMGET user:1 name age
# 数値フィールドを加算
HINCRBY user:1 age 1
# フィールドが存在しない場合のみ設定
HSETNX user:1 role "admin"
List(リスト)
List は双方向リンクリストです。両端からの push/pop をサポートし、キューやスタックに最適です。
# 左端に追加(先頭)
LPUSH logs "event1" "event2" "event3"
# 右端に追加(末尾)
RPUSH queue "task1" "task2"
# 左端から取り出す
LPOP logs
# 右端から取り出す
RPOP queue
# ブロッキング取り出し(0 = 永久に待機)
BLPOP queue 0
BRPOP queue 30 # 最大 30 秒待機
# 範囲を確認(0 -1 = すべて)
LRANGE logs 0 -1
# インデックスで取得
LINDEX logs 0
# リストの長さ
LLEN logs
# トリム(先頭 100 件だけ残す)
LTRIM logs 0 99
# 要素の前後に挿入
LINSERT logs BEFORE "event2" "new-event"
# 一致する要素を削除
LREM logs 2 "event1" # "event1" を 2 件削除
典型的な使い方:メッセージキュー
# プロデューサー
RPUSH queue "msg1"
# コンシューマー(ブロッキング — メッセージが来たらすぐ返す)
BLPOP queue 0
Set(集合)
Set は順序なしの重複しない集合で、集合演算をサポートします。
# メンバーを追加
SADD tags "redis" "cache" "nosql"
# 存在確認
SISMEMBER tags "redis" # 1
# すべてのメンバーを取得
SMEMBERS tags
# 集合のサイズ
SCARD tags
# メンバーを削除
SREM tags "nosql"
# ランダムに取得(削除しない)
SRANDMEMBER tags 2
# ランダムに取り出して削除
SPOP tags
# 集合演算
SADD set1 "a" "b" "c"
SADD set2 "b" "c" "d"
SUNION set1 set2 # 和集合:a b c d
SINTER set1 set2 # 積集合:b c
SDIFF set1 set2 # 差集合:a(set1 にあり set2 にない)
# 結果を新しい key に保存
SUNIONSTORE result set1 set2
SINTERSTORE result set1 set2
ZSet(ソート済み集合)
ZSet の各メンバーにはスコアがあり、スコア順に並びます。ランキングに最適です。
# メンバーを追加(スコア メンバー名)
ZADD leaderboard 1000 "Alice" 850 "Bob" 1200 "Charlie"
# メンバーのスコアを取得
ZSCORE leaderboard "Alice" # 1000
# スコア昇順のランクを取得(0 = 1位)
ZRANK leaderboard "Alice" # 1(0-indexed)
# スコア降順のランクを取得
ZREVRANK leaderboard "Alice" # 1
# ランク範囲で取得(昇順)
ZRANGE leaderboard 0 -1 WITHSCORES
# ランク範囲で取得(降順)
ZREVRANGE leaderboard 0 2 WITHSCORES
# スコア範囲で取得
ZRANGEBYSCORE leaderboard 800 1100 WITHSCORES
# スコアを加算
ZINCRBY leaderboard 100 "Alice" # 1100
# メンバー総数
ZCARD leaderboard
# スコア範囲内のメンバー数
ZCOUNT leaderboard 900 1200
# メンバーを削除
ZREM leaderboard "Bob"
# ランク範囲で削除
ZREMRANGEBYRANK leaderboard 0 1
# スコア範囲で削除
ZREMRANGEBYSCORE leaderboard 0 800
有効期限
# 秒単位で有効期限を設定
EXPIRE key 3600
# ミリ秒単位で設定
PEXPIRE key 3600000
# Unix タイムスタンプ(秒)で設定
EXPIREAT key 1893456000
# 残り TTL を確認(秒、-1=期限なし、-2=key なし)
TTL key
# 残り TTL を確認(ミリ秒)
PTTL key
# 有効期限を削除(永続化)
PERSIST key
永続化
Redis はデフォルトでインメモリです。再起動するとデータが失われます。永続化方法は2つあります:
RDB(スナップショット)
定期的にメモリをディスクに書き込みます。デフォルトの永続化方式です。
# redis.conf(60 秒ごとに 1 件以上の変更があれば保存)
save 60 1
save 300 10
save 900 1
# 手動でトリガー
BGSAVE # 非同期バックグラウンド保存
SAVE # 同期(ブロッキング — 本番環境では避けること)
メリット:ファイルがコンパクトで復元が速い。
デメリット:2回のスナップショット間のデータが失われる可能性がある。
AOF(追記ログ)
すべての書き込みコマンドを記録し、再起動時に再生してデータを復元します。
# redis.conf
appendonly yes
appendfilename "appendonly.aof"
# 同期ポリシー
appendfsync always # 毎回同期 — 最も安全、最も遅い
appendfsync everysec # 毎秒同期(推奨 — 最大 1 秒のデータ損失)
appendfsync no # OS に任せる — 最速だがリスクが高い
メリット:安全性が高く、最大 1 秒のデータ損失。
デメリット:ファイルが大きく、復元が遅い。
ハイブリッド永続化(推奨 — Redis 4.0+)
# redis.conf
aof-use-rdb-preamble yes
AOF ファイルの先頭に RDB スナップショットを含め、その後に増分コマンドを追記します。速度と安全性を両立できます。
パブリッシュ / サブスクライブ
# チャンネルをサブスクライブ(メッセージを待ってブロック)
SUBSCRIBE news sports
# メッセージをパブリッシュ
PUBLISH news "Breaking: Redis 8.0 released"
# パターンサブスクライブ
PSUBSCRIBE news.*
# サブスクライブ情報を確認
PUBSUB CHANNELS # アクティブなチャンネル一覧
PUBSUB NUMSUB news # チャンネルのサブスクライバー数
注意:Pub/Sub はファイア・アンド・フォゲットで永続化なし。信頼性の高いメッセージングには Stream か外部 MQ を推奨。
トランザクション
Redis のトランザクションは MULTI / EXEC でコマンドを原子的に実行します(ただし実行時エラーのロールバックはない)。
MULTI # トランザクション開始
SET k1 "v1" # キューに追加
SET k2 "v2"
INCR counter
EXEC # キューのコマンドをすべて実行
# トランザクションを破棄
DISCARD
WATCH(楽観的ロック):
WATCH balance # キーを監視
MULTI
DECRBY balance 100
EXEC # WATCH 後に balance が変更されていたら nil を返す
Pipeline(バッチリクエスト)
Pipeline は複数のコマンドを1回のネットワーク往復にまとめ、スループットを大幅に向上させます。
# redis-cli の例
redis-cli --pipe << EOF
SET k1 v1
SET k2 v2
INCR counter
EOF
主要クライアントライブラリはすべて Pipeline をサポートしています。Node.js(ioredis)の例:
const pipeline = redis.pipeline()
pipeline.set('k1', 'v1')
pipeline.set('k2', 'v2')
pipeline.incr('counter')
await pipeline.exec()
主な使用シナリオ
キャッシュ
# キャッシュアサイドパターン:
# 読み取り:Redis を確認 → ミスならDBを照会してRedisに書き込み
# 書き込み:先にDBを更新 → Redisキャッシュを削除(整合性を保証)
SET user:1:profile "{...}" EX 300
分散ロック
# ロック取得:NX で1クライアントのみ成功保証、EX でデッドロック防止
SET lock:order:123 "client-uuid" 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:order:123 client-uuid
レート制限
# ユーザーごとに1分間最大100リクエスト
INCR rate:user:123
EXPIRE rate:user:123 60
# 原子的な初期化
SET rate:user:123 0 EX 60 NX # 初回リクエスト時に初期化
INCR rate:user:123 # リクエストごとに加算
ランキング
# スコアを更新
ZINCRBY leaderboard 10 "user:123"
# Top 10 を取得
ZREVRANGE leaderboard 0 9 WITHSCORES
# ユーザーのランクを確認
ZREVRANK leaderboard "user:123"
セッション管理
SET session:abc123 "{userId: 1, role: admin}" EX 86400
GET session:abc123
EXPIRE session:abc123 86400 # セッションを更新
キャッシュの3大障害
キャッシュ貫通(Cache Penetration)
症状: キャッシュにもDBにも存在しないキーへのリクエストが常にDBを直撃する。
対策:
- null をキャッシュ:DBに存在しなくても短いTTLで空の値をRedisに保存する
- ブルームフィルター:存在しない可能性があるリクエストをRedisに届く前に拒否する
キャッシュ崩壊(Cache Breakdown)
症状: ホットキーが期限切れになった瞬間、大量のリクエストが一斉にDBを直撃する。
対策:
- ホットキーを期限なし(または論理的期限切れ + 非同期更新)にする
- ミューテックスロック:最初のリクエストだけがキャッシュを再構築し、他は待機する
キャッシュ雪崩(Cache Avalanche)
症状: 大量のキーが同時に期限切れになり、DBが一瞬で圧倒される。
対策:
- TTL にランダムなジッターを追加して期限切れを分散させる
- クリティカルなデータは期限なしで非同期バックグラウンド更新
- サーキットブレーカーとグレースフルデグラデーションでDBを保護する
よく使う管理コマンド
# Redis の情報を確認(メモリ、接続、永続化など)
INFO
INFO memory
INFO server
# スロークエリログを確認
SLOWLOG GET 10
# 現在のデータベースをクリア(注意して使用)
FLUSHDB
# すべてのデータベースをクリア(注意して使用)
FLUSHALL
# キーの型を確認
TYPE key
# キーを削除
DEL key1 key2
# 非同期削除(大きな key に推奨、ブロッキングなし)
UNLINK key
# キーの名前を変更
RENAME old-key new-key
# キーのメモリ使用量を確認
MEMORY USAGE key
Fonnpo