Redis实现分布式锁
来源:互联网 发布:华三交换机端口镜像 编辑:程序博客网 时间:2024/06/11 03:47
Redis实现分布式锁
分布式锁的一些问题
- 并发问题,若多个客户端同时上锁,结果只允许一个客户端成功,其他失败,可以利用redis的
SETNX
命令来实现,该命令允许若给定的 key 已经存在,则SETNX
不做任何动作,设置成功,返回 1 ,设置失败,返回 0 。 - 上锁后解锁的问题,可以考虑使用redis key的ttl过期,通过
PEXPIRE
来设置key的自动过期。若不使用自动过期特性,则需要在锁定结束后使用DEL
命令来进行解锁,这种情况有可能发生某个客户端已经crash,于是这个锁会永远锁定,导致其他客户端无法获得锁。
Redis2.6以后新特性
redis2.6.12以后 SET 命令的行为可以通过一系列参数来修改
1. EX second :设置键的过期时间为 second 秒。 SET key value EX second
效果等同于 SETEX key second value
。
1. PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond
效果等同于 PSETEX key millisecond value
。
1. NX :只在键不存在时,才对键进行设置操作。 SET key value NX
效果等同于 SETNX key value
。
1. XX :只在键已经存在时,才对键进行设置操作。
使用新特性来解决分布式锁
- 使用命令
SET key value NX EX second
设置锁的同时为锁设置TTL过期时间,若当锁已经存在时返回nil。
Redisson解决方法
Redisson是redis的一个java客户端,实现了分布式锁和同步器,Redisson的分布式锁RLock Java对象实现了java.util.concurrent.locks.Lock接口,同时还支持自动过期解锁。
RLock lock = redisson.getLock("anyLock");// 最常见的使用方法lock.lock();// 支持过期解锁功能// 10秒钟以后自动解锁// 无需调用unlock方法手动解锁lock.lock(10, TimeUnit.SECONDS);// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);...lock.unlock();
以上是redisson使用锁的方法,它的原理采用了lua脚本的方式,这样能兼容redis 2.6.12之前的版本,锁的核心源码如下RedissonLock.java
<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) { internalLockLeaseTime = unit.toMillis(leaseTime); return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command, //先检查key是否存在 "if (redis.call('exists', KEYS[1]) == 0) then " + //key不存在,创建Hash "redis.call('hset', KEYS[1], ARGV[2], 1); " + //设置过期时间 "redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " + "end; " + //若锁已经存在,并且是同样获得锁的线程调用 "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " + //复用锁,为锁+1 "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + //延长锁定时间 "redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " + "end; " + //若无法获得锁,返回锁的剩余时间 "return redis.call('pttl', KEYS[1]);", Collections.<Object>singletonList(getName()), internalLockLeaseTime, getLockName(threadId)); }
阅读全文
0 0
- Redis实现分布式锁
- Redis 分布式锁实现
- Redis 分布式锁实现
- Redis实现分布式锁
- redis实现分布式锁
- Redis实现分布式锁
- 分布式锁redis实现
- Redis 分布式锁实现
- redis分布式锁实现
- redis实现分布式锁
- Redis分布式锁实现
- redis分布式锁实现
- redis实现分布式锁
- Redis分布式锁实现
- Redis实现分布式锁
- Redis实现分布式锁
- redis实现分布式锁
- Redis实现分布式锁
- UEFI模式安装win10和Ubuntu 16.04 LTS双系统时遇到的问题
- 洛谷 P1980
- Android 开源组件和第三方库汇总
- AndroidStudio通过设置Soft Wrap 实现换行
- SpringMVC从入门到精通(一)
- Redis实现分布式锁
- 神经网络为什么要使用激活函数,为什么relu要比sigmoid要好
- 图像处理常用算法GPU实现四:基于中值滤波的二值图像平滑
- 一个宏定义---OpenCV源码阅读之一
- java集合之hashMap的hash原理
- ssh用法
- 第二节 Elasticsearch加入中文分词器IK
- Spring的@RequestHeader注释
- 鱼眼校正