分布式锁的3种实现
Posted 我爱看明朝
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式锁的3种实现相关的知识,希望对你有一定的参考价值。
分布式锁的3种实现
我们在线上部署只有一个应用实例的时候,我们可用sychronized、lock来加锁,但是当部署了多个实例,实例间要对资源进行加锁,就要使用分布式锁了。
我们这里介绍3种分布锁的实现方式:
- db
- redis
- zk
数据库
数据库实现分布式锁的原理有两种一种基于悲观锁,一种基于乐观锁。spring帮助我们提供了一套shedlock的分布式锁。
- 悲观锁 shedlock
- 乐观锁
zk
我们知道zk的节点分为持久节点、持久顺序节点、临时节点、临时顺序节点。
持久节点: 创建后一直存在,直到主动删除此节点。
持久顺序节点:创建后一直存在,知道主动删除此节点,在zk中,每个父节点会为它的第一级子节点维护一份时序,记录每个子节点创建的先后顺序。
临时节点:在客户端会话失效后节点自动清除,临时节点下面不能创建子节点。
临时顺序节点;在客户端会话失效后节点自动清除,临时节点下面不能创建子节点。
我们可以利用持久节点 + 临时顺序节点的特性来创建分布式锁。
zk持久节点 + 临时顺序节点 : 当客户端尝试获取锁,没有持久节点创建,同时创建临时顺
序节点,当临时顺序节点是最小的节点,则获取到锁,否则监听,当自己持有的临时顺序节点是最小的则获取锁。
redis
我们也可以利用redis的单线程特性,来实现分布式锁。
- 利用set和expire实现锁
- 利用set ex x nx
- 利用redisson
- 利用redisson + redlock
set和expire
我们可以分别利用set命令实现加锁及expire处理死锁问题或进程意外退出没有释放锁。
这种方案有缺点就是set和expire不是原子执行,当set执行完进程崩溃了,锁就永远无法释放。
set ex px nx
我们可以利用set ex px nx的方案来实现保障set和expire的原子性。
但是设置过期时间这个方案有缺点,过期时间设置的长了,导致效率低下,太短又会存在过期时间太短,业务逻辑还未执行完,锁被释放了。
redisson
redisson可以避免过期时间太长太短的问题,有一个守护进程,定时判断,锁是否存在,存在则延长锁的到期时间。
redisson: 是一个在redis的基础上实现的java驻内存数据网路,redisson底层采用netty网络框架。
redisson封装的redlock
由于单台redis机器,会存在机器故障挂掉的可能性,因此在上面的基础上,又提出了redlock:5台不同步的master,当获得锁时分别从这5台机器上获取锁,当大于等于3台获取到锁,则认为获取到了锁。
redisson给我们封装好了api。
参考
什么是分布式锁?实现分布式锁的三种方式
redlock: redis分布式锁最牛逼的实现
以上是关于分布式锁的3种实现的主要内容,如果未能解决你的问题,请参考以下文章