Redis

インメモリデータ構造ストア。キャッシュ、メッセージブローカー、データベースとして使用可能。圧倒的な高速性とリアルタイム処理能力が特徴。

データベースサーバーインメモリNoSQLキーバリューキャッシュ高速リアルタイムセッション管理

データベースサーバー

Redis

概要

Redisは「REmote DIctionary Server」の略で、インメモリデータ構造ストアとして世界で最も人気のあるキー・バリュー型データベースです。キャッシュ、メッセージブローカー、データベースとして多目的に使用でき、圧倒的な高速性とリアルタイム処理能力が特徴です。文字列、ハッシュ、リスト、セット、ソート済みセットなど豊富なデータ型をサポートし、マイクロ秒レベルの低レイテンシでデータアクセスが可能です。StackOverflow調査でも開発者に最も愛されるデータベースとして高い評価を受けています。

詳細

Redis 2025年版は、Redis 7.4の最新機能を含むRedis Stack(検索、JSON、時系列、確率的データ構造、グラフ)との統合により、単純なキャッシュを超えた包括的なデータプラットフォームとして進化しています。メモリ内での動作により極めて高速な読み書きが可能で、永続化機能(RDB、AOF)により耐久性も確保されています。水平スケーリングのためのRedis Clusterや高可用性のためのSentinel機能を提供し、レプリケーション、Lua/JavaScript scripting、地理空間データ処理、フルテキスト検索、ベクター検索など先進的な機能を包含しています。2024年のライセンス変更により、2025年5月からRSALv2/SSPL/Apacheのトリプルライセンス化が予定されています。

主な特徴

  • インメモリ高速処理: マイクロ秒レベルの低レイテンシでの読み書き処理
  • 豊富なデータ型: 文字列、ハッシュ、リスト、セット、ソート済みセット、ビットマップ等
  • 永続化オプション: RDBスナップショットとAOF(Append Only File)による耐久性
  • スケーラビリティ: Redis Clusterによる水平分散と自動シャーディング
  • 高可用性: Sentinelによる自動フェイルオーバーとレプリケーション
  • 拡張機能: Redis Stack(検索、JSON、時系列、ML)による機能拡張

メリット・デメリット

メリット

  • キャッシュサーバー分野での圧倒的なシェアと成熟したエコシステム
  • マイクロ秒レベルの超高速レスポンスタイムでリアルタイムアプリケーションに最適
  • 豊富なデータ型と原子的操作により複雑なデータ構造を効率的に処理
  • 軽量でシンプルな設計により運用コストが低く、メモリ効率も優秀
  • Pub/Sub機能やLuaスクリプティングによる高度なリアルタイム処理
  • Docker、Kubernetes環境での優れたポータビリティと運用性

デメリット

  • メモリベースのため大容量データの保存にはコストが高く制約がある
  • 2024年のライセンス変更により商用利用での法的検討が必要
  • 単一スレッドアーキテクチャによりCPU集約的な処理には向かない
  • 複雑なクエリや集計処理にはRDBMSより機能が限定的
  • クラスター構成での運用には高度な知識と適切な設計が必要
  • 永続化設定を誤ると予期しないデータ消失のリスクがある

参考ページ

書き方の例

インストールと基本セットアップ

# Ubuntu/Debianでのインストール
sudo apt update
sudo apt install redis-server redis-tools

# Redis Stack(拡張機能含む)のインストール
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 update
sudo apt install redis-stack-server

# CentOS/RHELでのインストール
sudo dnf install epel-release
sudo dnf install redis

# Dockerでの起動
docker run --name redis-server \
  -p 6379:6379 \
  -d redis:7.4-alpine

# Redis Stackの起動(検索、JSON等の機能含む)
docker run --name redis-stack \
  -p 6379:6379 \
  -p 8001:8001 \
  -d redis/redis-stack:latest

# Redis CLI接続
redis-cli
redis-cli -h localhost -p 6379

# 基本設定確認
redis-cli ping  # PONG が返ればOK
redis-cli info server

基本操作とデータ型

# 文字列操作
SET user:1:name "田中太郎"
GET user:1:name
MSET user:1:email "[email protected]" user:1:age "30"
MGET user:1:name user:1:email user:1:age

# 有効期限付きデータ
SETEX session:abc123 3600 "user_session_data"  # 1時間で期限切れ
TTL session:abc123  # 残り時間確認
EXPIRE user:1:name 86400  # 24時間後に期限切れ設定

# カウンター操作
SET page_views 0
INCR page_views  # 1増加
INCRBY page_views 10  # 10増加
DECR page_views  # 1減少

