分布式锁

互联网的应用场景中,为了支持高并发的请求,服务都是执行的分布式部署(相同的任务可以在集群中不同的服务器上执行)并且现在的服务容器都是支持多线程,相同的任务也可能会被同一个容器多次执行,都要求执行结果都满足幂等性的设计原则。

分布式锁,就是为了确保在分布式的环境下,相同任务只会执行成功的执行一次,后续的执行不会对这些已经产生了变化的业务再次产生影响。

一、是否有必要加锁

如果对精度要求不高,可不可以不加锁

二、加锁方式

1. 数据库加锁

2. 基于Redis的分布式锁

3. 基于ZooKeeper的分布式锁。

2.1 基于Redis实现分布式锁

  • 方案://todo

  • 缺点:阻塞问题(未获得锁的线程阻塞,一直等待,导致系统并发性能降低)

    数据库主从延迟(对于读写分离的数据库,写到主库,读为从库,主库和从库之间的数据同步存在延迟,当数据未及时同步时,会导致读取到的数据不是最新的)

  • 基于Redis 实现分布式锁的一些问题

    • 在高并发下的分布式锁实现中,key的过期肯定不能设置的太长,否则会影响后续线程持有该锁;

    • 但是如果设置过期时间很短,直到key过期,持有该锁的线程还未执行完任务;接着下一个线程获取到该锁,这时候前一个线程执行完成后触发del释放该锁,而这把锁这个时候其实是另外一个线程持有;

    • 获取锁是非阻塞的,无论成功还是失败就直接返回;

    • 锁公平问题,所有等待线程同时发起获取锁命令操作。

    针对上述问题需要另外服务来保证实现:

    1. 守护线程:如果某个线程在expire时间内,还未执行完成,守护线程自动expire一个新过期时间,直到该线程执行完成或释放;

    2. 释放验证:线程加锁前通过线程ID和Key Value匹配,释放前通过两者判断是否一致,一致再释放该锁,避免错误释放其他线程执行时持有相同的锁(原子性可以通过lua脚本来实现);

    3. 阻塞锁: 通过while true之类的机制去阻塞代码实现;

    4. 公平锁:可以通过将所有等待线程放入同一个队列来实现。

参考资料

集群环境中使用Redis实现分布式锁两种方式

普通锁和分布式锁

posted @   zhegeMaw  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示