- 产生背景
服务器集群模式下需要对临界资源实现互斥访问 - 实现方案
- 基于数据库
使用唯一索引或排他锁来实现。
缺点是IO限制导致的性能较差,同时支持功能太少,需要额外开发锁超时、锁失效等功能。 - 基于KV缓存
一般通过redis来实现。
一种是单机方案,即通过单个redis实例,set key value ex/px timeout nx语句实现加锁,通过lua脚本比较key和value实现解锁,通过watchDog看门狗来实现业务运行时间超过“锁超时时间”时的续期,该方案问题在于单点故障问题;
另一种是哨兵模式方案, 通过引入主从架构和哨兵机制,提升了系统的鲁棒性,但仍然会有主从切换时分布式锁可能被同时获取、以及由于网络原因导致的“脑裂”(多个master节点)等问题;
第三种是RedLock方案,通过多个并列的redis实例提升系统的鲁棒性,加锁时需要对每个redis实例都加锁,只有超过一半的实例都加锁成功才算加锁成功。这种方案极大恶化了性能,同时在一些边界情况如某个redis实例中的锁过期时客户端在GC导致仍然在使用锁等场景仍然有问题 - 基于一致性协议
一般通过zookeeper实现,主要借助临时有序节点和watcher机制,客户端在获取锁时,会在zookeeper中创建一个临时有序节点(先创建的节点序号更小,优先级更高),序号最小的节点能获取到锁,同时通过watcher机制观察节点状态,当客户端解锁时,对应的临时有序节点会在zookeeper中注销,watcher观察到节点注销后,会通知下一个序号最小的节点获取到锁。
zookeeper是鲁棒性最强的方案,但是在一些极边界情况下,仍然有问题,比如客户端网络异常会导致对应临时有序节点被注销,这样就会有新的客户端能拿到锁,可能就造成了锁被同时持有。
- 基于数据库
- 方案选型
- 对性能没要求,对分布式锁的功能需求也极简单,可以考虑数据库方案,但一般不建议。
- 对性能要求高,允许极端情况容错,可以采用Redis的方案。
- 对性能要求较高,同时对一致性要求相当严格,可以采用zookeeper的方案。
分布式锁简介
张小明
前端开发工程师
C++ 中的常见的动态内存问题
C 中常见的动态内存问题 C 的动态内存管理(通过 new/delete 或 new[]/delete[])是强大但危险的功能。如果使用不当,会导致严重的运行时错误、内存泄漏、安全漏洞甚至程序崩溃。下面列出实际项目中最常见的动态内存问题,按严重性和…
从美团全栈化看 AI 冲击:前端转全栈,是自救还是必然 [特殊字符][特殊字符][特殊字符]
从美团的全栈化看 AI 冲击:前端转全栈,是自救还是必然? 美团近年来在AI工具上的大力投入(如2025年推出的NoCode平台),确实让很多人联想到“AI对前端开发的冲击”,尤其是NoCode被描述为“全栈的…
27.斑点匹配
题目如下 方案设计: Advance Scirpt #region namespace imports using System; using System.Collections; using System.Drawing; using System.IO; using System.Windows.Forms; using Cognex.VisionPro; using Cognex.VisionPro.ToolBlock; using Cognex.VisionPro3D; usi…
裂隙瓦斯模型的Comsol模拟之旅
裂隙瓦斯模型 Comsol模拟在矿业工程等领域,裂隙瓦斯模型的研究至关重要,它关乎着安全生产以及资源的高效开采。而Comsol Multiphysics作为一款强大的多物理场仿真软件,为我们深入探究裂隙瓦斯模型提供了绝佳的平台。 裂隙瓦斯模型简述 裂隙瓦…
Python基础六:算数运算符、赋值运算符、逻辑运算符与比较运算符
一、算数运算符 # 加减乘除 a, b 10, 3print(a b) # 加法: 13 print(a - b) # 减法: 7 print(a * b) # 乘法: 30 print(a / b) # 除法: 3.3333333333333335 print(a // b) # 整除: 3(向下取整) print(a % b) # 取模: 1(余数&…
tk点赞协议
X-Bogus这个签名是老演员了,一开始就校验上了。该算法入参是:query, user_agent, body 区分GET/POST请求,如果在log里发现了d41d8cd98f00b204e9800998ecf8427e 这个就是空值的md5值,也就表示GET请求。首先分别进行算法签名2次得到…