searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

分布式锁实现方式

2023-11-23 08:46:42
1
0

分布式锁

在单机系统中,如果多线程对一个共享资源访问时,可以用锁处理。

在分布式系统中,多个服务对同一个共享的资源访问时,例如同一用户对于某个接口未返回时不能重复调用,由于服务不在同一机器或不能共享内存,不能共享之前的锁,即自己的锁只对自己有效并不影响别的 ,因此需要一个可以分布式锁的能力。

分布式锁能力有几种解决方案:

  1. 通过数据库实现分布式锁
  2. 基于缓存Redis实现分布式锁
  3. 基于Zookeeper实现分布式锁

1. 通过数据库实现分布式锁

具体的实现方法可以在数据库中创建一个表,包括调用方法名、参数、调用者、调用时间等字段,在调用时在不表中插入数据,表示成功获取锁,释放锁时删除记录。

该种方式实现起来不复杂,但是有一些缺点:

  1. 分布式锁的性能受制于数据库的性能;
  2. 没有锁失效机制,如果某次成功插入数据后,服务器宕机,导致锁一直没有释放
  3. 不具备锁阻塞特性,如果获取锁失败,需要制定获取逻辑,例如循环获取

2. 基于redis实现

redis实现分布式锁的方式就是,通过插入key-value,当key不存在时,增加k-v表示成功获取锁,如果k存在,表示获取失败。

其优点是,redis基于内存存储性能较高,而且redis支持set k-v时附带超时时间,即锁时间到期会自动释放,避免死锁相关问题

但redis同样不具备锁阻塞特性。

3. 基于Zookeeper

ZooKeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录下只能有一个唯一文件名。

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

Zookeeper具备高可用、可重入、阻塞锁特性。

0条评论
0 / 1000