データベース
Redis
概要
Redisは、高速なインメモリデータ構造ストアです。キーバリューストア、キャッシュ、メッセージブローカーとして使用され、リアルタイムデータ駆動アプリケーションのために設計されています。「Remote Dictionary Server」の略で、優れたパフォーマンスと豊富なデータ型サポートで知られています。
詳細
Redisは2009年にSalvatore Sanfilippo氏によって開発されました。全てのデータをメモリ上に保持することで、極めて高速な読み書きを実現しています。単純なキーバリューストアを超えて、リスト、セット、ハッシュ、ストリームなど多様なデータ構造をサポートしています。
Redisの主な特徴:
- インメモリデータストレージ
- 豊富なデータ構造(文字列、リスト、セット、ハッシュ、ストリーム等)
- 永続化機能(RDB/AOF)
- レプリケーション
- 高可用性(Redis Sentinel)
- クラスタリング
- Pub/Subメッセージング
- Lua スクリプト実行
- トランザクション
- 地理空間データサポート
メリット・デメリット
メリット
- 超高速: メモリベースで極めて高いパフォーマンス
- 多用途: キャッシュ、データベース、メッセージブローカーとして活用
- 豊富なデータ型: 様々なデータ構造の直接サポート
- 軽量: シンプルで軽量な設計
- スケーラビリティ: レプリケーションとクラスタリング対応
- エコシステム: 豊富なクライアントライブラリとツール
- オープンソース: BSD ライセンスで無料使用可能
デメリット
- メモリ制限: 利用可能メモリがデータサイズの制限となる
- 永続化: メモリベースのため適切な永続化設定が必要
- 単一スレッド: 基本的に単一スレッドでのコマンド処理
- 複雑なクエリ: SQLライクな複雑なクエリは制限される
- データ型制限: リレーショナルなデータモデリングには制約
主要リンク
書き方の例
インストール・セットアップ
# Ubuntu/Debian
sudo apt update
sudo apt install redis-server
# Red Hat/CentOS
sudo yum install epel-release
sudo yum install redis
# macOS (Homebrew)
brew install redis
# Docker
docker run --name redis-db -p 6379:6379 -d redis:latest
# Redis起動
sudo systemctl start redis
sudo systemctl enable redis
# Redisクライアント接続
redis-cli
基本操作(CRUD)
# 文字列操作
SET user:1:name "田中太郎"
GET user:1:name
SET user:1:age 30
INCR user:1:age
EXPIRE user:1:name 3600 # 1時間後に削除
# 複数キーの操作
MSET user:1:email "[email protected]" user:1:city "東京"
MGET user:1:name user:1:email user:1:city
# キー管理
KEYS user:*
EXISTS user:1:name
DEL user:1:name
TTL user:1:email # 残り有効期限確認
データ構造操作
# リスト操作
LPUSH shopping:list "牛乳" "パン" "卵"
RPUSH shopping:list "りんご"
LRANGE shopping:list 0 -1
LPOP shopping:list
LLEN shopping:list
# セット操作
SADD tags:user:1 "engineer" "javascript" "nodejs"
SMEMBERS tags:user:1
SISMEMBER tags:user:1 "javascript"
SCARD tags:user:1
# ハッシュ操作
HSET user:1 name "田中太郎" age 30 email "[email protected]"
HGET user:1 name
HGETALL user:1
HINCRBY user:1 age 1
HDEL user:1 email
# ソートセット操作
ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
ZRANGE leaderboard 0 -1 WITHSCORES
ZREVRANGE leaderboard 0 2 WITHSCORES # 上位3位
ZRANK leaderboard "player1"
インデックス・最適化
# メモリ使用量確認
INFO memory
MEMORY USAGE user:1
# キー数確認
DBSIZE
# ベンチマーク
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
# ログレベル設定
CONFIG SET loglevel notice
# パフォーマンス設定
CONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru
実用例
# セッション管理
SETEX session:abc123 1800 '{"userId": 1, "username": "tanaka"}'
GET session:abc123
# カウンター
INCR page:views:home
INCRBY api:calls:today 1
GET page:views:home
# Pub/Sub メッセージング
# 購読者
SUBSCRIBE notifications user:updates
# 発行者(別接続で)
PUBLISH notifications "新しいメッセージが届きました"
PUBLISH user:updates "ユーザー情報が更新されました"
# 地理空間データ
GEOADD cities 139.6917 35.6895 "東京" 135.5023 34.6937 "大阪"
GEODIST cities "東京" "大阪" km
GEORADIUS cities 139.6917 35.6895 100 km
ベストプラクティス
# パイプライン処理
redis-cli --pipe < commands.txt
# トランザクション
MULTI
SET user:1:name "田中太郎"
INCR user:1:login_count
EXEC
# Lua スクリプト
EVAL "
local key = KEYS[1]
local value = redis.call('GET', key)
if value then
return redis.call('INCR', key)
else
redis.call('SET', key, 1)
return 1
end
" 1 counter:visits
# 永続化設定
# redis.conf
save 900 1 # 900秒間に1回以上変更があれば保存
save 300 10 # 300秒間に10回以上変更があれば保存
save 60 10000 # 60秒間に10000回以上変更があれば保存
# AOF有効化
appendonly yes
appendfsync everysec
# レプリケーション設定(スレーブ側)
# redis.conf
replicaof 192.168.1.100 6379
Node.js での使用例
const redis = require('redis')
// クライアント作成
const client = redis.createClient({
host: 'localhost',
port: 6379
})
client.on('error', (err) => {
console.log('Redis Client Error', err)
})
async function redisOperations() {
await client.connect()
// 基本操作
await client.set('user:1:name', '田中太郎')
const name = await client.get('user:1:name')
console.log(name)
// ハッシュ操作
await client.hSet('user:1', {
name: '田中太郎',
age: 30,
email: '[email protected]'
})
const userData = await client.hGetAll('user:1')
console.log(userData)
// リスト操作
await client.lPush('tasks', '買い物', '洗濯', '掃除')
const tasks = await client.lRange('tasks', 0, -1)
console.log(tasks)
await client.quit()
}
redisOperations()
設定とチューニング
# redis.conf の主要設定
maxmemory 2gb
maxmemory-policy allkeys-lru
timeout 300
tcp-keepalive 300
databases 16
# セキュリティ設定
requirepass your_password_here
bind 127.0.0.1
# ネットワーク設定
port 6379
tcp-backlog 511