查看更多当前 - 案例分析 - Web应用设计
简单
案例题
2024年5月第4题
#必须掌握
#超纲

在分布式系统中,由于多个节点同时操作共享资源,容易产生竞争条件和资源冲突问题。为了保证数据一致性和系统的稳定性,需要一种有效的分布式锁机制来协调各节点对共享资源的访问。为了简化分布式锁的实现并提高性能,张工提出了一种利用数据库主键索引的方法来实现分布式锁。该方法的核心思想是利用数据库的唯一性约束和事务特性,通过对特定记录的插入和删除操作来实现锁的获取和释放。

分值(9分

基于数据库实现分布式锁的缺点。

参考答案

基于数据库实现分布式锁虽然实现简单、依赖少,但存在明显缺点:在高并发场景下性能较差,容易成为系统瓶颈;若服务异常未能释放锁,易导致死锁;可重入性和公平性支持弱;扩展性差,难以支撑大规模分布式系统的稳定运行。因此,在对性能和可靠性要求较高的系统中,通常不推荐使用数据库作为分布式锁的实现方式。

凯恩解析

基于数据库实现分布式锁常见的实现方式主要有以下两种:
1. 利用唯一索引插入
基本原理是 唯一性约束充当“互斥机制”,确保同一时间只有一个客户端能获得锁。

  • 创建一张锁表,如 distributed_locks (lock_key VARCHAR PRIMARY KEY, owner_id VARCHAR, expire_time DATETIME)
  • 某客户端尝试通过插入一条唯一的 lock_key 记录来加锁:
INSERT INTO distributed_locks (lock_key, owner_id, expire_time)
VALUES ('my_lock', 'instance_1', NOW() + INTERVAL 10 SECOND);
  • 如果插入成功,则加锁成功;如果因主键冲突插入失败,说明锁已被持有。

  • owner_id 判断是否是当前客户端持有锁,只有持有者才可删除:

DELETE FROM distributed_locks WHERE lock_key = 'my_lock' AND owner_id = 'instance_1';

2. 利用数据库的 SELECT ... FOR UPDATE 加悲观锁
基本原理是通过数据库行锁实现互斥。

  • 在锁表中先插入一条标志性记录。
  • 使用事务和 SELECT ... FOR UPDATE 对该记录加锁。
BEGIN;
SELECT * FROM distributed_locks WHERE lock_key = 'my_lock' FOR UPDATE;
-- 执行临界区代码
COMMIT;

这种方法的主要的问题是

  1. 竞争激烈时插入失败频繁。在高并发场景中,大量节点同时尝试 INSERT 锁记录会频繁触发主键冲突,导致性能下降,数据库压力剧增。
  2. 锁重入难实现。默认情况下无法支持可重入(同一线程/服务可多次加锁),需要额外存储 owner_id 和 lock_count 等字段,并设计相应逻辑,增加实现难度。
  3. 数据库成为瓶颈。分布式锁操作本质是对数据库的高频写入和查询操作,容易将数据库打满,拖慢主业务性能。
联系我们
隐私协议
用户协议
微信公众号
知乎
小红书
浙ICP备2021029036号
@2022-2026
嘉兴市安芯网络科技有限公司 版权所有