美文网首页
redis 实现简单分布式锁

redis 实现简单分布式锁

作者: 蔡欣圻 | 来源:发表于2019-10-12 18:30 被阅读0次

    Redis分布式锁

    Redis SET 命令如下:

         SET key value [EX seconds] [PX milliseconds] [NX|XX]
    

    参数说明:

    • EX seconds:将键的过期时间设置为seconds秒。 执行SET key value EX seconds的效果等同于执行SETEX key seconds value。

    • PX milliseconds:将键的过期时间设置为milliseconds毫秒。 执行SET key value PX milliseconds的效果等同于执行 PSETEX key milliseconds value。

    • NX : 只在键不存在时, 才对键进行设置操作。 执行SET key value NX的效果等同于执行SETNX key value。

    • XX : 只在键已经存在时, 才对键进行设置操作。

    返回值

    在Redis 2.6.12版本以前,SET命令总是返回 OK 。

    从Redis 2.6.12版本开始,SET命令只在设置操作成功完成时才返回OK; 如果命令使用了NX或者XX选项, 但是因为条件没达到而造成设置操作未执行, 那么命令将返回空批量回复(NULL Bulk Reply)

    Redis分布式锁实现原理

    从Redis命令看出,SET命令为原子操作,我们可以用SET key value EX seconds NX来实现分布式锁,下面为go语言实现:

    下面简单的go代码

          package main
            import(
                "errors"
               "time"
              "github.com/go-redis/redis"
           )
    
          var(
                  redisClient  *redis.Client
            )
    
    type  TryLocker interface{
            TryLock() error
             Unlock() error
    }
    
    type redisLock struct{
          Name string  //key
         Expire   time.Duration //过期时间
    }
    
    func newRedisLock(name string, t time.Duration) *redisLock{
            return & redisLock{
                Name:name,
                Expire:t, 
           }
    }
    
    func(l *redisLock)TryLock() error{
           if ok, _ := redisClient.SetNX(l.Name, 1, l.Expire).Result(); !ok {
            return errors.New("redis lock: already locked")
        }
        return nil
    }
    
    
    func(l *redisLock)Unlock() error{
         return redisClient.Del(l.Name).Err()
    }
      func main(){
            l:=newRedisLock("cr",time.Second)
           err:=l.TryLock()
          var wg sync.WaitGroup
        for i := 0; i < 100; i++ {
            wg.Add(1)
                   if err != nil {
                time.Sleep(50*time.Millisecond)
                if i >= 100 {
                    fmt.Println("任务处理 异常:", i)
                    wg.Done()
                    return
                }
            }
            fmt.Println("任务处理中....")
            l.Unlock()
            fmt.Println("任务处理 ok:", i)
            wg.Done()
        }
        wg.Wait()
     }
    

    相关文章

      网友评论

          本文标题:redis 实现简单分布式锁

          本文链接:https://www.haomeiwen.com/subject/ifhcmctx.html