分布式锁
互联网的应用场景中,为了支持高并发的请求,服务都是执行的分布式部署(相同的任务可以在集群中不同的服务器上执行)并且现在的服务容器都是支持多线程,相同的任务也可能会被同一个容器多次执行,都要求执行结果都满足幂等性的设计原则。
分布式锁,就是为了确保在分布式的环境下,相同任务只会执行成功的执行一次,后续的执行不会对这些已经产生了变化的业务再次产生影响。
一、是否有必要加锁
如果对精度要求不高,可不可以不加锁
二、加锁方式
1. 数据库加锁
2. 基于Redis的分布式锁
3. 基于ZooKeeper的分布式锁。
2.1 基于Redis实现分布式锁
-
方案://todo
-
缺点:阻塞问题(未获得锁的线程阻塞,一直等待,导致系统并发性能降低)
数据库主从延迟(对于读写分离的数据库,写到主库,读为从库,主库和从库之间的数据同步存在延迟,当数据未及时同步时,会导致读取到的数据不是最新的)
-
基于Redis 实现分布式锁的一些问题
-
在高并发下的分布式锁实现中,key的过期肯定不能设置的太长,否则会影响后续线程持有该锁;
-
但是如果设置过期时间很短,直到key过期,持有该锁的线程还未执行完任务;接着下一个线程获取到该锁,这时候前一个线程执行完成后触发del释放该锁,而这把锁这个时候其实是另外一个线程持有;
-
获取锁是非阻塞的,无论成功还是失败就直接返回;
-
锁公平问题,所有等待线程同时发起获取锁命令操作。
针对上述问题需要另外服务来保证实现:
-
守护线程:如果某个线程在expire时间内,还未执行完成,守护线程自动expire一个新过期时间,直到该线程执行完成或释放;
-
释放验证:线程加锁前通过线程ID和Key Value匹配,释放前通过两者判断是否一致,一致再释放该锁,避免错误释放其他线程执行时持有相同的锁(原子性可以通过lua脚本来实现);
-
阻塞锁: 通过while true之类的机制去阻塞代码实现;
-
公平锁:可以通过将所有等待线程放入同一个队列来实现。
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话