• 使用Redis锁可能出现的问题


    分布式锁

    分布式锁常规情况下都是使用redis来实现。很早以前,使用SETNX加过期命令进行设置,无法保证原子性。但随着时代的发展,redis已经支持一条指令(set指令)实现setnx加过期时间。

    什么是线程不安全?

    线程不安全指的是多个线程操作一个资源,期望值和获取到的数据不一致。

    可能存在的问题

    没有一种解决方案是银弹

    • 在使用分布式锁的情况下,需要考虑如果一个线程获取到锁之后,如果业务处理产生了耗时操作,或者调用第三方接口超时,导致当前线程拿到的锁过期,这个时候,其他线程就会获取锁,然后进入业务处理方法,此时可能会出现线程不安全的情况。
      • 解决方案:针对超时导致锁过期,其他线程进入的情况,可根据业务,设置一个合理的过期时间。或者自动续期。采用Redisson就可以实现自动续期
    • 针对第一种情况,还存在如果第一个线程耗时,锁以及过期,线程2拿到了锁,但是这个时候,线程1执行完成了。这个时候,线程1就释放了线程2的锁
      • 解决方案:给锁一个唯一标识,只有锁的唯一标识和当前线程设置的唯一标识对应上了才能删除。但是删除的时候需要先根据key获取到uuid。无法保证原子性。所以还得结合lua脚本保证原子性。
    • 大量请求打击到redis服务上,导致redis服务崩溃。
      • 解决方案:redis进行高可用配置,配置主从以及哨兵机制。但是这种解决方案也会存在锁失效的情况,就是如果主节点挂了,但是锁的状态还没同步到其他节点,就会出现其他线程可以获取锁的情况。redis的作者提示了redLock(红锁)但是这种解决方案似乎是存在问题,对于时钟问题比较敏感。如果要防止上面的问题,最终还是需要有一个兜底的方案,保证锁出问题的情况下,不会对数据的结果产生太大的问题。

    谨记:一个分布式锁,在极端情况下,不一定是安全的。如果对数据很敏感,一定要有兜底的策略。当然,现在似乎人肉解决数据不一致的情况是比较常见的。

    Redis常用操作类库Redisson

    如果非必须,建议使用Redisson进行开发,多人开发的肯定比自己造轮子的强
    但是也要理解原理

  • 相关阅读:
    Storyboard中segue使用总结
    Present ViewController Modally
    UILabel设置富文本格式显示
    objective-c 中随机数的用法 (3种:arc4random() 、random()、CCRANDOM_0_1() )
    ios中static的作用
    NSBundle的使用,注意mainBundle和Custom Bundle的区别
    OC的基础语法OC继承和复合语言特性目标动作回调
    动态规划-被3整除的子序列
    A
    Coins POJ
  • 原文地址:https://www.cnblogs.com/chaoba/p/16039296.html
Copyright © 2020-2023  润新知