如何使用redis来实现分布式锁

如何使用redis来实现分布式锁

分布式锁其实可以理解为:控制分布式系统有序的去对共享资源进行操作,通过互斥来保持一致性。 

举个不太恰当的例子:假设共享的资源就是一个房子,里面有各种书,分布式系统就是要进屋看书的人,分布式锁就是保证这个房子只有一个门并且一次只有一个人可以进,而且门只有一把钥匙。     (推荐学习:Redis视频教程

使用redis实现分布式锁                     

使用redis命令 set key value NX EX max-lock-time 实现加锁

使用redis命令 EVAL 实现解锁

加锁:

Jedis jedis = new Jedis("127.0.0.1", 6379);    private static final String SUCCESS = "OK";    /**     * 加锁操作     * @param key 锁标识     * @param value 客户端标识     * @param timeOut 过期时间     */    public Boolean lock(String key,String value,Long timeOut){        String var1 = jedis.set(key,value,"NX","EX",timeOut);        if(LOCK_SUCCESS.equals(var1)){            return true;        }        return false;    }

解读:

加锁操作:jedis.set(key,value,”NX”,”EX”,timeOut)【保证加锁的原子操作】

key就是redis的key值作为锁的标识,value在这里作为客户端的标识,只有key-value都比配才有删除锁的权利【保证安全性】

通过timeOut设置过期时间保证不会出现死锁【避免死锁】

NX,EX什么意思?

NX:只有这个key不存才的时候才会进行操作,if not exists;

EX:设置key的过期时间为秒,具体时间由第5个参数决定

解锁

Jedis jedis = new Jedis("127.0.0.1", 6379);    private static final Long UNLOCK_SUCCESS = 1L;    /**     * 解锁操作     * @param key 锁标识     * @param value 客户端标识     * @return     */    public static Boolean unLock(String key,String value){        String luaScript = "if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else  return 0 end";        Object var2 = jedis.eval(luaScript,Collections.singletonList(key), Collections.singletonList(value));        if (UNLOCK_SUCCESS == var2) {            return true;        }     return false;  }

解读:

luaScript 这个字符串是个lua脚本,代表的意思是如果根据key拿到的value跟传入的value相同就执行del,否则就返回0【保证安全性】

jedis.eval(String,list,list);这个命令就是去执行lua脚本,KEYS的集合就是第二个参数,ARGV的集合就是第三参数【保证解锁的原子操作】

上述就实现了怎么使用redis去正确的实现分布式锁,但是有个小缺陷就是锁过期时间要设置为多少合适,这个其实还是需要去根据业务场景考量一下的。

更多Redis相关技术文章,请访问Redis视频教程栏目进行学习!

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享