大白话快速讲懂Redis分布式锁

2023年 7月 16日 29.0k 0

技术的演变都是为了解决问题的,这也是技术演变吸引人的一点。

Redis分布式锁

分布式锁顾名思义 就是在分布式场景下 多台机器竞争一项资源去加锁

最简单的版本

首先就是最简单的版本,可以通过Redis的setnx命令(set if not exist)

setnx key value

这个命令会使Redis中如果不存在key就会创建值为value的key,存在的话就返回0

image.png

过期时间

如果获取锁的机器服务挂了呢?

image.png

其他机器:奶奶滴 怎么还不释放锁?

所以 有个兜底策略: 设置过期时间(挂了之后过段时间锁自动过期释放了)

此时可以用一个Redis自带的原子性的操作命令:

setnx key value nx ex 100

时间单位是秒

万一释放错锁了怎么办?

看这么一个场景:

image.png

涉及到两个问题:

  • 任务还没处理完锁就过期释放了
  • 释放掉了别人的锁
  • 对应的解决办法:

  • 锁的续约(根据业务加长时间,并且每过一段时间访问锁,如果存在就续约,增加时间)
  • 给每个锁区分一下,这是谁加的锁(锁的value可以设置UUID等唯一确定的值)
  • 优化过后的:

    image.png

    lua实现原子性

    上面的一步删除的时候会发生什么错误?

    image.png

    当然 这个问题上面已经解决了,就是UUID+线程id作为key,已经不会被其他线程删掉了,但是这么看来这种错误也是挺危险的,作为一个兜底方案,我们可以用lua脚本实现原子性

    lua脚本可以这么写

    7e5cc0a8898c93381a90dbb81b414cc8.png

    最后的防御

    当然分布式的NPC原则告诉我们,没有完全安全的分布式锁(所以大家还是要根据业务来)

    上面的场景中,主节点挂了咋办?

    因为Redis是AP架构的,也就是说不能保证高一致性,主节点里的锁也许并没有同步到从节点里

    这里可以用Redis官方的Red Lock 保证当前hash算法选择的节点的主从都有key了才会返回true

    这种做法也有点“重”了,有些时候,杀鸡焉用牛刀

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论