Redisをインストールして各データ型を試す

Redisをインストールして基本のデータ型を試してみたメモです。


Redis 4.0.1を使用してみます。
Ubuntu16にインストールして試してみます。

インストール

インストールはソースを取得、解凍してmakeするだけです。

$ wget http://download.redis.io/releases/redis-4.0.1.tar.gz
$ tar xzf redis-4.0.1.tar.gz
$ cd redis-4.0.1
$ make

起動

インストールしたディレクトリで下記コマンドでredis-serverを起動します。

$ src/redis-server

17739:C 19 Sep 02:26:44.779 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
17739:C 19 Sep 02:26:44.779 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=17739, just started
17739:C 19 Sep 02:26:44.779 # Warning: no config file specified, using the default config. In order to specify a config file use src/redis-server /path/to/redis.conf
17739:M 19 Sep 02:26:44.780 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 4.0.1 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 17739
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

17739:M 19 Sep 02:26:44.780 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
17739:M 19 Sep 02:26:44.780 # Server initialized
17739:M 19 Sep 02:26:44.780 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
17739:M 19 Sep 02:26:44.780 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
17739:M 19 Sep 02:26:44.780 * Ready to accept connections

client

redis-cliは標準で付属している対話型クライアントです。
redis-cliでredis-serverにアクセスして操作してみます。

データ型

各データ型の基本のコマンドだけ確認してみます。

Strings

StringsはRedisの一番基本の型です。
普通のキーバリューストアのように扱えます。

set, get

setで指定したキーに値を設定。
getで指定したキーの値をフェッチ。

> set my_key my_value
OK

> get my_key
"my_value"
del

delで指定したキーの値を削除。

> del my_key
(integer) 1

> get my_key
(nil)
xx, nx

xxオプションを付与すると既に値が存在する場合だけ設定され、
nxオプションを付与すると値が存在しない場合だけ設定される。

> get new_key
(nil)

# nx 存在しないキーの場合は設定される
> set new_key new_val nx
OK

> get new_key
"new_val"

# nx 存在しているキーの場合は設定されない
> set new_key new!! nx
(nil)

> get new_key
"new_val"

# xx 存在しているキーの場合は設定される
> set new_key new!!!  xx
OK

> get new_key
"new!!!"

# xx 存在しないキーの場合は設定されない
> set xxx_key abc xx
(nil)

> get xxx_key
(nil)
incr, decr

incrで値をインクリメント、
decrで値をデクリメント。
数値を指定するとその値分インクリメント、デクリメントされる。

> set my_count 100
OK
> incr my_count
(integer) 101
> incr my_count
(integer) 102
> incrby my_count 10
(integer) 112
> decr my_count
(integer) 111
> decr my_count
(integer) 110
> decrby my_count 10
(integer) 100
mset, mget

msetで複数の値を一度にセットできる。
mgetで複数の値を一度にフェッチできる。

> mset AAA 111 BBB 222 CCC 333
OK
> mget AAA BBB CCC
1) "111"
2) "222"
3) "333"
> mget AAA BBB CCC DDD
1) "111"
2) "222"
3) "333"
4) (nil)
exists

existsで指定したキーが存在する場合1、存在しない場合0

> exists AAA
(integer) 1
> exists DDD
(integer) 0

> del AAA
(integer) 1
> exists AAA
(integer) 0
expire

expireで対象キーの存続時間(秒)を指定できる。
存続時間を過るとキーは自動的に削除される。

> expire my_key 5
(integer) 1

# 直後に値を取得
> get my_key
"abcde"

# しばらくして値を取得
> get my_key
(nil)

List

ListはStringのリスト構造の型です。
Setとは異なり重複した値を持てます。

rpush

rpushでListの末尾に追加

> rpush my_list aaa
(integer) 1

> rpush my_list bbb
(integer) 2

> rpush my_list ccc
(integer) 3

> rpush my_list ddd
(integer) 4

> lrange my_list 0 -1
1) "aaa"
2) "bbb"
3) "ccc"
4) "ddd"

# 複数の値を一度にrpush可能
> rpush my_list aaa bbb ccc ddd
(integer) 4
lindex

指定したインデックスの要素を取得

> lindex my_list 0
"aaa"

> lindex my_list 2
"ccc"
lrange

