RubyでRedis使ってて便利だったgem

・redis-objectsの「Redis::Lock」

redis-objectsがまず便利なんだけど、その中で「Redis::Lock」。
処理が平行して実行されないようにしたい時など、処理の一部をロックしたい時に役立つ。

これは、redis公式の

http://redis.io/commands/setnx

これに則ってる。

簡単にいうと、SETNX(セットされていたかどうかで0or1が帰る処理)でキーを取得して、取得されていたら解放されるまでポーリング(もしくはタイムアウトを設定してタイムアウトさせる)

require 'redis-objects'
@lock = Redis::Lock.new('lock-key', timeout:0.1)
begin
  @lock.lock do # lockの最初に"setnx" "lock-key"を実行し、lockを獲得
    sleep(10)
  end           # lockの最後に"del" "lock-key"を実行し、lockを解放
rescue Redis::Lock::LockTimeout
  p 'ロック獲得できない時の処理'
end

ちなみにlockのtimeoutを設定しない場合、timeout:5(秒)となる。
また、0.1秒ごとにSETNXでキーの解放をチェックする。

`lock': Timeout on lock lock-key exceeded 5 sec (Redis::Lock::LockTimeout)
・Resqueで同じパラメータのものはenqueしない「Resque::Plugins::UniqueJob」

https://github.com/jayniz/resque-loner

Redisというか、Resqueなんだけど。

同じパラメータのものは一度しかenqueしてほしくない時に使う。

仕組みとしては、ざっくり言うと「queue名」「パラメータ(をmd5等で一意のIDにしたもの)」をキーとしたものををenque時にredisにSETし、重複するものが既にSETされていればenqueしないという仕組み。


resque:loners:queue:cache_sweeps:job:5ac5a005253450606aa9bc3b3d52ea5b

ただ、これはenqueueの重複を防ぐだけでqueueの重複実行を防ぐものではない(queueが取り出され実行された時点で、次のenqueueは受け付けるので)。
なので、重複実行には上記のlock等を使うべき。