golang redisによる分散ロック

1113 ワード

redisはstringデータ構造を用いて分散ロックを実現することができる.ここにいくつかの注意点を記録します.
  • setnx:setnxの特性を利用して、keyが存在しない場合、設定に成功することができます.keyが存在する場合、setnxはnilを返します.
  • expireの設定:クライアントがロックを取得した後にロックを解除することを忘れないように、ここでロックの有効期限を設定します.setnxとexpireが原子操作であることをredisによって保証します.そうしないと、setnx後にexpireが設定されていない場合があります.
  • タイムアウトの問題:expire時間が設定されているため、プロセスがロックを取得する時間が長すぎてredisで設定されたexpire時間を超えると、反発性が保証されません.ここではexpire時間と処理時間をよく比較し,このような状況を防止する.

  •  
    package redis
    
    import (
    	"github.com/garyburd/redigo/redis"
    )
    
    const (
    	redisLockTimeout = 10 // 10 seconds
    )
    
    func Lock(key string) (isLock bool, err error) {
            //        con  ,pool      。
    	con := pool.Get()
    	defer con.Close()
            //    redis.String   ,    redis.ErrNil
    	_, err = redis.String(con.Do("set", key, 1, "ex", redisLockTimeout, "nx"))
    	if err != nil {
    		if err == redis.ErrNil {
    			err = nil
    			return
    		}
    		return
    	}
    	isLock = true
    	return
    }
    
    func Unlock(key string) (err error) {
    	con := pool.Get()
    	defer con.Close()
    	_, err = con.Do("del", key)
    	if err != nil {
    		return
    	}
    	return
    }