redis,分布式锁

从哪里开始说呢,直接开题吧,在高并发写库的情况下,如何和避免“超卖”现象,参考(https://www.cnblogs.com/gxyandwmm/p/9588383.html

超卖现象,意思是,卖出了超过一开始设定的阈值

举个场景例子:我想卖10本书,结果,因为没处理好并发问题,卖出了大于10本。

1,单机的话,可以用jdk锁,synchronized或者lock等等都可以,但现在很少有单机的了,都是集群,所以,我们主要介绍分布式锁

2,分布式锁

下面是同学们能写出的常见的代码:

伪码1:
if(setnx(key,1) == 1){
    expire(key,30)
    try {
        do something ......
    }catch()
  {
  }
  finally {
       del(key)
    }

}

但上面的代码存在的问题如下:

1,当执行完if后挂了,那锁那长期持有,无法释放,但redis2.0版本后,,修复了这个bug,其实也不算bug吧,总之插入key值与设置过期时间变成原子操作了

2,继续往下走,设置超时时间,举个极端反例

线程A得到锁,过期时间30秒,但30秒内没有完成,锁自动释放

这时候,线程B当然可以得到锁了

这时候,线程A正好执行完了,执行finally中的del操作来释放锁,可想而知,这时候释放的是线程B正在持有的锁

接触锁与加的锁不一致

如何解决:锁名称加uuid或者线程id

3,超大并发情况下,哪怕线程A释放的就是自己的锁,但依旧也有两个线程同时在执行同一段代码

解决:续费过期时间,思想可以参考redisson,q其实也可以直接用redisson一行代码搞定。

4,主从redis,设置锁后,主挂了,主还未将锁信息同步到从,则从没有锁的信息,会有另一个线程也获取到锁,锁便失去了意义

咋办:好像redis没办法,只能用zookeeper了

简答说一下zookeeper的原理吧,其实我也不是很清楚,主要区别是zookeeper有一种机制叫临时节点,当第一个请求来了后,或建立一个临时节点,后面的线程便会依次排队,等待锁的释放。当zookeeper检测到连接断了时,会将临时节点删掉,这样,下一个线程便能获取锁。

 

转载于:https://my.oschina.net/u/3796880/blog/3083403

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值