# ハッシュ操作(オブジェクト的データ)
HMSET user:2 name "佐藤花子" email "[email protected]" age 28
HGET user:2 name
HGETALL user:2
HINCRBY user:2 age 1  # 年齢を1増加
HDEL user:2 email  # emailフィールド削除

# リスト操作(配列的データ)
LPUSH messages "こんにちは"  # 左端に追加
RPUSH messages "さようなら"  # 右端に追加
LRANGE messages 0 -1  # 全要素取得
LPOP messages  # 左端から取得して削除
LLEN messages  # リスト長取得

# セット操作(重複なし集合)
SADD tags:1 "Redis" "NoSQL" "キャッシュ"
SMEMBERS tags:1  # 全メンバー取得
SISMEMBER tags:1 "Redis"  # メンバー存在確認
SCARD tags:1  # セットサイズ取得

# ソート済みセット(スコア付き)
ZADD ranking 100 "user1" 85 "user2" 95 "user3"
ZRANGE ranking 0 -1 WITHSCORES  # スコア順で取得
ZREVRANGE ranking 0 2 WITHSCORES  # 上位3位まで取得
ZSCORE ranking "user1"  # 特定ユーザーのスコア取得

JSON操作とRedis Stack機能

# JSON操作(Redis Stack必要)
JSON.SET product:1 $ '{"name":"ノートPC","price":89800,"category":"電子機器","specs":{"cpu":"Intel i7","memory":"16GB"}}'
JSON.GET product:1
JSON.GET product:1 $.name  # 特定フィールド取得
JSON.SET product:1 $.price 79800  # 価格更新
JSON.NUMINCRBY product:1 $.price -5000  # 価格から5000減算

# JSONでの配列操作
JSON.SET products $ '{"items":[{"id":1,"name":"商品A"},{"id":2,"name":"商品B"}]}'
JSON.ARRAPPEND products $.items '{"id":3,"name":"商品C"}'  # 配列に追加
JSON.ARRLEN products $.items  # 配列長取得

# 検索インデックス作成(Redis Stack)
FT.CREATE product_idx ON JSON PREFIX 1 product: SCHEMA 
  $.name AS name TEXT 
  $.price AS price NUMERIC SORTABLE
  $.category AS category TAG

# 全文検索実行
FT.SEARCH product_idx "@name:ノート*"  # ノートで始まる商品検索
FT.SEARCH product_idx "@price:[50000 100000]"  # 価格範囲検索
FT.SEARCH product_idx "@category:{電子機器}"  # カテゴリ検索

# 時系列データ(Redis Stack)
TS.CREATE temperature:sensor1 RETENTION 86400000  # 24時間保持
TS.ADD temperature:sensor1 * 25.6  # 現在時刻で温度追加
TS.RANGE temperature:sensor1 - +  # 全データ取得
TS.MRANGE - + FILTER area=tokyo  # 複数センサーのデータ取得

Pub/Sub(メッセージング)とストリーム

# Pub/Sub(メッセージング)
# 購読者側
SUBSCRIBE news:updates notifications:*

# 発行者側
PUBLISH news:updates "新しいニュースが追加されました"
PUBLISH notifications:user:123 "メッセージが届きました"

# パターン購読
PSUBSCRIBE events:*  # events:で始まるチャンネル全て購読

# Redis Streams(永続化メッセージキュー)
# ストリーム作成とメッセージ追加
XADD user_actions * action "login" user_id "123" timestamp "2024-01-15T10:00:00Z"
XADD user_actions * action "purchase" user_id "456" product_id "789" amount "1500"

# ストリーム読み取り
XREAD COUNT 10 STREAMS user_actions 0  # 最初から10件読み取り
XREAD BLOCK 0 STREAMS user_actions $  # 新しいメッセージを待機

# コンシューマーグループ作成
XGROUP CREATE user_actions processors $ MKSTREAM
XREADGROUP GROUP processors consumer1 COUNT 1 STREAMS user_actions >

# 確認応答
XACK user_actions processors <message-id>

# ストリーム情報確認
XINFO STREAM user_actions
XLEN user_actions  # ストリーム長

Luaスクリプティングと高度な操作

# 単純なLuaスクリプト実行
EVAL "return redis.call('GET', KEYS[1])" 1 mykey

# 複雑なLuaスクリプト(原子的な増加と上限チェック)
EVAL "
local current = redis.call('GET', KEYS[1])
if current == false then
    current = 0
else
    current = tonumber(current)
