Redsync 源码简单分析
- 加锁
- 自动续期
- 解锁
加锁
使用 setnx 进行加锁,没有实现分布式锁的可重入性。
func (m *Mutex) acquire(ctx context.Context, pool redis.Pool, value string) (bool, error) {conn, err := pool.Get(ctx)if err != nil {return false, err}defer conn.Close()reply, err := conn.SetNX(m.name, value, m.expiry)if err != nil {return false, err}return reply, nil
}
自动续期
var touchScript = redis.NewScript(1, `if redis.call("GET", KEYS[1]) == ARGV[1] thenreturn redis.call("PEXPIRE", KEYS[1], ARGV[2])elsereturn 0end
`)func (m *Mutex) touch(ctx context.Context, pool redis.Pool, value string, expiry int) (bool, error) {conn, err := pool.Get(ctx)if err != nil {return false, err}defer conn.Close()status, err := conn.Eval(touchScript, m.name, value, expiry)if err != nil {return false, err}return status != int64(0), nil
}
解锁
删除 key 前先判断,防止误删别人的锁。
var deleteScript = redis.NewScript(1, `if redis.call("GET", KEYS[1]) == ARGV[1] thenreturn redis.call("DEL", KEYS[1])elsereturn 0end
`)func (m *Mutex) release(ctx context.Context, pool redis.Pool, value string) (bool, error) {conn, err := pool.Get(ctx)if err != nil {return false, err}defer conn.Close()status, err := conn.Eval(deleteScript, m.name, value)if err != nil {return false, err}return status != int64(0), nil
}