分布式锁

系统部署架构

部署架构
    如果同时有多个请求访问,对存入redis中的数据进行减操作,但是由于业务中存在着一些逻辑,导致无法使用redis提供的原子性的decr操作。则会存在数据一致性的问题,即使在业务代码中加锁。

处理方式一

    此时最简单的方式是在操作逻辑中使用redis的setnx操作设置一个值,并设置超时时间。在减操作完成后,删除相关的键。
    但是这会存在一个问题,并发量不大的情况下,这一切都会好好运行,但是可能某个意外,导致:
    当前线程在删除相关的键之前,超时时间已经到了,然后别的线程又运行的很快,别人又把这把锁给删除了。此时会存在空档期,导致又被别的线程获取到锁,总之会存在不一致的问题。

处理方式二

    出现上面问题的原因是自己获取的锁被别人删除了。此时可以在获取锁之前设置UUID,将setnx的value设置成UUID,在删除锁时,判断一下,这个锁必须可以和这个UUID对应,才让删除。
    但是安装上面的玩法还是可能存在问题,这个问题的根本原因是超时时间引起的,比如删除锁的伪代码是如下写法,即非原子性操作:

if uuid == redis.get('key'):   // 在此时锁超时
	delete key

处理方式三

    在当前处理逻辑中再开一个线程,去检测当前线程是否还持有这把锁,如果有,则延长锁的超时时间。真实使用可以使用redission
    但是上面的处理方式还是可能会存在问题。此时问题并不是出现在server端上,而是出现在redis上,因为一般情况下可能使用的是redis集群,但是如果你的redis集群使用的是master-slave架构,如果在master节点同步过程中master挂掉,还是会导致数据不一致问题,此时就需要引入zookeeper了,让它去管理redis集群,实现数据的一致性。CAP原则

处理方式四

    通过上面的这些操作可以看到,为了实现数据的一致性,会导致性能降低。但是我们回过头来重新来审视这个问题:
对 存 入 r e d i s 中 的 数 据 进 行 减 操 作 对存入redis中的数据进行减操作 redis
    为提高并发,我们可以对原始数据重新组织一下:也就是分段,比如我们需要对100进行减操作。但是完全可以把这个数据分成5个20,显然,在这种情况下我们从原先的只能获取一把锁,变成了可以获取5把锁。
    不过,这样分段的做法也会引入问题,比如,在某个段中的值为2,但是业务中导致此时要减3,此时无法减完。大家可以根据具体的业务自行思考优化的方法

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值