指定した範囲の要素を取得。
第1引数は開始するインデックス、第2引数は終了するインデックス。

> lrange my_list 0 2
1) "aaa"
2) "bbb"
3) "ccc"

> lrange my_list 1 3
1) "bbb"
2) "ccc"
3) "ddd"

# -1は末尾の要素を指す
> lrange my_list 0 -1
1) "aaa"
2) "bbb"
3) "ccc"
4) "ddd"
lpush

リストの先頭に指定された要素を挿入。

> lpush my_list aa
(integer) 5

> lrange my_list 0 -1
1) "aa"
2) "aaa"
3) "bbb"
4) "ccc"
5) "ddd"
lpop, rpop

lpopでリストの最初の要素を削除して取得。
rpopでリストの末尾の要素を削除して取得。

> lpop my_list
"aa"

> lrange my_list 0 -1
1) "aaa"
2) "bbb"
3) "ccc"
4) "ddd"

> rpop my_list
"ddd"

> lrange my_list 0 -1
1) "aaa"
2) "bbb"
3) "ccc"
ltrim

指定した範囲を残すようにリストをトリムする。
第1引数は開始するインデックス、第2引数は終了するインデックス。

> lrange my_list 0 -1
1) "aaa"
2) "bbb"
3) "ccc"
4) "ddd"

> ltrim my_list 0 1
OK

> lrange my_list 0 -1
1) "aaa"
2) "bbb"

Set

Setは一意なStringの集合の型です。
Listとは異なり順序は持ちません。

sadd, smembers

saddでセットに要素を追加。
smembersでセットに含まれるすべての要素を取得。

> sadd my_set AAA
(integer) 1

> sadd my_set BBB
(integer) 1

> sadd my_set CCC
(integer) 1

> sadd my_set AAA
(integer) 0

> smembers my_set
1) "CCC"
2) "BBB"
3) "AAA"

# 複数の要素を一度に追加可能
> sadd my_set AAA BBB CCC
(integer) 3

> smembers my_set
1) "CCC"
2) "BBB"
3) "AAA"
spop

ランダムに要素を削除して取得。

> smembers my_set
1) "CCC"
2) "BBB"
3) "AAA"

> spop my_set
"BBB"

> smembers my_set
1) "CCC"
2) "AAA"
sismember

指定した要素が格納されているかどうか。

> sismember my_set AAA
(integer) 1

> sismember my_set DDD
(integer) 0
srem

指定した要素を削除.

> srem my_set BBB
(integer) 1

> smembers my_set
1) "CCC"
2) "AAA"

Hash

Hashはフィールドと値のマッピングを持つ型です。
JavaのMapに近いです。

hset, hget, hgetall, hdel

hsetで指定したフィールドに値を設定。
hgetで指定したフィールドの値を取得。
hgetallで指定したキーのすべてのフィールドと値を取得。
hdelで指定したフィールドを削除。

> hset my_hash aaa 111
(integer) 1

> hset my_hash bbb 222
(integer) 1

> hset my_hash ccc 333
(integer) 1

> hget my_hash aaa
"111"

> hget my_hash bbb
"222"

> hgetall my_hash
1) "aaa"
2) "111"
3) "bbb"
4) "222"
5) "ccc"
6) "333"

> hdel my_hash ccc
(integer) 1

> hgetall my_hash
1) "aaa"
2) "111"
3) "bbb"
4) "222"
hmset, hmget

hmsetで指定したフィールドと値をまとめて設定。
hmgetで指定したフィールドの値をまとめて取得。

> hmset my_hash aaa 111 bbb 222 ccc 333
OK

> hgetall my_hash
1) "aaa"
2) "111"
3) "bbb"
4) "222"
5) "ccc"
6) "333"

> hmget my_hash aaa ccc
1) "111"
2) "333"
hincrby

指定したフィールドの値をインクリメント。

> hget my_hash aaa
"111"

> hincrby my_hash aaa 1
(integer) 112

> hget my_hash aaa
"112"

> hincrby my_hash aaa 100
(integer) 212

> hget my_hash aaa
"212"

zset(Sorted Set)

zsetはソートされたSetです。
各キー(メンバ)に対してスコアを持ち、スコアによってソートされ、
スコアの値や範囲を指定してメンバを取得することが出来ます。

zadd

zsetに第1引数で指定したスコアで、第2引数のメンバを登録。

