はい、承知いたしました。Redisのよく使うコマンド一覧と使い方を詳細に解説する記事を作成します。約5000語を目指し、記事内容を直接表示します。
よく使うRedisコマンド一覧と使い方を徹底紹介
はじめに:インメモリデータストアRedisの世界へようこそ
現代のウェブアプリケーションやサービス開発において、高速なデータアクセスは不可欠です。大量のユーザーからのリクエストに応答し、リアルタイム性の高い機能を提供するためには、従来のディスクベースのデータベースだけでは限界があります。そこで注目されるのが、インメモリデータ構造ストアである「Redis」です。
Redisは、データをメインメモリ上に保持することで、ミリ秒以下の非常に高速な読み書きを実現します。また、単なるキャッシュとしてだけでなく、多様なデータ構造(文字列、リスト、ハッシュ、セット、ソート済みセットなど)をサポートしており、メッセージキュー、セッションストア、リーダーボード、リアルタイム分析など、幅広い用途で活用されています。
Redisが多くの開発者に選ばれる理由はいくつかあります。
- 圧倒的な高速性: データをメモリに保持するため、ディスクI/Oのボトルネックがなく、非常に高速なデータ操作が可能です。
- 多様なデータ構造: シンプルなキー・バリューだけでなく、リスト、ハッシュ、セット、ソート済みセットなど、プログラムでよく使うデータ構造をそのまま扱えます。これにより、アプリケーションのロジックをシンプルに保つことができます。
- 永続化オプション: データはメモリ上にありますが、RDBスナップショットやAOF(Append Only File)などの永続化オプションにより、サーバーが再起動してもデータを復旧させることが可能です。
- 高可用性: Sentinelによる自動フェイルオーバーや、Redis Clusterによるシャーディングなど、高可用性・スケーラビリティのための機能も充実しています。
- シンプルなコマンド: コマンドは直感的で分かりやすく、学習コストが比較的低いことも魅力です。
この記事では、Redisの基本的な操作から、それぞれのデータ構造に対応する主要なコマンドまでを、具体的な使用例とともに徹底的に解説します。この記事を読めば、Redisを使った開発の基礎をしっかりと身につけることができるでしょう。
さあ、Redisの強力な世界への一歩を踏み出しましょう。
Redisの基本:インストールと接続、そしてコマンドの構造
Redisを使うためには、まずRedisサーバーをインストールし、クライアントから接続する必要があります。
Redisのインストール(簡易説明)
多くのOSでRedisは簡単にインストールできます。
- Linux (Ubuntu):
sudo apt update && sudo apt install redis-server
- macOS (Homebrew):
brew install redis
- Windows: 公式サイトからインストーラーをダウンロードするか、WSL (Windows Subsystem for Linux) を利用するのが一般的です。
インストール後、redis-server
コマンドでサーバーを起動します。
redis-cliを使った接続
Redisサーバーが起動したら、同梱されているコマンドラインインターフェース(CLI)ツールであるredis-cli
を使って接続します。
ターミナルで以下のコマンドを実行します。
bash
redis-cli
デフォルト設定であれば、パスワードなしでポート6379に接続されます。
127.0.0.1:6379>
このようにプロンプトが表示されれば接続成功です。これでRedisコマンドを実行できるようになります。
コマンドの基本構文
Redisコマンドは、ほとんどの場合以下の構造を持っています。
COMMAND_NAME key [argument1 argument2 ...]
COMMAND_NAME
: 実行したいコマンドの名前(例:SET
,GET
,LPUSH
)key
: 操作対象となるキーの名前(ほとんどのコマンドで必須)[argument ...]
: コマンドに必要な追加の引数(値、インデックス、オプションなど)
Redisでは、コマンド名と引数は大文字・小文字を区別しませんが、慣習として大文字で記述することが多いです。キー名や値はバイナリセーフであり、ほとんどどのようなデータでも格納できます。
コマンド例:疎通確認
接続できているか確認するために、シンプルなPING
コマンドを使ってみましょう。
127.0.0.1:6379> PING
PONG
PONG
という応答があれば、サーバーは正常に動作しています。
さて、ここからはいよいよRedisの主要なデータ構造とそれに対応するコマンドを詳しく見ていきましょう。
主要なデータ構造とコマンド群
Redisは単なるキー・バリューだけでなく、複数の高度なデータ構造をネイティブにサポートしています。これにより、アプリケーション開発がより効率的かつシンプルになります。代表的なデータ構造とそれに対応するよく使うコマンドを紹介します。
1. String (文字列)
最もシンプルで基本的なデータ構造です。キーと1対1で対応する文字列値を格納します。値はテキストだけでなく、バイナリデータ(画像なども)も格納できます。String型は、キャッシュ、セッション情報、簡単なカウンターなどに利用されます。
SET key value [options]
指定したキーに文字列値を設定します。既存のキーがあれば、その値は上書きされます。
- 構文:
SET key value [EX seconds | PX milliseconds | KEEPTTL] [NX | XX]
- 説明:
key
にvalue
を関連付けます。オプションで有効期限(EX
/PX
)や、キーが存在しない場合(NX
)または存在する場合(XX
)のみ設定する条件を指定できます。 - 例:
127.0.0.1:6379> SET mykey "Hello Redis"
OK
127.0.0.1:6379> SET user:1:name "Alice" EX 3600
OK # 3600秒(1時間)後に期限切れ
127.0.0.1:6379> SET onlyifnotexists "initial value" NX
OK # onlyifnotexistsが存在しないので設定される
127.0.0.1:6379> SET onlyifnotexists "another value" NX
(nil) # onlyifnotexistsは既に存在するので設定されない
GET key
指定したキーに格納されている値を取得します。
- 構文:
GET key
- 説明:
key
に関連付けられている値を取得します。キーが存在しない場合や、String型以外の値が格納されている場合は(nil)
が返されます。 - 例:
127.0.0.1:6379> GET mykey
"Hello Redis"
127.0.0.1:6379> GET nonexistingkey
(nil)
DEL key [key ...]
指定したキーを削除します。複数のキーを一度に指定することも可能です。
- 構文:
DEL key [key ...]
- 説明: 指定されたキーとその値を削除します。
- 戻り値: 削除されたキーの数。
- 例:
127.0.0.1:6379> SET key1 "value1"
OK
127.0.0.1:6379> SET key2 "value2"
OK
127.0.0.1:6379> DEL key1 key2 nonexistingkey
(integer) 2 # key1とkey2の2つが削除された
EXISTS key [key ...]
指定したキーが存在するかどうかを確認します。
- 構文:
EXISTS key [key ...]
- 説明: 指定されたキーが存在すれば1、存在しなければ0を返します。複数のキーを指定した場合は、存在するキーの合計数を返します。
- 例:
127.0.0.1:6379> SET existingkey "hello"
OK
127.0.0.1:6379> EXISTS existingkey
(integer) 1
127.0.0.1:6739> EXISTS nonexistingkey
(integer) 0
127.0.0.1:6739> EXISTS existingkey nonexistingkey
(integer) 1
EXPIRE key seconds
指定したキーに有効期限を設定します。seconds
で指定した秒数が経過すると、そのキーは自動的に削除されます。
- 構文:
EXPIRE key seconds
- 説明:
key
の有効期限をseconds
秒に設定します。キーが存在し、有効期限が設定できた場合は1、キーが存在しない場合や操作が無効な場合は0を返します。 - 例:
127.0.0.1:6379> SET volatilekey "this will expire"
OK
127.0.0.1:6379> EXPIRE volatilekey 10
(integer) 1 # 10秒後に期限切れ
127.0.0.1:6379> TTL volatilekey # 残り時間を取得 (次に説明)
(integer) 8 # 例:実行から2秒経過後
TTL key
指定したキーの有効期限の残り時間(秒)を取得します。
- 構文:
TTL key
- 説明: キーがまだ存在し、有効期限が設定されている場合の残り時間を秒で返します。
- 有効期限が設定されていないキー: -1
- キーが存在しない: -2
- キーが存在し、有効期限が設定されている: 残り時間(秒)
- 例:
127.0.0.1:6379> SET tempkey "value" EX 60
OK
127.0.0.1:6379> TTL tempkey
(integer) 58 # 例:設定から2秒経過後
127.0.0.1:6379> SET persistentkey "value"
OK
127.0.0.1:6379> TTL persistentkey
(integer) -1
127.0.0.1:6379> TTL nonexistingkey
(integer) -2
INCR key
キーに格納されている値を1増やします。値は数値として解釈されます。
- 構文:
INCR key
- 説明:
key
の値を数値として解釈し、1インクリメントします。キーが存在しない場合は、まず値を0として設定し、それからインクリメントするため、結果は1になります。値が数値として解釈できない場合はエラーとなります。 - 戻り値: インクリメント後の値。
- 例:
127.0.0.1:6379> SET counter 10
OK
127.0.0.1:6379> INCR counter
(integer) 11
127.0.0.1:6379> INCR counter
(integer) 12
127.0.0.1:6379> INCR newcounter
(integer) 1 # newcounterが存在しないため0が設定され、1になる - 関連コマンド:
DECR
(1減らす),INCRBY value
(指定した数値だけ増やす),DECRBY value
(指定した数値だけ減らす),INCRBYFLOAT value
(浮動小数点数で増やす)
MSET key1 value1 [key2 value2 ...]
複数のキーと値を一度に設定します。
- 構文:
MSET key1 value1 [key2 value2 ...]
- 説明: 複数のキーと値をアトミック(不可分)に設定します。すべてのキーが一度に設定されるか、何も設定されないかのどちらかになります。
- 例:
127.0.0.1:6379> MSET user:1:name "Alice" user:1:email "[email protected]" user:2:name "Bob"
OK
127.0.0.1:6379> GET user:1:name
"Alice"
127.0.0.1:6379> GET user:2:name
"Bob"
MGET key1 [key2 ...]
複数のキーの値を一度に取得します。
- 構文:
MGET key1 [key2 ...]
- 説明: 指定された複数のキーに関連付けられた値をリストで返します。キーが存在しない場合は、その位置に
(nil)
が返されます。 - 例:
127.0.0.1:6379> MSET book:1:title "Redis Basics" book:2:title "Advanced Redis"
OK
127.0.0.1:6379> MGET book:1:title book:3:title book:2:title
1) "Redis Basics"
2) (nil) # book:3:title は存在しない
3) "Advanced Redis"
2. List (リスト)
Listは、要素が挿入順に並ぶリスト構造です。要素は重複していても構いません。リストの両端(左端と右端)からの要素の追加や削除が高速に行えるため、キューやスタックとしてよく利用されます。
LPUSH key element [element ...]
リストの左端(先頭)に要素を追加します。複数の要素を指定した場合、指定された順序で左端に追加されます。
- 構文:
LPUSH key element [element ...]
- 説明: 指定された
element
をkey
に関連付けられたリストの左端に追加します。キーが存在しない場合は、新しいリストが作成されます。 - 戻り値: 操作後のリストの長さ。
- 例:
127.0.0.1:6379> LPUSH mylist "world"
(integer) 1
127.0.0.1:6379> LPUSH mylist "hello"
(integer) 2 # リストは ["hello", "world"] になる
127.0.0.1:6379> LPUSH mylist "pre" "alpha"
(integer) 4 # リストは ["alpha", "pre", "hello", "world"] になる
RPUSH key element [element ...]
リストの右端(末尾)に要素を追加します。
- 構文:
RPUSH key element [element ...]
- 説明: 指定された
element
をkey
に関連付けられたリストの右端に追加します。キーが存在しない場合は、新しいリストが作成されます。 - 戻り値: 操作後のリストの長さ。
- 例:
127.0.0.1:6379> RPUSH mylist "apple"
(integer) 1
127.0.0.1:6379> RPUSH mylist "banana"
(integer) 2 # リストは ["apple", "banana"] になる
127.0.0.1:6379> RPUSH mylist "cherry" "date"
(integer) 4 # リストは ["apple", "banana", "cherry", "date"] になる
LPOP key
リストの左端(先頭)から要素を取り出し、削除します。
- 構文:
LPOP key
- 説明:
key
に関連付けられたリストの左端の要素を取り出します。リストが空の場合やキーが存在しない場合は(nil)
を返します。 - 例:
127.0.0.1:6379> RPUSH mylist "a" "b" "c"
(integer) 3 # リストは ["a", "b", "c"]
127.0.0.1:6379> LPOP mylist
"a" # リストは ["b", "c"] になる
127.0.0.1:6379> LPOP mylist
"b" # リストは ["c"] になる
127.0.0.1:6379> LPOP mylist
"c" # リストは [] (空) になる
127.0.0.1:6379> LPOP mylist
(nil) # リストは空なので nil - 関連コマンド:
RPOP
(リストの右端から要素を取り出し削除する)
LRANGE key start stop
リストの指定された範囲の要素を取得します。リスト自体は変更されません。
- 構文:
LRANGE key start stop
- 説明:
key
に関連付けられたリストから、インデックスstart
からstop
までの要素を取得します。インデックスは0から始まり、負のインデックスは末尾からの位置を示します(-1は末尾の要素、-2はその前の要素など)。 - 例:
127.0.0.1:6379> RPUSH mylist "a" "b" "c" "d" "e"
(integer) 5 # リストは ["a", "b", "c", "d", "e"]
127.0.0.1:6379> LRANGE mylist 0 2
1) "a"
2) "b"
3) "c" # インデックス0から2までを取得
127.0.0.1:6379> LRANGE mylist -3 -1
1) "c"
2) "d"
3) "e" # 後ろから3番目から末尾までを取得
127.0.0.1:6379> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e" # 全ての要素を取得
LLEN key
リストの長さを取得します。
- 構文:
LLEN key
- 説明:
key
に関連付けられたリストに含まれる要素の数を返します。キーが存在しない場合は0を返します。 - 例:
127.0.0.1:6379> RPUSH mylist "a" "b" "c"
(integer) 3
127.0.0.1:6379> LLEN mylist
(integer) 3
127.0.0.1:6379> LPOP mylist
"a"
127.0.0.1:6379> LLEN mylist
(integer) 2
127.0.0.1:6379> LLEN nonexistinglist
(integer) 0
RPOPLPUSH source destination
source
リストの右端から要素を取り出し、それをdestination
リストの左端に追加します。アトミックに行われます。
- 構文:
RPOPLPUSH source destination
- 説明:
source
リストの末尾要素を削除し、その要素をdestination
リストの先頭に追加します。これは、タスクキューなどの処理において、要素を「処理中」リストに移動させる用途などに便利です。 - 戻り値: 移動された要素。
source
リストが空の場合は(nil)
。 - 例:
127.0.0.1:6379> RPUSH taskqueue "task1" "task2" "task3"
(integer) 3
127.0.0.1:6379> LRANGE taskqueue 0 -1
1) "task1"
2) "task2"
3) "task3"
127.0.0.1:6379> RPOPLPUSH taskqueue processingtasks
"task3"
127.0.0.1:6379> LRANGE taskqueue 0 -1
1) "task1"
2) "task2"
127.0.0.1:6379> LRANGE processingtasks 0 -1
1) "task3"
3. Hash (ハッシュ)
Hashは、フィールドと値のペアの集合を格納する構造です。一つのキーに対して、複数のフィールドとそれぞれの値を関連付けられます。リレーショナルデータベースのレコードや、オブジェクトのような構造を表現するのに適しています。
HSET key field value [field value ...]
ハッシュにフィールドと値を設定します。複数のフィールドと値を一度に設定できます。
- 構文:
HSET key field value [field value ...]
- 説明: 指定された
key
に関連付けられたハッシュに、field
とvalue
のペアを設定します。フィールドが既に存在する場合は値が上書きされます。 - 戻り値: Redis 4.0以降では、新しく追加されたフィールドの数。それ以前は、追加されたフィールド数(0または1)。
- 例:
127.0.0.1:6379> HSET user:1 name "Alice" age 30 city "New York"
(integer) 3 # 3つの新しいフィールドが追加された
127.0.0.1:6379> HSET user:1 age 31
(integer) 0 # ageフィールドは既存だったので、新しい追加は0
HGET key field
ハッシュから指定したフィールドの値を取得します。
- 構文:
HGET key field
- 説明:
key
に関連付けられたハッシュから、指定されたfield
の値を返します。キーが存在しない場合、ハッシュ内にフィールドが存在しない場合、またはキーがハッシュ型以外の場合は(nil)
を返します。 - 例:
127.0.0.1:6379> HGET user:1 name
"Alice"
127.0.0.1:6379> HGET user:1 email
(nil) # emailフィールドは存在しない
127.0.0.1:6379> HGET nonexistinghash somefield
(nil)
HMGET key field [field ...]
ハッシュから複数のフィールドの値を一度に取得します。
- 構文:
HMGET key field [field ...]
- 説明:
key
に関連付けられたハッシュから、指定された複数のfield
の値を取得します。フィールドが存在しない場合は、その位置に(nil)
が返されます。 - 例:
127.0.0.1:6379> HMGET user:1 name age email
1) "Alice"
2) "31"
3) (nil) # emailフィールドは存在しない - 注意: Redis 4.0以降では、
HGET
で複数のフィールドを指定できるようになり、HGET
の代わりにHGETALL
または単一のHGET
を複数回実行することが推奨される場合もあります。しかし、HMGET
は依然として便利です。
HGETALL key
ハッシュの全てのフィールドと値を取得します。
- 構文:
HGETALL key
- 説明:
key
に関連付けられたハッシュに含まれる全てのフィールドと値をリスト形式で返します。リストはフィールド名、その値、フィールド名、その値、… の順になります。キーが存在しない場合は空のリストを返します。 - 例:
127.0.0.1:6379> HGETALL user:1
1) "name"
2) "Alice"
3) "age"
4) "31"
5) "city"
6) "New York"
HDEL key field [field ...]
ハッシュから指定したフィールドを削除します。
- 構文:
HDEL key field [field ...]
- 説明:
key
に関連付けられたハッシュから、指定されたfield
を削除します。 - 戻り値: 削除されたフィールドの数。
- 例:
127.0.0.1:6379> HDEL user:1 city email
(integer) 1 # cityは削除されたが emailは存在しなかった
127.0.0.1:6379> HGETALL user:1
1) "name"
2) "Alice"
3) "age"
4) "31"
HLEN key
ハッシュに含まれるフィールドの数を取得します。
- 構文:
HLEN key
- 説明:
key
に関連付けられたハッシュに含まれるフィールドの数を返します。キーが存在しない場合は0を返します。 - 例:
127.0.0.1:6379> HLEN user:1
(integer) 2 # nameとageの2フィールドが残っている
127.0.0.1:6379> HLEN nonexistinghash
(integer) 0
HINCRBY key field increment
ハッシュの指定フィールドの値を指定した数値だけ増やします。値は整数として解釈されます。
- 構文:
HINCRBY key field increment
- 説明:
key
に関連付けられたハッシュのfield
の値をincrement
だけ増やします。フィールドが存在しない場合は0として扱われます。値が整数として解釈できない場合はエラーとなります。 - 戻り値: インクリメント後のフィールドの値。
- 例:
127.0.0.1:6379> HSET product:1 stock 100
(integer) 1
127.0.0.1:6379> HINCRBY product:1 stock 5
(integer) 105
127.0.0.1:6379> HINCRBY product:1 sales 1
(integer) 1 # salesフィールドは存在しなかったので0が設定され、1になる - 関連コマンド:
HINCRBYFLOAT key field increment
(浮動小数点数で増やす)
4. Set (セット)
Setは、順序付けされていない一意な要素の集合です。リストと異なり、要素の重複は許されません。要素の存在確認や、複数のセット間の和集合、積集合、差集合の計算が効率的に行えます。タグ、ユニークユーザーの追跡、友達リストなどに利用されます。
SADD key member [member ...]
セットに1つ以上の要素を追加します。追加しようとした要素が既に存在する場合は無視されます。
- 構文:
SADD key member [member ...]
- 説明: 指定された
member
をkey
に関連付けられたセットに追加します。キーが存在しない場合は新しいセットが作成されます。 - 戻り値: 新しくセットに追加された要素の数。
- 例:
127.0.0.1:6379> SADD tags "redis" "database" "nosql"
(integer) 3
127.0.0.1:6379> SADD tags "database" "cache"
(integer) 1 # "database"は既に存在、"cache"が新しく追加
SMEMBERS key
セットの全ての要素を取得します。要素の順序は保証されません。
- 構文:
SMEMBERS key
- 説明:
key
に関連付けられたセットに含まれる全ての要素を返します。キーが存在しない場合は空のリストを返します。 - 例:
127.0.0.1:6379> SMEMBERS tags
1) "nosql"
2) "redis"
3) "cache"
4) "database"
SISMEMBER key member
指定した要素がセットに含まれているかを確認します。
- 構文:
SISMEMBER key member
- 説明: 指定された
member
がkey
に関連付けられたセットに含まれている場合、1を返します。含まれていない場合やキーが存在しない場合は0を返します。 - 例:
127.0.0.1:6379> SISMEMBER tags "redis"
(integer) 1
127.0.0.1:6379> SISMEMBER tags "python"
(integer) 0
SCARD key
セットに含まれる要素の数を取得します(カーディナリティ)。
- 構文:
SCARD key
- 説明:
key
に関連付けられたセットに含まれる要素の数を返します。キーが存在しない場合は0を返します。 - 例:
127.0.0.1:6379> SCARD tags
(integer) 4
127.0.0.1:6379> SCARD nonexistingset
(integer) 0
SREM key member [member ...]
セットから指定した要素を削除します。
- 構文:
SREM key member [member ...]
- 説明:
key
に関連付けられたセットから、指定されたmember
を削除します。指定された要素がセットに含まれていない場合は無視されます。 - 戻り値: セットから実際に削除された要素の数。
- 例:
127.0.0.1:6379> SREM tags "nosql" "database" "unknown"
(integer) 2 # "nosql"と"database"が削除された。"unknown"は存在しない
127.0.0.1:6379> SMEMBERS tags
1) "redis"
2) "cache"
SUNION key [key ...]
/ SINTER key [key ...]
/ SDIFF key [key ...]
複数のセット間で和集合、積集合、差集合を計算します。
- 構文:
SUNION key [key ...]
(和集合)SINTER key [key ...]
(積集合)SDIFF key [key ...]
(最初のセットから後続のセットの要素を除いた差集合)
- 説明: 指定された全てのセットに対して、和集合(全ての要素)、積集合(全てのセットに共通する要素)、または差集合(最初のセットにのみ存在する要素)を計算し、その結果を返します。結果は新しいセットとして格納することもできます(例:
SUNIONSTORE
)。 - 例:
127.0.0.1:6379> SADD set1 "a" "b" "c"
(integer) 3
127.0.0.1:6379> SADD set2 "c" "d" "e"
(integer) 3
127.0.0.1:6379> SUNION set1 set2
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> SINTER set1 set2
1) "c"
127.0.0.1:6379> SDIFF set1 set2
1) "a"
2) "b"
127.0.0.0:6379> SDIFF set2 set1
1) "d"
2) "e"
5. Sorted Set (ソート済みセット)
Sorted Setは、Setと同様に一意な要素の集合ですが、各要素に浮動小数点数である「スコア」が付与されており、そのスコアに基づいて要素が常にソートされています。要素の重複は許されませんが、スコアの重複は許されます。スコアが同じ要素の場合は、文字列として辞書順にソートされます。リーダーボード、優先度付きキュー、レート制限などに利用されます。
ZADD key score member [score member ...]
ソート済みセットに1つ以上の要素(スコア付き)を追加します。要素が既に存在する場合はスコアが更新されます。
- 構文:
ZADD key [options] score member [score member ...]
- 説明: 指定された
key
に関連付けられたソート済みセットに、score
とmember
のペアを追加します。キーが存在しない場合は新しいソート済みセットが作成されます。 - 戻り値: 新しくセットに追加された要素の数(既存要素のスコア更新は含まれない)。
- 例:
127.0.0.1:6379> ZADD leaderboard 100 "Alice" 200 "Bob" 150 "Charlie"
(integer) 3
127.0.0.1:6379> ZADD leaderboard 250 "Bob" # Bobのスコアを更新
(integer) 0
ZRANGE key start stop [WITHSCORES]
ソート済みセットの指定された範囲の要素を、スコアの昇順で取得します。
- 構文:
ZRANGE key start stop [WITHSCORES]
- 説明:
key
に関連付けられたソート済みセットから、インデックスstart
からstop
までの要素をスコアの昇順で取得します。インデックスは0から始まり、負のインデックスは末尾からの位置を示します。WITHSCORES
オプションを指定すると、各要素とそのスコアをペアで取得できます。 - 例:
127.0.0.1:6379> ZRANGE leaderboard 0 -1 # 全ての要素をスコア昇順で
1) "Alice" # スコア 100
2) "Charlie" # スコア 150
3) "Bob" # スコア 250
127.0.0.1:6379> ZRANGE leaderboard 0 -1 WITHSCORES
1) "Alice"
2) "100"
3) "Charlie"
4) "150"
5) "Bob"
6) "250"
127.0.0.1:6379> ZRANGE leaderboard 1 2 WITHSCORES
1) "Charlie"
2) "150"
3) "Bob"
4) "250" - 関連コマンド:
ZREVRANGE
(スコアの降順で取得)
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
ソート済みセットの指定されたスコア範囲の要素を取得します。
- 構文:
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
- 説明:
key
に関連付けられたソート済みセットから、スコアがmin
からmax
の範囲にある要素をスコアの昇順で取得します。min
とmax
には-inf
(負の無限大)や+inf
(正の無限大)を指定できます。スコアの範囲はデフォルトで含まれます(min <= score <= max
)。範囲を排他的にする場合は、(min
や(max
のように括弧を付けます。LIMIT
オプションで取得する要素数を制限できます。 - 例:
127.0.0.1:6379> ZADD scores 10 "user:1" 20 "user:2" 30 "user:3" 40 "user:4" 50 "user:5"
(integer) 5
127.0.0.1:6379> ZRANGEBYSCORE scores 20 40 WITHSCORES
1) "user:2"
2) "20"
3) "user:3"
4) "30"
5) "user:4"
6) "40"
127.0.0.1:6379> ZRANGEBYSCORE scores (20 40 WITHSCORES # スコア20, 40を含まない
1) "user:3"
2) "30"
127.0.0.1:6379> ZRANGEBYSCORE scores -inf +inf WITHSCORES LIMIT 1 2 # スコア不問で2番目から2つ取得
1) "user:2"
2) "20"
3) "user:3"
4) "30" - 関連コマンド:
ZREVRANGEBYSCORE
(スコアの降順で指定スコア範囲を取得)
ZSCORE key member
ソート済みセット内の指定した要素のスコアを取得します。
- 構文:
ZSCORE key member
- 説明:
key
に関連付けられたソート済みセット内のmember
のスコアを文字列として返します。キーが存在しない場合や、セット内に要素が存在しない場合は(nil)
を返します。 - 例:
127.0.0.1:6379> ZSCORE leaderboard "Bob"
"250"
127.0.0.1:6379> ZSCORE leaderboard "David"
(nil)
ZREM key member [member ...]
ソート済みセットから指定した要素を削除します。
- 構文:
ZREM key member [member ...]
- 説明:
key
に関連付けられたソート済みセットから、指定されたmember
を削除します。指定された要素がセットに含まれていない場合は無視されます。 - 戻り値: セットから実際に削除された要素の数。
- 例:
127.0.0.1:6379> ZREM leaderboard "Alice" "Charlie" "David"
(integer) 2 # "Alice"と"Charlie"が削除された。"David"は存在しない
127.0.0.1:6379> ZRANGE leaderboard 0 -1 WITHSCORES
1) "Bob"
2) "250"
ZCARD key
ソート済みセットに含まれる要素の数を取得します。
- 構文:
ZCARD key
- 説明:
key
に関連付けられたソート済みセットに含まれる要素の数を返します。キーが存在しない場合は0を返します。 - 例:
127.0.0.1:6379> ZCARD leaderboard
(integer) 1 # Bobだけが残っている
127.0.0.1:6379> ZCARD nonexistingzset
(integer) 0
ZINCRBY key increment member
ソート済みセットの指定要素のスコアを指定した数値だけ増やします。要素が存在しない場合は、スコア0で追加され、インクリメントされます。
- 構文:
ZINCRBY key increment member
- 説明:
key
に関連付けられたソート済みセット内のmember
のスコアをincrement
だけ増やします。increment
は浮動小数点数でも指定できます。 - 戻り値: インクリメント後の要素のスコア(文字列形式)。
- 例:
127.0.0.1:6379> ZINCRBY leaderboard 50 "Bob"
"300"
127.0.0.1:6379> ZSCORE leaderboard "Bob"
"300"
127.0.0.1:6379> ZINCRBY leaderboard 100 "David"
"100" # Davidは存在しなかったのでスコア0で追加され、100になる
ZRANK key member
/ ZREVRANK key member
ソート済みセット内の指定要素のスコア順(昇順/降順)でのランク(0から始まるインデックス)を取得します。
- 構文:
ZRANK key member
,ZREVRANK key member
- 説明:
key
に関連付けられたソート済みセット内のmember
のスコア順でのランクを返します。ZRANK
は昇順、ZREVRANK
は降順です。要素のスコアが同じ場合は辞書順でソートされます。キーが存在しない場合や、セット内に要素が存在しない場合は(nil)
を返します。 - 例:
127.0.0.1:6379> ZADD game:scores 100 playerA 200 playerB 50 playerC 150 playerD
(integer) 4
127.0.0.1:6379> ZRANGE game:scores 0 -1 WITHSCORES # 昇順: playerC, playerA, playerD, playerB
1) "playerC"
2) "50"
3) "playerA"
4) "100"
5) "playerD"
6) "150"
7) "playerB"
8) "200"
127.0.0.1:6379> ZRANK game:scores "playerA"
(integer) 1 # 昇順で2番目 (0-indexed)
127.0.0.1:6379> ZREVRANK game:scores "playerA"
(integer) 2 # 降順で3番目 (0-indexed)
キー操作とその他のユーティリティコマンド
データ構造に特化したコマンドの他に、キー全体を操作したり、サーバーの状態を確認したりするための汎用的なコマンドも多数あります。
KEYS pattern
指定したパターンに一致する全てのキーを取得します。
- 構文:
KEYS pattern
- 説明:
pattern
にはGlobスタイル(*
: 0文字以上の任意の文字列、?
: 任意の一文字、[]
: 角括弧内の文字のどれか)のパターンを指定できます。 - 戻り値: パターンに一致するキーのリスト。
- 例:
127.0.0.1:6379> SET user:1:name "Alice"
OK
127.0.0.1:6379> SET user:2:name "Bob"
OK
127.0.0.1:6379> SET product:1:price 100
OK
127.0.0.1:6379> KEYS user:*
1) "user:1:name"
2) "user:2:name"
127.0.0.1:6379> KEYS *name
1) "user:1:name"
2) "user:2:name"
127.0.0.1:6379> KEYS *
1) "user:1:name"
2) "user:2:name"
3) "product:1:price" - 警告:
KEYS
コマンドは、データベース内の全てのキーをスキャンするため、多数のキーが存在する本番環境では絶対に使用しないでください。サーバーがブロックされ、アプリケーションに深刻な影響を与える可能性があります。代わりに、後述するSCAN
コマンドを使用してください。
SCAN cursor [MATCH pattern] [COUNT count]
データベース内のキーをイテレーションするための安全なコマンドです。
- 構文:
SCAN cursor [MATCH pattern] [COUNT count]
- 説明:
KEYS
の代替として、データベース内のキーを少しずつ取得します。cursor
はイテレーションの状態を表す数値で、最初の呼び出しでは0を指定します。コマンドの応答には、次に使用すべきカーソル値と、取得されたキーのリストが含まれます。取得されたカーソルが0になるまで、そのカーソル値を使ってSCAN
を繰り返します。 - 戻り値: 次のカーソル値と、取得されたキーのリスト。
- 例:
127.0.0.1:6379> SCAN 0
1) "4" # 次に使用すべきカーソル
2) 1) "key:1"
2) "key:100"
3) "user:1:name" # 今回取得されたキーのリスト (一部)
127.0.0.1:6379> SCAN 4 # 前回の応答のカーソル値を使用
1) "0" # 次のカーソルが0なのでイテレーション終了
2) 1) "product:1:price"
2) "user:2:name" # 今回取得されたキーのリスト (残り) - 注意:
SCAN
はイテレーション開始後のキーの変更(追加、削除など)を完全に保証するものではありません(イテレーション中に変更されたキーが結果に含まれたり、含まれなかったりする可能性があります)。しかし、サーバーをブロックしないため、本番環境でのキーのスキャンには必ずSCAN
を使用してください。
TYPE key
指定したキーに格納されている値のデータ型を取得します。
- 構文:
TYPE key
- 説明: キーに格納されている値のデータ型(string, list, hash, set, zset, streamなど)を返します。キーが存在しない場合は
none
を返します。 - 例:
127.0.0.1:6379> SET mykey "hello"
OK
127.0.0.1:6379> TYPE mykey
string
127.0.0.1:6379> RPUSH mylist 1 2 3
(integer) 3
127.0.0.1:6379> TYPE mylist
list
127.0.0.1:6379> TYPE nonexistingkey
none
SELECT index
接続しているデータベースを選択します。Redisはデフォルトで16個(0から15)の論理データベースを持っています。
- 構文:
SELECT index
- 説明: 0から始まるインデックスで指定されたデータベースを選択します。デフォルトはデータベース0です。各データベースは独立しており、キーは共有されません。
- 例:
127.0.0.1:6379> SELECT 1 # データベース1に切り替え
OK
127.0.0.1:6379[1]> SET mykey "value_in_db1"
OK
127.0.0.1:6379[1]> SELECT 0 # データベース0に戻る
OK
127.0.0.1:6379> GET mykey # データベース0には存在しない
(nil)
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> GET mykey # データベース1には存在する
"value_in_db1" - 注意: 多くの本番環境では、データベースを分けずに一つのデータベースを使うか、Redis Clusterを利用してシャーディングを行うのが一般的です。異なるデータベースを使う場合でも、アプリケーション側でデータベースインデックスを適切に管理する必要があります。
DBSIZE
現在選択されているデータベースに含まれるキーの数を取得します。
- 構文:
DBSIZE
- 説明: 現在のデータベースに含まれるキーの総数を返します。
- 例:
127.0.0.1:6379> DBSIZE
(integer) 3 # 例:現在のデータベースに3つのキーがある
FLUSHDB
/ FLUSHALL
データベース内の全てのキーを削除します。
- 構文:
FLUSHDB
,FLUSHALL
- 説明:
FLUSHDB
: 現在選択されているデータベースの全てのキーを削除します。FLUSHALL
: Redisサーバー上の全てのデータベースの全てのキーを削除します。
- 警告: これらのコマンドはデータを完全に削除するため、本番環境での実行は非常に慎重に行う必要があります。開発やテスト用途で利用するのが一般的です。
PING
サーバーが応答するか確認します。
- 構文:
PING
- 説明: Redisサーバーへの接続が生きているかを確認します。サーバーが正常であれば
PONG
を返します。 - 例:
127.0.0.1:6379> PING
PONG
INFO [section]
Redisサーバーに関する様々な情報を取得します。
- 構文:
INFO [section]
- 説明: Redisサーバーのバージョン、稼働時間、メモリ使用量、レプリケーション状態、統計情報など、詳細な情報を返します。
section
を指定すると、特定のカテゴリの情報のみを取得できます(例:info memory
,info clients
,info stats
)。 - 例:
127.0.0.1:6379> INFO server # サーバー情報を取得
# Server
redis_version:7.2.4
redis_git_sha1:a9232950
... (その他多くの情報)
127.0.0.1:6379> INFO memory # メモリ使用量情報を取得
# Memory
used_memory:1002480
used_memory_human:979.00K
...
QUIT
Redisサーバーへの接続を閉じます。
- 構文:
QUIT
- 説明: 現在のクライアント接続を閉じます。
高度な機能と関連コマンド
Redisは基本的なデータ操作だけでなく、分散システムで役立つ高度な機能も提供しています。
トランザクション
Redisのトランザクションは、複数のコマンドをグループ化し、アトミックに(不可分に)実行するための機能です。MULTI
, EXEC
, DISCARD
, WATCH
コマンドを使用します。
MULTI
トランザクションの開始を宣言します。これ以降に送信されたコマンドは、キューに積まれてすぐに実行されず、EXEC
コマンドが実行されるまで待機します。
- 構文:
MULTI
- 説明: トランザクションモードに入ります。成功すると
OK
を返します。 - 例:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET mykey "hello" # このコマンドはキューに積まれる
QUEUED
127.0.0.1:6379> INCR counter # このコマンドもキューに積まれる
QUEUED
127.0.0.1:6379> GET mykey # この時点ではまだ値は設定されていない
QUEUED
EXEC
MULTI
で開始されたトランザクション内の全てのコマンドを順番に実行します。
- 構文:
EXEC
- 説明: キューに積まれた全てのコマンドを実行します。各コマンドの実行結果がリストとして返されます。トランザクション中に
WATCH
で監視していたキーが変更されていない場合にのみ、コマンドは実行されます。 - 例:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET mykey "hello"
QUEUED
127.0.0.1:6379> INCR counter
QUEUED
127.0.0.1:6379> EXEC # ここで全てのコマンドが実行される
1) OK # SET mykey "hello" の結果
2) (integer) 1 # INCR counter の結果 (counterが新しければ0->1)
もしWATCH
していたキーがトランザクション開始からEXEC
までの間に変更された場合、EXEC
は(nil)
を返し、トランザクション内のコマンドは何も実行されません。
DISCARD
MULTI
で開始されたトランザクションを破棄し、キューに積まれた全てのコマンドをクリアします。
- 構文:
DISCARD
- 説明: トランザクションモードを終了し、キュー内のコマンドを実行せずに捨てます。
- 例:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET tempkey "some value"
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> GET tempkey # コマンドは実行されなかったので値は設定されていない
(nil)
WATCH key [key ...]
トランザクションの実行前に、1つ以上のキーの変更を監視します。監視しているキーがEXEC
実行前に他のクライアントによって変更された場合、トランザクションはアボートされます(実行されない)。
- 構文:
WATCH key [key ...]
- 説明: トランザクションを開始する
MULTI
コマンドの前に実行する必要があります。監視対象のキーがWATCH
実行後からEXEC
実行までの間に少しでも変更された場合、そのトランザクションは失敗します。 -
例:
“`
# クライアントA
127.0.0.1:6379> WATCH counter
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR counter # クライアントAはcounterをインクリメントしようとする
QUEUEDクライアントB (クライアントAの WATCH/MULTI の間に実行)
127.0.0.1:6379> INCR counter
(integer) 1クライアントA に戻る
127.0.0.1:6379> EXEC # WATCHしていたcounterがクライアントBによって変更されているため失敗
(nil) # トランザクションがアボートされた
``
(nil)`応答を受け取ったクライアントは、操作を再試行する必要があります。
この
パブリッシュ/サブスクライブ (Pub/Sub)
Redisは、軽量なメッセージングシステムとしても機能します。クライアントは特定の「チャンネル」にメッセージを発行(Publish)したり、特定のチャンネルを購読(Subscribe)したりできます。
PUBLISH channel message
指定したチャンネルにメッセージを発行します。そのチャンネルを購読している全てのクライアントにメッセージが配信されます。
- 構文:
PUBLISH channel message
- 説明:
channel
という名前のチャンネルにmessage
を送信します。メッセージは文字列です。 - 戻り値: メッセージを受信した購読者の数。
- 例:
127.0.0.1:6379> PUBLISH news "Hello subscribers!"
(integer) 2 # 例:2人の購読者がメッセージを受信した
SUBSCRIBE channel [channel ...]
1つ以上のチャンネルを購読します。このコマンドを実行したクライアントは、指定したチャンネルにメッセージが発行されるたびにそれを受信するようになります。
- 構文:
SUBSCRIBE channel [channel ...]
- 説明: 指定されたチャンネルを購読します。このコマンドを実行したクライアントは、他のコマンドを実行できなくなります(Redisの接続は通常、Pub/Sub専用になります)。購読を解除するには、別の接続から
UNSUBSCRIBE
コマンドを実行する必要があります。 -
例:
“`
# クライアントA (SUBSCRIBEを実行)
127.0.0.1:6379> SUBSCRIBE chat
Reading messages… (press Ctrl-C to quit)
1) “subscribe” # 購読確認
2) “chat”
3) (integer) 1クライアントB (別の接続から PUBLISH を実行)
127.0.0.1:6379> PUBLISH chat “Hello, chat room!”
(integer) 1 # クライアントAが受信したクライアントA (メッセージを受信)
1) “message”
2) “chat”
3) “Hello, chat room!”
``
PSUBSCRIBE pattern [pattern …]
* 関連コマンド:(パターンに一致するチャンネルを購読する),
UNSUBSCRIBE [channel …](チャンネルの購読を解除する),
PUNSUBSCRIBE [pattern …]` (パターンの購読を解除する)
スクリプティング (Luaスクリプト)
RedisはLuaスクリプトの実行をサポートしています。これにより、複数のコマンドをサーバーサイドでアトミックに実行したり、複雑なロジックを実装したりできます。
EVAL script numkeys key [key ...] arg [arg ...]
指定したLuaスクリプトをRedisサーバー上で実行します。
- 構文:
EVAL script numkeys key [key ...] arg [arg ...]
- 説明:
script
として渡されたLuaスクリプトを実行します。スクリプトはサーバー上で実行されるため、ネットワークラウンドトリップを減らし、複数の操作をアトミックに行うことができます。numkeys
はスクリプトで使用するキーの数を示し、それに続いてkey
のリスト、その後arg
(その他の引数)のリストを渡します。スクリプト内では、KEYS
グローバル変数でキーのリスト、ARGV
グローバル変数でその他の引数のリストにアクセスできます。 -
例:
127.0.0.1:6379> EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey "hello_from_script"
OK
127.0.0.1:6379> GET mykey
"hello_from_script"
より複雑な例:キーが存在しない場合のみSETし、成功したら1、失敗したら0を返すスクリプト127.0.0.1:6379> EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey "new value"
(integer) 0 # mykeyは既に存在するので設定されない
127.0.0.1:6379> DEL mykey
(integer) 1
127.0.0.1:6379> EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey "new value"
(integer) 1 # mykeyは存在しないので設定される
* 注意: Luaスクリプトはサーバー上で実行中、Redisをシングルスレッドでブロックします。実行時間の長いスクリプトは他のクライアントの処理を遅延させる可能性があるため注意が必要です。
実践的な使い方と考慮事項
Redisを効果的に活用するためには、コマンドの使い方だけでなく、いくつかの実践的な考慮事項があります。
キー設計のベストプラクティス
- 可読性と構造: キー名には、コロン (
:
) を使って階層構造を持たせると、管理しやすくなります。例えば、object_type:id:field
のような形式(例:user:100:profile
,product:abc:price
)。 - 短さと一意性: キーは短く保つことでメモリ使用量を抑えられますが、同時にアプリケーション全体で一意になるように設計する必要があります。
- パターンの活用:
SCAN
,DEL
,EXPIRE
などのコマンドでパターンマッチングを利用することを想定してキーを設計すると、まとめて操作しやすくなります。
有効期限 (TTL) の活用
EXPIRE
, SETEX
などでキーに有効期限を設定することは、Redisをキャッシュとして利用する際に非常に重要です。
- メモリ管理: 不要になったデータが自動的に削除されるため、メモリの枯渇を防ぐのに役立ちます。
- データの一貫性: キャッシュされた古いデータが一定時間後に破棄されることで、オリジンデータとの乖離を最小限に抑えられます。
- アイドルデータの削除: セッション情報など、一定時間アクセスされないデータを自動削除するのに便利です。
パイプライン処理
複数のコマンドをまとめてサーバーに送信し、まとめて応答を受け取る「パイプライン処理」は、Redisのパフォーマンスを大幅に向上させる重要なテクニックです。クライアントライブラリの多くがパイプラインをサポートしています。
個々のコマンドを逐次実行するのではなく、まとめて送信することで、ネットワークのラウンドトリップ時間を短縮できます。例えば100個のSETコマンドを実行する場合、100回のネットワーク往復が必要な通常の実行と比べ、パイプラインなら1回の往復で済みます。
“`
通常の逐次実行
SET key1 value1 -> (往復) -> OK
SET key2 value2 -> (往復) -> OK
…
パイプライン
SET key1 value1 (バッファに積む)
SET key2 value2 (バッファに積む)
…
EXECUTE (まとめて送信) -> (往復) -> OK, OK, … (まとめて応答を受け取る)
“`
メモリ管理
Redisはインメモリデータベースであるため、利用可能なメモリ容量は重要な制約となります。
- 最大メモリ設定:
maxmemory
設定でRedisが使用する最大メモリ量を制限し、メモリ枯渇を防ぐことができます。 - Evictionポリシー:
maxmemory-policy
設定で、最大メモリに達した際にどのキーを削除するか(最近使われていないキー、有効期限の近いキー、ランダムなど)を指定できます。 - 監視:
INFO memory
コマンドや監視ツールを使用して、メモリ使用量を常に監視することが推奨されます。
セキュリティ
- パスワード認証:
requirepass
設定でパスワードを設定し、AUTH
コマンドで認証を行うようにします。 - ネットワーク制限: Redisポート (デフォルト6379) は、信頼できるクライアントからのみアクセス可能になるようにファイアウォールなどで制限します。
- コマンドの無効化/名前変更: 危険なコマンド(
KEYS
,FLUSHALL
など)は、設定ファイルで無効化したり、推測されにくい名前に変更したりすることを検討します。
まとめ
この記事では、インメモリデータ構造ストアであるRedisの基本的な概念から、主要なデータ構造(String, List, Hash, Set, Sorted Set)に対応するよく使うコマンド、さらにはキー操作、トランザクション、Pub/Sub、スクリプティングといった応用的な機能まで、幅広く解説しました。
Redisの最大の魅力は、その圧倒的な速度と、様々なデータ構造を直接扱える柔軟性です。これらの特性を活かすことで、キャッシュ、セッション管理、メッセージキュー、リアルタイムランキングなど、多岐にわたるアプリケーション機能を効率的に実装できます。
ご紹介したコマンドは、Redisを使い始める上で必要となる基本的な操作を網羅しています。これらのコマンドを理解し、使いこなすことが、Redisの能力を最大限に引き出す第一歩となります。
Redisの学習は、ここで紹介したコマンドから始めて、徐々に高度な機能や運用のベストプラクティスへと広げていくのがおすすめです。公式ドキュメントは非常に充実しており、さらに深く学びたい場合の強力なリソースとなります。
高速でスケーラブルなアプリケーション開発において、Redisは強力な味方となるでしょう。ぜひこの記事で学んだ知識を活かして、あなたのプロジェクトにRedisを導入してみてください。
これで、よく使うRedisコマンド一覧と使い方を徹底紹介する約5000語の詳細な記事の作成は完了です。