redis冒号分隔符含义_细品redis分布式锁

更新时间:2023-07-13 12:01:27 阅读: 评论:0

分布式锁的本质就是,不同服务间或同⼀个服务间的线程在redis⾥⾯争抢坑位,当⼀个线程占⽤了这个坑位,门⼀锁,那么其他线程
//伪代码
try{
}catch (Exception e){
e.printStackTrace();
}finally {
//就算异常了也会执⾏,删除操作
delKey;
}
}
1. 那就是给这个锁(坑位)来个时间限定,你到时间就得⾃动进⾏释放。那么实现⽅式是先获取锁,然后再设置定时时间:
春节手抄报简单> tnx lock:codehole true
OK
> expire lock:codehole 5
... do something critical ...
> del lock:codehole
(integer) 1
礼仪书
1. 由于上⾯所说的这个⽅式不是操作过程不是原⼦性(要全部执⾏,要么全部不执⾏。不会出现执⾏⼀半)的所以也会出现拿到锁后。
然后出现这只锁超时时间异常或者服务挂掉的问题。这样也就回到了最初的问题了。
毕淑敏小说2. 那我们想想这样有什么好的办法处理呢? 说到原⼦性,这不就是事物的四⼤特性之⼀吗。那我们就
使⽤redis的事物来处理这个问题
呗。将指令 tnx 和 expire放在同⼀个事物⾥⾯进⾏执⾏。 就在redis 2.8的时候处理了这个问题,那就是这两个命令是可以⼀块执⾏。这也是我们使⽤分布式锁的奥义所在。
> t lock:codehole true ex 5 nx OK ... do something critical ...
> del lock:codehole
简单的科学小制作1. 那由于线程执⾏时间过长锁超时了怎么办呢?
分布式锁过期
1. Redis 的分布式锁不能解决超时问题,如果在加锁和释放锁之间的逻辑执⾏的太长,以⾄
于超出了锁的超时限制,就会出现问题。因为这时候锁过期了,第⼆个线程重新持有了这把锁,
但是紧接着第⼀个线程执⾏完了业务逻辑,就把锁给释放了,第三个线程就会在第⼆个线程逻
辑执⾏完之间拿到了锁。
2. ⾸先这种问题我们得规避,产⽣的原因就是业务逻辑执⾏时间太长,那么就要在使⽤的时候尽量⽤于时间短的,尽量避业务存在夸服
务调⽤,还有就是设置尽量合理的过期时间尽量⼤与业务执⾏时间。
3. 还有⼀个更加安全的⽅案就是给每⼀个锁都放⼀个值,在进⾏del的时候我们可以先对⽐⼀下是不是之前放的value。这带点乐观锁的
意思了。compare and swap 对⽐后替换。但是匹配和key删除不是⼀个原⼦性操作,操⼼。还好redis提供⼀个脚本执⾏⽅式,且脚本是具有原⼦性的,使⽤lua脚本达到原⼦性的⽬标。(在使⽤阿⾥云的redis sharding模式得注意⼀下。他们sharding模式对lua脚本的⽀持有问题。我踩的坑。使⽤redission的RmapCache时其源码有lua脚本导致最后运⾏失败)
# delifequals
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
el
return 0
end
可重⼊性
手机连接助手1. 可重⼊性指的是在持有锁的情况下再次请求加锁,仍然可以 再次请求加锁,那么这个锁就是可重⼊的。例如java中的reentrantLock
和 sychronized都是可重⼊锁。
犹太人信仰的是什么教
2. 他们实现的⼤概原理是通过乐观锁去修改他们的锁状态,如果是同⼀个线程id那就会更改成功,可以获取到锁,如果不是同⼀个线程
ID那就回锁升级。那我们使⽤redis如何实现呢?同⼀个道理呗。我们可以把这个线程ID 或者是这个任务ID,可以是线程维度,也可以是任务维度。进⾏可重⼊。
中间件的使⽤
1. jedis(在使⽤的时,在连接池回收有问题,应该是我⾃⼰的代码写的有问题,最后没有解决)
2. redission (更换了redssion后回收连接池的问题解决了,但是将原来的redis单机版升sharding模式时出现了lua脚本的问题)
上⾯是两个redis的中间件⽤起来很舒服,括号⾥⾯是我踩的坑。
真实案例分享
需求
微服务间调⽤,对外暴露接⼝,为防⽌接⼝短时间内被同⼀个任务ID重复调⽤(保证前⼀个任务执⾏完成)。防⽌同时操作⼀条数据。
新年祝福公司的祝福语
解决⽅案:使⽤redis分布式锁,使⽤taskId作为锁。设置过期时间为2s,等待时间为2秒。
2s的意思是,业务执⾏最长时间为2s。执⾏不完就释放。
3s的意思是锁超时我等待的这个任务⼀定能执⾏。
使⽤的是:redssion封装好的:
@Override
public Respon discernCommon(DiscernCallBackResultTo discernCallBackResultTo) {
//防⽌并发,通过同⼀个TSKID做锁重复新增发票,锁过期时间3秒,等待时间为2秒
boolean lock = TaskId(), 2, 3);
if (lock) {
try {
dealDiscernResult(discernCallBackResultTo);
} catch (Exception e) {
wifi不能用<(e.getMessage(), Coder.of(ErrorCode.DISCERN_DEAL_EXCEPTION), e);
} finally {
RedissonLockUtils.TaskId());
}
} el {
EventMessage confilct = new EventMessage(EventEnum.EVENT_EventId())
.addExtValue("taskId", TaskId());
}
return Respon.ok("回调成功!");
}
总结
redis分布式锁的实现和演进
redis锁过期导致锁释放错误,通过加任务好的⽅式,先对⽐在删除
redis分布式锁的可重⼊锁的实现,通过乐观锁的⽅式,对其线程iD 或者任务ID进⾏可重⼊设计。
参考
《redis 极度深寒》

本文发布于:2023-07-13 12:01:27,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1094267.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:问题   时间   脚本   任务
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图