> zadd my_zset 111 member1
(integer) 1

> zadd my_zset 222 member2
(integer) 1

> zadd my_zset 333 member3
(integer) 1
zrange

指定した範囲のメンバを返す。
第1引数は開始するインデックス、第2引数は終了するインデックス。
withscoresオプションを指定すると、スコアも同時に返す。

> zrange my_zset 0 -1
1) "member1"
2) "member2"
3) "member3"

> zrange my_zset 0 -1 withscores
1) "member1"
2) "111"
3) "member2"
4) "222"
5) "member3"
6) "333"
zrangebyscore

第1引数と第2引数の間のスコアを持つ要素を返す。
withscoresオプションを指定すると、スコアも同時に返す。

> zrangebyscore my_zset 0 100 withscores
(empty list or set)

> zrangebyscore my_zset 0 150 withscores
1) "member1"
2) "111"

> zrangebyscore my_zset 100 230 withscores
1) "member1"
2) "111"
3) "member2"
4) "222"

第1引数と第2引数にはinfを指定することが可能。
+infでプラスの無限大を表し、-infでマイナスの無限大を表す。

> zrangebyscore my_zset -inf 300
1) "member1"
2) "member2"

> zrangebyscore my_zset 200 +inf
1) "member2"
2) "member3"
zrem

指定されたメンバを削除する。

> zrange my_zset 0 -1 withscores
1) "member1"
2) "111"
3) "member2"
4) "222"
5) "member3"
6) "333"

> zrem my_zset member1
(integer) 1

> zrange my_zset 0 -1 withscores
1) "member2"
2) "222"
3) "member3"
4) "333"
zremrangebyscore

第1引数と第2引数の間のスコアを持つ要素を削除する。

> zrange my_zset 0 -1 withscores
1) "member1"
2) "111"
3) "member2"
4) "222"
5) "member3"
6) "333"

> zremrangebyscore my_zset 200 400
(integer) 2

> zrange my_zset 0 -1 withscores
1) "member1"
2) "111"

トランザクション

RedisのトランザクションRDBトランザクションとは異なり、
操作したすべてのコマンドが他のクライアントから割り込まれること無く実行されることを指します。

MULTI, EXEC

MULTIでトランザクションを開始し、後続のコマンドはキューに入ります。
EXECでキューにあるすべてのコマンドを実行し、トランザクションを終了します。

> multi
OK

> rpush user_list bob
QUEUED
> incr counter
QUEUED
> rpush user_list alice
QUEUED
> incr counter
QUEUED

> exec
1) (integer) 1
2) (integer) 1
3 (integer) 2
4) (integer) 2

rpush,incrした後、execする前に別のクライアントから値を取得してもnil

> lrange user_list 0 -1
(empty list or set)

> get counter
(nil)

exec後に再度別のクライアントから取得

> lrange user_list 0 -1
1) "bob"
2) "alice"

> get counter
"2"
DISCARD

キューに入れられたすべてのコマンドをトランザクション内でフラッシュします。
トランザクションは解除されます。

> get counter
"2"

> multi
OK

> incr counter
QUEUED
> incr counter
QUEUED

> discard
OK

> get counter
"2"
WATCH

WATCHで指定したキーを監視します。
監視していたキーが他のクライアントから更新されると、EXECした際にエラーになります。

> get counter
"3"

> watch counter
OK

> multi
OK

> rpush user_list cindy
QUEUED
> incr counter
QUEUED

上のmultiの後に別クライアントからcounterを更新

> get counter
"3"

# multiのあとに実行
> incr counter
(integer) 4

元のトランザクションのクライアントでexecを実行。

# execの戻り値がnil
> exec
(nil)

# このトランザクションでのincrが反映されていない
> get counter
"4"

> lrange user_list 0 -1
1) "bob"
2) "alice"
UNWATCH

WATCHで監視対象となったすべてのキーをフラッシュします。
execかdiscardを呼び出した場合は自動でフラッシュされます。(手動でunwatch不要)

> get counter
"6"

> watch counter
OK

> unwatch
OK

> multi
OK

> incr counter
QUEUED

> exec
1) (integer) 8

> get counter
"8"

上のmultiの後に別クライアントからcounterを更新

> get counter
"6"

# multiのあとに実行
> incr counter
(integer) 7


終わり。