忙しい人のためのRedisチュートリアル
この記事は何?
RedisConf19参加にあたり, Redisのdocsをしっかり読み込んだことがなかったため実施した. 量が多いため, 途中から要約だけ載せる.(疲れたので)
なお, 現時点でのlatest stableはRedis v5.0.4である.
commands
データ型はstring, bit, hash, list, set, sorted set, hyperloglog, streamと多種揃っている. 呼び出せるコマンドについては全てココにあるため, 今回は割愛する. 日本語のドキュメントだと, v2.0.3までの関数は以下にある. コマンドリファレンス — redis 2.0.3 documentation
stream type
v5.0.0から stream型エントリ のデータ管理方法が実装された. stream型は名前のとおり, 時系列データを扱うためのデータ型である. XADDやXRANGE, XDEL, XTRIMといった先頭にXのつくコマンドがstream用のコマンドとなっている. 例. XADDのdoc XADD – Redis
例えばXADDは, 同一keyに対して複数valuesを与える形で記述できる.
redis> XADD mystream * name Sara surname OConnor "1553778517432-0" redis> XRANGE mystream - + 1) 1) "1553778517432-0" 2) 1) "name" 2) "Sara" 3) "surname" 4) "OConnor" redis> XADD mystream * field1 value1 field2 value2 field3 value3 redis> XRANGE mystream - + 1) 1) "1553778517432-0" 2) 1) "name" 2) "Sara" 3) "surname" 4) "OConnor" 2) 1) "1553778517433-0" 2) 1) "field1" 2) "value1" 3) "field2" 4) "value2" 5) "field3" 6) "value3"
value登録時に発行される文字列をstream IDと呼ぶ. 例えば上記の例では"1553778517432-0"が該当する. ご覧の通り, stream IDは[unix msecのタイムスタンプ]-[シーケンス番号]と構成される.
以下参考.
qiita.com qiita.com streamのintroduction (とは思えない程の分量と内容) Redis Pub/Subを先に読むことを推奨 Introduction to Redis Streams – Redis
Pipelining
https://redis.io/topics/pipelining
TL;DR
ClientがRequestを発行してからServerがResponseし, Clientへ結果が戻るまでの時間をRoundTripTimeと呼ぶ. Server側がRequestを受信する度にResponseを返すのではなく, まとめて返事することで(server側の)system callsの実行回数が減り, レイテンシ低減する. それだけでなく, 時間辺りに実行できるクエリ数も増加する. できるだけpipeliningを使おう!←結論
Pub/Sub
https://redis.io/topics/pubsub
Apache Kafkaとか有名なやつ, メッセージングパターン.
TL;DR
例えばclientがsubscribeしたいとする. この時, clientはチャンネルをSUBSCRIBEコマンドで指定する. そしてチャンネルにpushされたメッセージは, それをsubscribeしている全clientに送信される. pushするにはPUBLISHコマンドを用いる. チャンネルのsubscribeをやめる場合は, UNSUBSCRIBEコマンドを用いる. Redis Pub/SubはパターンマッチングによるPub/Sub機能もある. それぞれPSUBSCRIBE, PUNSUBSCRIBEを使う. Pub/Sub subsystemの状態を見たい場合はPUBSUBコマンドを叩く.
以下参考.
Lua scripting
https://redis.io/commands/eval Luaスクリプトを実行できるよ!
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first" 4) "second"
RedisとLuaの相互型変換は可能らしい. ただし, 浮動小数で返してほしい場合はLua側が文字列として返す必要あり.
If you want to return a float from Lua you should return it as a string
あとSHA-1ハッシュ関数を使うEVALSHAコマンドもある.
transactions
トランザクションもあるよ. https://redis.io/topics/transactions
トランザクション — Redis Documentation (Japanese Translation)
トランザクション自体の説明は以下参考.
データベースさわったこと無い新人向けトランザクション入門 - Qiita
TL;DR
主にMULTI, EXEC, DISCARD, WATCHコマンドを使う.
> MULTI OK > INCR foo QUEUED > INCR bar QUEUED > EXEC 1) (integer) 1 2) (integer) 1
特徴として, コマンドがミスっていても, 実行可能なものは処理されてしまうという点には気をつけたい.
even when a command fails, all the other commands in the queue are processed
Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. MULTI +OK SET a 3 abc +QUEUED LPOP a +QUEUED EXEC *2 +OK -ERR Operation against a key holding the wrong kind of value
ロールバックはサポートされていない. 理由は - シンタックスが間違ってるときしか失敗しないから - ロールバックしなくても問題ないぐらい速い (もう一度実行しろってことかな)
DISCARDコマンドでトランザクションのabortが可能
> SET foo 1 OK > MULTI OK > INCR foo QUEUED > DISCARD OK > GET foo "1"
WATCHコマンドを使うと, 楽観的なロックが実現できる. WATCHコマンドは check-and-set の振る舞いを提供する. つまりWATCHコマンドで監視しているkeyに変更が加わった場合, トランザクション全体を中止する.
persistence
Redisでは大きく2つの永続化オプションがある もちろん使わないことも可能だし, 片方だけ使うこともできるし, 組み合わせて使うことも可能. 求める永続化の性能に依存.
RDB: 指定時刻ごとにデータセットのスナップショットを取得する. もしくはコマンドを叩いて取得する. スナップショットはバックアップとしては完璧だが, redisに障害発生時のデータ損失可能性はそこまで低く出来ない.
AOF(= Append only log): 実行されたコマンドをログとして残す. 耐障害性はRDBより高いが, ファイルサイズが大きくなりがち.
Memory optimization
Redisをメモリ効率よく使うためのTips, まだ執筆途中とのこと. https://redis.io/topics/memory-optimization
TL;DR
メモリ効率の良いhashをできるだけ使いましょう
だいぶ端折りましたが, 疲れたので残りは次回!