利志分享
view_headline
开发工具箱
go教程
clickhouse教程
kafka教程
python教程
shell教程
原创杂文
开发工具箱
go教程
clickhouse教程
kafka教程
python教程
shell教程
原创杂文
从线上分布式锁的使用到深度理解redis分布式锁
原创杂文 / 时间:2021-09-20 19:40:22 / 阅读:270 / 分享:0
关于分布式锁,相信大家都用的非常普遍。分布式锁其实就是控制分布式系统间不同的服务,不同的进程或者不同的线程共享同一资源的一种方式。当共享资源被竞争,我们需要通过互斥来防止彼此干扰从而保证一致性,这个时候我们就需要使用分布式锁。 这篇文章我主要分享通过redis来实现分布式锁的方式,以及存在的问题。 setnx命令 set if not exists 设置一个值,或者填一个坑,设置完了或者填完了就没有了,只有del才能释放。 线上案例分享: 我们线上分布式锁就是使用的setnx,有一次因为线上问题,我们强制重启了一个服务,造成后面重启之后a数据一直没拿到。a数据只能让某一个服务能拿到。这个获取就是通过setnx实现的,因为a数据只能启动后一个服务获取到。后面查了许久才明白过来setnx执行之后,del没有执行成功,造成陷入死锁。像这种问题我们如何避免呢?是不是加个过期时间才能解决?其实过期时间也是会存在同样的问题,如果setnx成功,但是expire执行失败了,那还是同样会有问题。 总结案例: 使用setnx来控制并发,del或者expire的使用能一定程度上解决死锁的问题,但是如果两个命令有一个执行失败,那死锁就来了,就出现问题了。上面我们看到使用setnx存在的问题,我们想只有保证setnx和del或者setnx和expire原子性操作才能保证一定不会死锁。setnx和del是无法做到原子性的,但是set和expire则可以。这样我们就引入另外一个处理命令。 set lock x EX 10 NX 这个命令表示只有不存在key为lock才设置,有效时间是10s。这个命令是原子性的,从redis2.6.12版本开始支持。是不是以为这个命令实现分布式锁就是完美的了?并不是!使用这个只是说相对来说比较安全。为什么这么说,因为如果一个锁里面的执行超过了设置锁的超时时间,可能临界区域的代码并不是安全的执行,这样可能其他线程或者服务就会同时操作同一份数据。 总结: **setnx结合expire或者del命令并不是原子性的。 SET key value [EX seconds] [PX milliseconds] [NX|XX] 这个命令是原子性的,但是使用需要注意执行的数据是否超过过期时间。**
按时间分类
2022-04-22
2022-04-10
2022-03-26
2022-03-16
2022-03-08
2022-03-04
2022-02-27
2022-02-26
2022-02-19
2022-01-30
2022-01-23
2021-11-14
2021-11-06
2021-10-07
2021-09-21
2021-09-20
2021-09-15
2021-08-22
2021-08-13
2021-07-28
2021-06-17
2021-05-22
2021-04-23
2021-04-03
2021-03-07
2021-03-05
2021-03-04
2021-02-28
2021-02-21
2021-02-20