【ISUCON用】Redis Cheat Sheet
ISUCON予選が明日に迫ってきました。
Redisの操作が全く覚えられないのでまとめておきます。
セッティング
インストール
この辺とか見たらいい感じにできるのではないでしょうか(未確認)
使い方
# デフォルトは127.0.0.1:6379で繋がるはずなのでとりあえずこれで def redis @redis ||= (Thread.current[:isu8_redis] ||= Redis.new(host: "127.0.0.1", port: 6379)) end # keyはこんな感じでメソッドで隠してあげるとtypoが減ってよさそう def redis_key_unread_count(channel_id) "isu7:unread_count:#{channel_id}" end # redisの操作もこんな感じでメソッドで隠してあげよう def redis_increment_unread_count(channel_id) user_ids = redis_get_user_ids user_ids.each do |user_id| redis.hincrby(redis_key_unread_count(channel_id), user_id, 1) end end
Redis豆知識
格納されているフォーマットについて
Redisには数値という概念がなく、一度全て文字列として格納されている。 (incrとかは文字列を数値に変換してから+1して文字列に戻すなどの操作をしているっぽい)
そのため、redis.get ...
とかで取得した数値は毎回to_i
する必要がある。
redis-cliでのデバッグ
- とりあえず格納されているkeyを全部見たい
keys *
- 一旦格納されてるデータ全部消したい
flushall
データ型
つらつら書いていこうかと思ったけどドキュメント見ればわかると思ったのでひとことに留めておきます。
String
標準的なkey value
get
, set
, mget
, mset
, incr
, incrby
とかをよく使う気がします。
文字列型 — redis 2.0.3 documentation
# 使う可能性のあるコマンド一覧 SET(key, value) GET(key) # なければnilを返す GETSET(key, value) MGET(key1, key2, ..., keyN) SETNX(key, value) MSET(key1, value1, key2, value2, ..., keyN, valueN) MSETNX(key1, value1, key2, value2, ..., keyN, valueN) INCR(key) INCRBY(key, integer) DECR(key, integer) DECRBY(key, integer)
List
Listです。
両端からアクセスできる(rpush
, lpush
)けどisuconだとListは帯に短し襷に長し感があります。
Hashを使った方がいい場合の方が多そう。
idを保存しておいてllen
とかでSQLのcountの擬似実装とかには使えるかも?
リスト型 — redis 2.0.3 documentation
# 使う可能性のあるコマンド一覧 RPUSH(key, string) LPUSH(key, string) LLEN(key) LRANGE(key, start, end) # key, 0, -1 で全取得 LINDEX(key, index) LSET(key, index, value) LPOP(key) RPOP(key)
Set
sorted setを使おう。setを使いたい場面ってisuconであんまり思いつかない。
セット型 — redis 2.0.3 documentation
Sorted Set
score付きのset。コマンド名に癖があるけどなんかすごい高機能。
DBのtableをそのままredisに載せようと思ったら
- Hashとしてそのままデータをredisに突っ込む
- Sorted Setでkeyをテーブル名、memberをhashのkey, scoreをDBのindexとして使う
みたいな感じになるんじゃないかな。(やったことない)
scoreの範囲を指定して取得とかできるので本当にtableと置き換えられる。
ただ、データの変形をせずにそのままテーブルの置き換えてパフォーマンスがどのくらい変わるのかはよく分かっていない。
ソート済みセット型 — redis 2.0.3 documentation
# 使う可能性のあるコマンド一覧 ZADD(key, score, member) ZCARD(key) # memberの数を返す ZSCORE(key, member) # 対応するmemberのscoreを返す ZREM(key, member) # memberを削除 ZINCRBY(key, increment, member) ZRANK(key, member) # 指定したmemberのスコア順にソートされた場合のindexが取得できる ZREVRANK(key, member) # ZRANKの降順版 # indexで範囲指定してmemberを取得できる、WITHSCORESをつけると対応するscoreも取得できる ZRANGE(key, start, end, [WITHSCORES]) ZRANGE(key, start, end, [WITHSCORES]) # ZRANGEの降順版 # scoreで範囲指定してmemberを取得できる。LIMIT, offsetも指定できるので実質SQL ZRANGEBYSCORE(key, min, max, [LIMIT, offset, count, [WITHSCORES]]) ZCOUNT(key, min, max) # ZRANGEBYSCOREのCOUNT版 # 複数のsorted setから和集合、積集合を作る。共通するmemberのscoreは和をとる。 # ランキング計算とかするときにめちゃくちゃ便利なんだけど、複雑なので時間が余らないと使わない気がする? ZUNIONSTORE(dstkey, N, k1, ..., kN, [WEIGHTS, w1, ..., wN], [AGGREGATE, SUM|MIN|MAX]) ZINTERSTORE(dstkey, N, k1, ..., kN, [WEIGHTS, w1, ..., wN], [AGGREGATE, SUM|MIN|MAX])
Hash
Hash。tableをそのままredisに持ってこようとするような荒技を使うときに使う。 操作方法自体はStringと大差ない。
ハッシュ型 — redis 2.0.3 documentation
# 使う可能性のあるコマンド一覧 HSET(key, field, value) HGET(key, field) HMSET(key, field1, value1, ..., fieldN, valueN) HMGET(key, field1, ..., fieldN) HINCRBY(key, field, value) # 負数を指定すればデクリメントもできる HEXISTS(key, field) HLEN(key) HKEYS(key) HVALS(key) HGETALL(key)