データベース

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