Redis の特徴
Redisはメモリー上にデータを保存するKey-Value型のNoSQLデータベースのひとつ。用途はデータベースだけにとどまらず、キャッシュやメッセージブローカーとしても利用される。
In-Memory Database
RedisはIn-Memory Databaseなので、On-Disk Databaseと比べ非常に高速に動作する。ちなみにIn-Memory DatabaseとOn-Disk Databaseの違いは以下のとおり。- インメモリデータベース(In-Memory Database, Main-Memory Database, IMDM)
- メモリー上にデータを格納するDBMS(データベース管理システム)
- オンディスクデータベースと比較すると、高速で安定したパフォーマンスを提供できる
- 揮発性メモリー上で動作する性質上、電源喪失などによりデータが失われるリスクがある(永続化も可能)
- オンディスクデータベース(On-Disk Database, Disk-Based Database)
- ディスク上にデータを格納するDBMS
- ディスクに保存するので、データが失われるリスクは最小限に抑えられる
- インメモリデータベースと比較すると、ディスクにアクセスする分、低速になる
- ハイブリッド型データベース
- インメモリデータベースとオンディスクデータベースのいいとこ取り
シングルスレッドで動作する
Redisはシングルスレッドで動作するため、必然的にアトミックなデータ操作(排他的)になる。その反面、CPUのコア数が増えてもスケールしないため、CPU使用率がボトルネックになりやすい。マルチコアで使いたい場合は、コア数分のRedisサーバーを起動する必要がある。
Luaスクリプティング
Redis上でスクリプト言語のLuaを実行できる。あらかじめRedisにスクリプトを登録しておくことで、高度な計算処理などをRedis側に任せることができる。ただし、シングルスレッドという特徴があるので、スクリプト実行中は他のリクエストをブロックしてしまう。
レプリケーション
MASTER-SLAVE型のレプリケーションを構築できる。マスターは複数のスレーブを持つことができ、非同期でレプリケーションを行っている。そのため完全に動悸されるまでの間はマスターとスレーブに差異が生じることがある。データの永続化
Redisはデータの永続化オプションを提供している。- 揮発性ベース
- メモリーでデータを管理する
- サーバーを落とすとすべてのデータが失われる
- RDBベース
- 特定間隔でデータのスナップショットを保存する
- バックアップファイルがコンパクト
- 永続化はできるが、非同期スナップショットなので一部データが失われる可能性がある
- AOFベース
- サーバーが受け付けたすべての書き込みコマンドを保存する
- デフォルトは毎秒同期保存する
- fsyncを行わない、毎秒fsyncする、すべてのクエリごとにfsyncするから選択できる
- RDBファイルよりも大きくなる
などなど。
他にもクラスタ機能やPub/Sub機能などがある。
Redisをインストールする
Redisを触るためにインストールしなければならないのだが、ローカルマシンに直接インストールするのは気が引けるのでDockerを使う。イメージはRedisのOfficial Image。
# インストール
$ docker run -p 6379:6379 --name learning-redis -d redis
# コンテナにログイン
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
71d9b07574f4 redis "docker-entrypoint.s…" 3 seconds ago Up 1 second 0.0.0.0:6379->6379/tcp learning-redis
$ docker exec -it learning-redis /bin/bash
これでredis-server, redis-cliが使えるようになった。
他の方法でインストールする場合は、Downloadドキュメントを参照ください。
Redisを起動する
# Redisサーバーを起動する
$ redis-server
23:C 15 Feb 2019 07:05:26.641 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
23:C 15 Feb 2019 07:05:26.641 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=23, just started
23:C 15 Feb 2019 07:05:26.641 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
23:M 15 Feb 2019 07:05:26.642 # Could not create server TCP listening socket *:6379: bind: Address already in use
# Redisサーバーが動いているか確認する
$ redis-cli ping
PONG
引数なしでredis-serverコマンドを実行すると、デフォルト設定の状態でRedisが起動する。通常は/etc/redis.confに設定ファイルがあるのだが、Dockerのオフィシャルイメージには含まれていないので注意。参考: Additionally, If you want to use your own redis.conf | redis - Docker Hub
Redisのデータ構造
Redisはいくつかのデータ構造がサポートしている。
- 文字列型: Binary-safe strings
- すべてのデータの基本となる型
- バイナリセーフでどんな値でも扱える
- 最大1GBまで
- リスト型: Lists(Linked list)
- 文字列型のリスト
- 先頭/末尾に値の追加ができる
- リスト長をキャッシュして高速に取得できる
- セット型: Sets
- 文字列型の順不同のコレクション
- 同じメンバを重複して登録できない
- 2つのセットで集合演算が使える
- ソート済みセット型: Sorted sets
- 基本はセット型と同じ
- スコアの値でソートされた順位を持っている
- ハッシュ型: Hashes
- 順序がない文字列型のフィールドと値のマップ
- フィールド値で検索できる
- 値指定の検索は不可
- Bit arrays
- 特殊なコマンドで文字列をビット配列のように扱える
- HyperLogLogs
- 確率的なデータ構造
- Streams
- 時系列データを扱う
- インデックスにはタイムスタンプを使う
各データ型の基本操作(追加/取得/削除)
# Redisに接続
$ redis-cli
127.0.0.1:6379>
文字列型
# データの追加: set key value
127.0.0.1:6379> set mykey somevalue
OK
# データの取得: get key
127.0.0.1:6379> get mykey
"somevalue"
# データの更新: set key value [xx|nx]
## 上書きを許可する場合
127.0.0.1:6379> set mykey hoge
OK
# or
127.0.0.1:6379> set mykey hoge xx
OK
127.0.0.1:6379> get mykey
"hoge"
## 上書きを許可しない場合
127.0.0.1:6379> set mykey fuga nx
(nil)
127.0.0.1:6379> get mykey
"hoge"
# まとめて追加: mset key value [key value ...]
127.0.0.1:6379> mset a hoge b fuga c piyo
OK
# まとめて取得: mget key [key ...]
127.0.0.1:6379> mget a b c
1) "hoge"
2) "fuga"
3) "piyo"
# 削除: del key [key ...]
127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> get mykey
(nil)
リスト型
# リストの末尾に追加: rpush key value [value ...]
127.0.0.1:6379> rpush mylist A
(integer) 1
127.0.0.1:6379> rpush mylist B
(integer) 2
# リストの先頭に追加: lpush key value [value ...]
127.0.0.1:6379> rpush mylist first
# リストの要素を取得: lrange key start stop
# start, stopはリストのインデックスを指定。負の値は末尾からカウント(-1は最後の要素、-2は最後から2番目の要素)
127.0.0.1:6379> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
# リストの末尾から要素を取り出す: rpop key
127.0.0.1:6379> rpop mylist
"B"
127.0.0.1:6379> lrange mylist 0 -1
1) "first"
2) "A"
# リストの先頭から要素を取り出す: lpop key
127.0.0.1:6379> lpop mylist
"first"
127.0.0.1:6379> lrange mylist 0 -1
1) "A"
セット型
# セットの追加: sadd key member [member ...]
127.0.0.1:6379> sadd myset 1 2 3
(integer) 3
# メンバーを取得: smembers key
127.0.0.1:6379> smembers myset
1) "1"
2) "2"
3) "3"
# セット内に含まれるメンバーか確認: sismember key member
127.0.0.1:6379> sismember myset 2
(integer) 1
127.0.0.1:6379> sismember myset 20
(integer) 0
ソート済みセット型
# ソート済みセットの追加: zadd [nx|xx] [ch] [incr] score member [score member ...]
127.0.0.1:6379> zadd hackers 1940 "Alan Kay"
(integer) 1
127.0.0.1:6379> zadd hackers 1957 "Sophie Wilson" 1953 "Richard Stallman" 1949 "Anita Borg"
(integer) 3
# ソート済みセットの取得: zrange key start stop [withscores]
# scoreでソートされた状態で取得できる
127.0.0.1:6379> zrange hackers 0 -1
1) "Alan Kay"
2) "Anita Borg"
3) "Richard Stallman"
4) "Sophie Wilson"
# 逆順に取得: zrevrange key start stop [withscores]
127.0.0.1:6379> zrevrange hackers 0 -1
1) "Sophie Wilson"
2) "Richard Stallman"
3) "Anita Borg"
4) "Alan Kay"
# スコア付きで取得
127.0.0.1:6379> zrange hackers 0 -1 withscores
1) "Alan Kay"
2) "1940"
3) "Anita Borg"
4) "1949"
5) "Richard Stallman"
6) "1953"
7) "Sophie Wilson"
8) "1957"
ハッシュ型
# ハッシュの追加: hmset key field value [field value ...]
127.0.0.1:6379> hmset user:1000 username bc_rikko age 19 verified 1
OK
# ハッシュのフィールドを取得: hget key field [field ...]
127.0.0.1:6379> hget user:1000 username
"bc_rikko"
127.0.0.1:6379> hget user:1000 age
"19"
# すべて取得: hgetall key
127.0.0.1:6379> hgetall user:1000
1) "username"
2) "bc_rikko"
3) "age"
4) "19"
5) "verified"
6) "1"
よく使うコマンド
# 登録されているKeyを取得: keys pattern
127.0.0.1:6379> keys *
1) "hackers"
2) "a"
3) "c"
4) "b"
5) "user:1000"
6) "myset"
7) "mylist"
# globで指定できる
127.0.0.1:6379> keys my*
1) "myset"
2) "mylist"
# ヘルプを表示: help command
127.0.0.1:6379> help set
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
summary: Set the string value of a key
since: 1.0.0
group: string
# 全ヘルプを表示
127.0.0.1:6379> help @list
BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one is available
since: 2.0.0
BRPOPLPUSH source destination timeout
summary: Pop a value from a list, push it to another list and return it; or block until one is available
since: 2.2.0
......
Node.jsからRedisに接続する。
redis-cliを使った基本的な操作は学んだので、次はNode.jsからRedisに接続する。
公式ドキュメントのクライアントページにいくつかサードパーティ製のライブラリが紹介されている。公式的にはioredisとnode_redisを推奨しているみたい。
今回はioredisを使う。理由はなんとなく。
# ライブラリのインストール
$ npm i ioredis
const Redis = require("ioredis");
// 接続
const redis = new Redis({
host: "127.0.0.1",
port: 6379
});
redis.on("error", console.error);
redis.on("connect", () => {
console.info("Connected");
});
redis.on("close", () => {
console.info("Disconnected");
});
// データ保存
redis.set("key", "value");
// データ取得
redis
.get("key")
.then(result => {
console.log(result);
})
.catch(err => {
console.error(err);
});
// 切断
redis.quit();
参考サイト
以上
written by @bc_rikko
0 件のコメント :
コメントを投稿