前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式锁解决方案

分布式锁解决方案

作者头像
一个会写诗的程序员
发布2020-05-26 15:05:08
5300
发布2020-05-26 15:05:08
举报

1. 基于数据库实现分布式锁

在数据库中创建一个表,表中包含方法名等字段,并在方法名字段上创建唯一索引,想要执行某个方法,就使用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。(性能不是特别高)

创建一个表

代码语言:javascript
复制
DROP TABLE IF EXISTS `method_lock`;
CREATE TABLE `method_lock` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `method_name` varchar(64) NOT NULL COMMENT '锁定的方法名',
  `desc` varchar(255) NOT NULL COMMENT '备注信息',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uidx_method_name` (`method_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='锁定中的方法';

想要执行某个方法,就使用这个方法名向表中插入数据。

代码语言:javascript
复制
INSERT INTO method_lock (method_name, desc) VALUES ('methodName', '测试的methodName');

由于对method_name做了唯一性约束,如果有多个请求同时提交到数据库,数据库会保证只有一个操作可以成功,那么就可以认为操作成功的那个线程获得了该方法的锁,可以执行方法体内容。

成功插入则获取锁,执行完成后删除对应的行数据释放锁。

代码语言:javascript
复制
delete from method_lock where method_name ='methodName';

2. 基于Redis实现分布式锁

获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值可以为一个随机生成的UUID,通过此在释放锁的时候进行判断。 获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。 释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。 setnx并不是原子操作,建议使用setex。另外基于Redission也可以实现分布式锁。

3. 基于Zookeeper实现分布式锁

基于ZooKeeper实现分布式锁的步骤如下: (1)创建一个目录mylock。 (2)线程A想获取锁就在mylock目录下创建临时顺序节点。 (3)获取mylock目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁。 (4)线程B获取所有节点,判断自己不是最小节点,设置监听比自己次小的节点。 (5)线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是不是最小的节点,如果是则获得锁。

4. 总结

ZooKeeper版本的分布式锁问题相对比较来说少。

锁的占用时间限制:redis就有占用时间限制,而ZooKeeper则没有,最主要的原因是Redis目前没有办法知道已经获取锁的客户端的状态,是已经挂了呢还是正在执行耗时较长的业务逻辑。而ZooKeeper通过临时节点就能清晰知道,如果临时节点存在说明还在执行业务逻辑,如果临时节点不存在说明已经执行完毕释放锁或者是挂了。由此看来redis如果能像ZooKeeper一样添加一些与客户端绑定的临时键,也是一大好事。

是否单点故障:Redis本身有很多中玩法,如客户端一致性hash,服务器端sentinel方案或者cluster方案,很难做到一种分布式锁方式能应对所有这些方案。而ZooKeeper只有一种玩法,多台机器的节点数据是一致的,没有Redis的那么多的麻烦因素要考虑。


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 基于数据库实现分布式锁
  • 2. 基于Redis实现分布式锁
  • 3. 基于Zookeeper实现分布式锁
  • 4. 总结
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档