LoginSignup
10
1

More than 5 years have passed since last update.

Redis四方山話

Last updated at Posted at 2016-12-22

本日は、Redisで運用している上で起こった事や気をつけている事を、取り留めなく列挙したいと思います。1

Redisについて詳しい説明はしませんが、ごく簡単に説明すると、オンメモリのKVSです。類似のものにmemcachedがありますが、memcachedと比べた優位点としては、自動で並べ替えられるリスト(ランキングで大活躍中)や、永続化機構(サーバーが死んでもバックアップから復帰できる)が挙げられるかと思います。

シングルスレッド

Redisはシングルスレッドなので、強い1CPUが有効です。

数値はdouble

数値周りはintでやり取りするので、何となくint型と思ってしまいますが、double型です。2 ですので、大きな値を代入するとブレます(17桁くらい)。

RDBへの保存中は他のコマンドや新規接続を受け付けない

Redisの永続化の方法はいくつかありますが、そのうちRDBについて、RDBファイルへの保存中、Redisは無応答になります

マシンのスペック次第ではありますが、弊社が利用しているサーバーでは、数GBクラスのデータをRDBへ保存すると、数十秒かかります。その期間中にRedisのデータ操作や参照を行おうとすると、その作業が終わるまでは無応答になります。新規の接続を確立しようとしても、設定次第でタイムアウトし得ます。

saveを無効にして、アクセスが少ない深夜にバッチでRDBに保存する事も考えられます。

ランキングで同順位を処理できない

Redisにはランキング利用に向いているSorted setsというデータ型がありますが、その特徴として、同じポイントのユーザーが同順位になりません。対象のコマンドは以下のとおりです。

  • ZRANK
  • ZREVRANK
  • ZRANGE
  • ZREVRANGE

具体的には以下のようになります( Ruby からの実行例)

# 7500位のユーザーを取得
> user_ids = Redis.current.zrevrange('hogehoge', 7500, 7500)
=> ["aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"]
> user_ids.each do |user_id|
*   pp Redis.current.zscore('hogehoge', user_id)
* end
9256

# 7501位のユーザーを取得
> user_ids = Redis.current.zrevrange('hogehoge', 7501, 7501)
=> ["aaaaaaaa-bbbb-cccc-dddd-ffffffffffff"]
> user_ids.each do |user_id|
*   pp Redis.current.zscore('hogehoge', user_id)
* end
9256# 7500位のユーザーと同じスコア・・・

それに対応するためには、上記4コマンド以外を活用します。例えば、特定のユーザーの現在のランクを取得したい場合、以下のようになります。

# 対象ユーザーのスコアを取得
> score = Redis.current.zscore('hogehoge', "aaaaaaaa-bbbb-cccc-dddd-ffffffffffff").to_i
=> 9
# そのスコアより大きいユーザーの数をカウントし、それに1を足すと対象ユーザーのランクになる
> Redis.current.zcount('hogehoge', "(#{score}", "+inf") + 1
=> 182

それに対応しようとしたパッチもあるようです。

データが溢れると新規データ保存できなくなる

maxmemoryで設定されている容量をオーバーすると、新規データが作れなくなります。3 Railsの場合はエラー扱いとなります。これへの対策として、可能な限りデータの有効期限を設定する事、可能な限り小さなデータにする事を心がけています。

設定値の倍以上のメモリーが必要

RedisはRDBで保存する際に、自身の丸ごとコピーを作ります。そのため、メモリーはmaxmemoryの設定値の倍以上を確保しておく必要があります。

色々あるけどやっぱり便利

色々ありますが、やはり速度が出ますし、自動で並べ替えができるのはありがたいです。今後ともうまく付き合っていきたいものです。


  1. バージョンは2.8.19です。 

  2. IEEE 754 floating point number 

  3. ちなみにmemcachedでは、溢れるとアクセスされた時間が古いデータから消されていきます(LRU) 

10
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1