「APIのレスポンスが遅い」「セッション管理をどうすればいい?」「非同期タスクを処理したい」――こうした課題を解決するツールとして、多くの開発者が活用しているのがRedisです。
Redisはインメモリデータストアで、データをメモリ上に保持するため非常に高速に動作します。本記事では、Redisのインストールから基本的なデータ型の操作、実際のアプリケーションでの活用方法まで、初心者向けにわかりやすく解説します。
Redisとは?特徴と主な用途
Redis(Remote Dictionary Server)は、オープンソースのインメモリデータ構造ストアです。2009年にSalvatore Sanfilippo氏によって開発され、現在では世界中の企業で採用されています。
Redisの主な特徴
- 超高速:データをメモリ上に保持するため、読み書きのレイテンシが1ミリ秒以下
- 豊富なデータ構造:文字列、リスト、セット、ハッシュ、ソート済みセットなど多様なデータ型
- 永続化:RDB(スナップショット)とAOF(追記型ログ)によるデータ永続化
- Pub/Sub:パブリッシュ/サブスクライブ型のメッセージング
- TTL(有効期限):キーに有効期限を設定でき、キャッシュに最適
- シングルスレッド:アトミックな操作が保証される
Redisの代表的な用途
Redisは「キーバリューストア」として分類されますが、実際にはさまざまな用途で活用されています。
キャッシュ:データベースクエリの結果やAPIレスポンスをキャッシュし、応答速度を向上させます。最も一般的な用途です。
セッションストア:Webアプリケーションのセッション情報を保存します。複数サーバー間でのセッション共有にも適しています。
メッセージキュー:非同期タスクの処理やマイクロサービス間の通信に使用します。
リアルタイムランキング:ソート済みセットを使って、リーダーボードやランキングを効率的に管理します。
レート制限:APIのリクエスト数を制限し、サービスを保護します。
Redisのインストールと接続
各環境でのインストール
# macOS(Homebrew)
brew install redis
brew services start redis
# Ubuntu/Debian
sudo apt update
sudo apt install redis-server
sudo systemctl start redis-server
sudo systemctl enable redis-server
# Docker(推奨)
docker run --name my-redis \
-p 6379:6379 \
-v redis-data:/data \
-d redis:7-alpine \
redis-server --appendonly yes
redis-cliでの接続と基本操作
# Redisに接続
redis-cli
# リモートサーバーに接続
redis-cli -h hostname -p 6379 -a password
# 接続テスト
127.0.0.1:6379> PING
PONG
# サーバー情報の確認
127.0.0.1:6379> INFO server
# データベースの統計情報
127.0.0.1:6379> INFO keyspace
基本的なデータ型と操作コマンド
Redisは5つの基本的なデータ型を提供します。それぞれの特徴と使い方を見ていきましょう。
String(文字列)
最も基本的なデータ型で、テキスト、数値、バイナリデータなどを保存できます。
# 基本的なセット/ゲット
SET user:1:name "田中太郎"
GET user:1:name
# "田中太郎"
# 有効期限付きのセット(60秒後に自動削除)
SET session:abc123 "{\"user_id\": 1}" EX 60
# SETEX(SET + EXPIREの短縮形)
SETEX cache:homepage 300 "<html>...</html>"
# 存在しない場合のみセット(ロック機構に利用)
SETNX lock:order:123 "processing"
# 数値のインクリメント/デクリメント
SET page:views 0
INCR page:views # 1
INCR page:views # 2
INCRBY page:views 10 # 12
DECR page:views # 11
# 複数キーを一度にセット/ゲット
MSET user:1:name "田中" user:1:email "tanaka@example.com"
MGET user:1:name user:1:email
Hash(ハッシュ)
フィールドと値のペアを持つデータ構造で、オブジェクトの表現に適しています。
# ハッシュにフィールドをセット
HSET user:1 name "田中太郎" email "tanaka@example.com" age 30
# 特定のフィールドを取得
HGET user:1 name
# "田中太郎"
# すべてのフィールドを取得
HGETALL user:1
# 1) "name"
# 2) "田中太郎"
# 3) "email"
# 4) "tanaka@example.com"
# 5) "age"
# 6) "30"
# フィールドの存在確認
HEXISTS user:1 name
# (integer) 1
# 数値フィールドのインクリメント
HINCRBY user:1 age 1
# (integer) 31
# フィールドの削除
HDEL user:1 age
List(リスト)
順序付きの文字列リストで、スタック(LIFO)やキュー(FIFO)として使えます。
# 左側に追加(先頭に挿入)
LPUSH notifications:user:1 "新しいメッセージがあります"
LPUSH notifications:user:1 "注文が確認されました"
# 右側に追加(末尾に追加)
RPUSH queue:emails "email:1" "email:2" "email:3"
# 範囲指定で取得(0始まり、-1は末尾)
LRANGE notifications:user:1 0 -1
# 1) "注文が確認されました"
# 2) "新しいメッセージがあります"
# 左側から取り出し(キュー:FIFO)
LPOP queue:emails
# "email:1"
# 右側から取り出し(スタック:LIFO)
RPOP queue:emails
# リストの長さ
LLEN queue:emails
# ブロッキングポップ(キューが空の場合、タイムアウトまで待機)
BLPOP queue:emails 30
Set(セット)とSorted Set(ソート済みセット)
# Set:重複しないコレクション
SADD tags:post:1 "redis" "database" "cache"
SADD tags:post:2 "redis" "performance" "tutorial"
# メンバーの確認
SMEMBERS tags:post:1
# 1) "redis" 2) "database" 3) "cache"
# 共通のタグ(積集合)
SINTER tags:post:1 tags:post:2
# 1) "redis"
# Sorted Set:スコア付きのセット(ランキングに最適)
ZADD leaderboard 100 "player:1"
ZADD leaderboard 250 "player:2"
ZADD leaderboard 180 "player:3"
ZADD leaderboard 320 "player:4"
# スコアの高い順にトップ3を取得
ZREVRANGE leaderboard 0 2 WITHSCORES
# 1) "player:4" 2) "320"
# 3) "player:2" 4) "250"
# 5) "player:3" 6) "180"
# 特定メンバーの順位を取得(0始まり、高い順)
ZREVRANK leaderboard "player:2"
# (integer) 1
# スコアの加算
ZINCRBY leaderboard 50 "player:1"
# "150"
キャッシュの実装パターン
Redisの最も一般的な用途であるキャッシュの実装パターンを、Node.jsのコード例で解説します。
Cache Aside(キャッシュアサイド)パターン
// Node.js + ioredis
import Redis from 'ioredis';
const redis = new Redis({
host: 'localhost',
port: 6379,
maxRetriesPerRequest: 3,
});
// Cache Asideパターン
async function getProduct(productId: string) {
const cacheKey = `product:${productId}`;
// 1. キャッシュから取得を試みる
const cached = await redis.get(cacheKey);
if (cached) {
console.log('Cache HIT');
return JSON.parse(cached);
}
// 2. キャッシュミス:DBから取得
console.log('Cache MISS');
const product = await db.query(
'SELECT * FROM products WHERE id = $1',
[productId]
);
// 3. キャッシュに保存(TTL: 10分)
if (product) {
await redis.set(cacheKey, JSON.stringify(product), 'EX', 600);
}
return product;
}
// データ更新時にキャッシュを無効化
async function updateProduct(productId: string, data: any) {
await db.query(
'UPDATE products SET name = $1, price = $2 WHERE id = $3',
[data.name, data.price, productId]
);
// キャッシュを削除(次のリクエストで再取得される)
await redis.del(`product:${productId}`);
}
キャッシュの一括無効化(パターンマッチ)
// 特定パターンのキャッシュを一括削除
async function invalidateProductCache() {
let cursor = '0';
do {
const [nextCursor, keys] = await redis.scan(
cursor,
'MATCH', 'product:*',
'COUNT', 100
);
cursor = nextCursor;
if (keys.length > 0) {
await redis.del(...keys);
}
} while (cursor !== '0');
}
キャッシュスタンピード対策
キャッシュの有効期限が切れた瞬間に大量のリクエストがDBに集中する「キャッシュスタンピード」を防ぐ方法です。
// ミューテックスロックを使った対策
async function getProductWithLock(productId: string) {
const cacheKey = `product:${productId}`;
const lockKey = `lock:product:${productId}`;
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// ロックの取得を試みる(10秒のTTL)
const acquired = await redis.set(lockKey, '1', 'EX', 10, 'NX');
if (acquired) {
try {
// ロック取得成功:DBから取得してキャッシュに保存
const product = await db.query(
'SELECT * FROM products WHERE id = $1',
[productId]
);
await redis.set(cacheKey, JSON.stringify(product), 'EX', 600);
return product;
} finally {
await redis.del(lockKey);
}
} else {
// ロック取得失敗:少し待ってからキャッシュを再取得
await new Promise(resolve => setTimeout(resolve, 100));
return getProductWithLock(productId);
}
}
セッション管理の実装
Redisはセッションストアとして広く使われています。Express.jsでの実装例を見てみましょう。
Express.js + connect-redis
import express from 'express';
import session from 'express-session';
import { RedisStore } from 'connect-redis';
import Redis from 'ioredis';
const app = express();
const redis = new Redis();
// セッションストアの設定
app.use(session({
store: new RedisStore({
client: redis,
prefix: 'sess:', // キーのプレフィックス
ttl: 86400, // セッションの有効期間(秒)
}),
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production',
httpOnly: true,
maxAge: 86400000, // クッキーの有効期間(ミリ秒)
sameSite: 'lax',
},
}));
// セッションの利用
app.post('/login', async (req, res) => {
const user = await authenticateUser(req.body.email, req.body.password);
if (user) {
req.session.userId = user.id;
req.session.role = user.role;
res.json({ success: true });
} else {
res.status(401).json({ error: '認証失敗' });
}
});
app.get('/profile', (req, res) => {
if (!req.session.userId) {
return res.status(401).json({ error: 'ログインが必要です' });
}
res.json({ userId: req.session.userId });
});
app.post('/logout', (req, res) => {
req.session.destroy((err) => {
res.json({ success: true });
});
});
メッセージキューの実装
RedisのList型を使って、シンプルなメッセージキューを実装できます。
プロデューサー/コンシューマーパターン
// プロデューサー:ジョブをキューに追加
async function enqueueJob(queueName: string, jobData: any) {
const job = {
id: crypto.randomUUID(),
data: jobData,
createdAt: new Date().toISOString(),
};
await redis.rpush(queueName, JSON.stringify(job));
console.log(`Job ${job.id} enqueued`);
return job.id;
}
// 使用例:メール送信ジョブをキューに追加
await enqueueJob('queue:emails', {
to: 'user@example.com',
subject: '注文確認',
body: 'ご注文ありがとうございます。',
});
// コンシューマー:キューからジョブを取得して処理
async function processJobs(queueName: string) {
console.log(`Waiting for jobs on ${queueName}...`);
while (true) {
// BLPOPで新しいジョブが来るまでブロック(タイムアウト30秒)
const result = await redis.blpop(queueName, 30);
if (result) {
const [, jobJson] = result;
const job = JSON.parse(jobJson);
try {
console.log(`Processing job ${job.id}`);
await sendEmail(job.data);
console.log(`Job ${job.id} completed`);
} catch (error) {
console.error(`Job ${job.id} failed:`, error);
// 失敗したジョブをリトライキューに入れる
await redis.rpush(`${queueName}:failed`, jobJson);
}
}
}
}
// コンシューマーの起動
processJobs('queue:emails');
BullMQを使った本格的なキュー
本番環境では、Redis上に構築されたキューライブラリ「BullMQ」の利用を推奨します。
import { Queue, Worker } from 'bullmq';
const connection = { host: 'localhost', port: 6379 };
// キューの作成
const emailQueue = new Queue('email', { connection });
// ジョブの追加
await emailQueue.add('send-welcome', {
to: 'user@example.com',
template: 'welcome',
}, {
attempts: 3, // 最大リトライ回数
backoff: {
type: 'exponential',
delay: 1000, // 初回リトライまでの待機時間
},
removeOnComplete: 1000, // 完了済みジョブを直近1000件だけ保持
removeOnFail: 5000, // 失敗ジョブを直近5000件保持
});
// ワーカーの作成
const worker = new Worker('email', async (job) => {
console.log(`Processing ${job.name} (${job.id})`);
await sendEmail(job.data);
}, {
connection,
concurrency: 5, // 同時処理数
});
worker.on('completed', (job) => {
console.log(`Job ${job.id} completed`);
});
worker.on('failed', (job, err) => {
console.log(`Job ${job?.id} failed: ${err.message}`);
});
Redisの運用で知っておくべきこと
メモリ管理とEvictionポリシー
Redisはメモリ上にデータを保持するため、メモリ使用量の管理が重要です。
# メモリ上限の設定(redis.conf)
maxmemory 256mb
# Evictionポリシー(メモリ上限に達した時の動作)
maxmemory-policy allkeys-lru
# 主なEvictionポリシー
# noeviction : 書き込みエラーを返す(デフォルト)
# allkeys-lru : すべてのキーからLRUで削除(キャッシュ用途に推奨)
# volatile-lru : TTL付きのキーからLRUで削除
# allkeys-random : ランダムに削除
# volatile-ttl : TTLが短いキーから削除
# メモリ使用量の確認
redis-cli INFO memory
# 特定キーのメモリ使用量
redis-cli MEMORY USAGE user:1
永続化の設定
# RDB(スナップショット)の設定
# 900秒以内に1回以上の変更があればスナップショット作成
save 900 1
# 300秒以内に10回以上の変更があればスナップショット作成
save 300 10
# AOF(Append Only File)の設定
appendonly yes
appendfsync everysec # 毎秒同期(推奨:パフォーマンスと耐久性のバランス)
セキュリティの基本設定
# パスワードの設定(redis.conf)
requirepass your_strong_password
# 危険なコマンドの無効化
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
# 接続時にパスワード認証
redis-cli -a your_strong_password
まとめ
本記事では、Redisの基本から実践的な活用方法まで解説しました。
- 基本データ型:String、Hash、List、Set、Sorted Setの操作方法
- キャッシュ:Cache Asideパターン、キャッシュスタンピード対策
- セッション管理:Express.js + connect-redisでの実装
- メッセージキュー:List型を使ったシンプルなキュー、BullMQを使った本格的なキュー
- 運用:メモリ管理、永続化、セキュリティ設定
Redisは「単なるキャッシュ」にとどまらず、セッション管理、メッセージキュー、リアルタイムランキングなど、さまざまな場面で活躍する万能ツールです。まずはDockerでRedisを起動し、redis-cliでコマンドを試してみるところから始めてみてください。
関連記事
AIエージェント開発入門|自律型AIの仕組みと構築方法を解説【2026年版】
AI駆動コーディングワークフロー|Claude Code・Cursor・Copilotの実践的使い分け
プロンプトエンジニアリング上級編|Chain-of-Thought・Few-Shot・ReActの実践
APIレート制限の設計と実装|トークンバケット・スライディングウィンドウ解説
APIバージョニング戦略|URL・ヘッダー・クエリパラメータの使い分け
BIツール入門|Metabase・Redash・Looker Studioでデータ可視化する方法
チャットボット開発入門|LINE Bot・Slack Botの構築方法と活用事例
CI/CDパイプラインの基礎|継続的インテグレーション・デリバリーの全体像