end
if current < tonumber(ARGV[1]) then
    return redis.call('INCR', KEYS[1])
else
    return nil
end
" 1 counter 100

# スクリプトの保存と実行
SCRIPT LOAD "return redis.call('GET', KEYS[1])"  # SHA1ハッシュ返却
EVALSHA <sha1_hash> 1 mykey  # 保存済みスクリプト実行

# トランザクション的処理
MULTI
SET account:1:balance 1000
SET account:2:balance 500
EXEC

# 条件付きトランザクション(楽観的ロック)
WATCH account:1:balance  # 監視開始
balance=$(redis-cli GET account:1:balance)
MULTI
SET account:1:balance $((balance - 100))
EXEC  # 監視中にデータが変更されていればnilが返る

Redis Cluster(分散構成)とレプリケーション

# Redis Cluster設定例(redis.conf)
cat > redis-cluster.conf << EOF
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
appendonly yes
EOF

# クラスターノード起動(複数ポート)
redis-server redis-cluster-7000.conf &
redis-server redis-cluster-7001.conf &
redis-server redis-cluster-7002.conf &

# クラスター作成
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 -p 7000 cluster nodes
redis-cli -p 7000 cluster info

# マスター・スレーブレプリケーション設定
# スレーブ側設定(redis.conf)
replicaof 127.0.0.1 6379
replica-read-only yes

# Sentinel設定(高可用性)
cat > sentinel.conf << EOF
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
EOF

# Sentinel起動
redis-sentinel sentinel.conf

パフォーマンス監視と運用管理

# パフォーマンス情報取得
INFO all  # 全般情報
INFO memory  # メモリ使用量
INFO stats  # 統計情報
INFO replication  # レプリケーション情報
INFO clients  # クライアント接続情報

# 低速クエリログ確認
CONFIG SET slowlog-log-slower-than 10000  # 10ms以上を記録
SLOWLOG GET 10  # 直近10件の低速クエリ
SLOWLOG RESET  # ログクリア

# クライアント監視
CLIENT LIST  # 接続中クライアント一覧
CLIENT KILL TYPE normal  # 通常クライアント切断
MONITOR  # リアルタイム監視(開発時のみ使用)

# メモリ使用量分析
MEMORY USAGE mykey  # 特定キーのメモリ使用量
MEMORY STATS  # メモリ統計
SCAN 0 MATCH user:* COUNT 100  # パターンマッチングでキー検索

# ベンチマークテスト
redis-benchmark -h localhost -p 6379 -c 50 -n 10000
redis-benchmark -t set,get -n 1000000 -q  # SET/GET性能測定

# データバックアップと復元
# RDBスナップショット作成
BGSAVE  # バックグラウンドで保存
LASTSAVE  # 最後のスナップショット時刻

# AOF再書き込み
BGREWRITEAOF  # AOFファイル最適化

# データベースクリア
FLUSHDB  # 現在のデータベースクリア
FLUSHALL  # 全データベースクリア(注意!)

# 設定変更(永続化)
CONFIG SET save "900 1 300 10 60 10000"  # 自動保存設定
CONFIG REWRITE  # 設定ファイルに書き込み

Redis Stack統合機能の活用

# 確率的データ構造(Bloom Filter)
BF.RESERVE unique_users 1000000 0.01  # 100万要素、1%誤判定率
BF.ADD unique_users "user123"  # 要素追加
BF.EXISTS unique_users "user123"  # 存在確認(false positiveの可能性)

# Count-Min Sketch(頻度推定)
CMS.INITBYDIM user_events 1000 5  # 初期化
CMS.INCRBY user_events login 1 purchase 3  # イベント追加
CMS.QUERY user_events login purchase  # 頻度取得

# ベクター検索(機械学習向け)
FT.CREATE vector_idx ON HASH PREFIX 1 vector: SCHEMA 
  embedding VECTOR FLAT 6 TYPE FLOAT32 DIM 128 DISTANCE_METRIC COSINE

# ベクター追加
HSET vector:1 embedding "<128次元のfloat32配列>"

# ベクター類似検索
FT.SEARCH vector_idx "*=>[KNN 5 @embedding $vec]" PARAMS 2 vec "<クエリベクター>" DIALECT 2

# 地理空間データ処理
GEOADD locations 139.6917 35.6895 "Tokyo"
GEOADD locations 135.5023 34.6937 "Osaka"
GEODIST locations "Tokyo" "Osaka" km  # 距離計算
GEORADIUS locations 139.6917 35.6895 100 km  # 半径100km以内の地点検索