redis分布式锁的学习记录

核心性质

独占性:对于同一把锁,同一时刻只能被一个加锁方独占
健壮性:不能产生死锁。如果有一个因为宕机无法主动解锁,锁也应该被正常加载
对称性:加成和解锁的使用方必须为同一个身份,不允许被非方释放
高可用:当提供分布式锁服务的基础组件中存在少量节点发生故障时,不应该影响到分布式锁服务的稳定性

实现类型

对 cpu 空转以及阻塞协程两种行为的损耗做出权衡

主动轮询型:该模型类似于单机锁中的主动轮询 + cas 乐观锁模型,取锁方会持续对分布式锁发出尝试获取动作,如果锁已被占用则会不断发起重试,直到取锁成功为止
watch 回调型:在取锁方发现锁已被他人占用时,会创建 watcher 监视器订阅锁的释放事件,随后不再发起主动取锁的尝试;当锁被释放后,取锁方能通过之前创建的 watcher 感知到这一变化,然后再重新发起取锁的尝试动作

分布式场景中”轮询“,背后存在的行为可能是一次甚至多次网络 IO 请求.但是,watch 机制在实现过程中需要建立长连接完成 watch 监听动作,也会存在一定的资源损耗

主动轮询型

针对同一把分布式锁,用同一条数据标识(redis中的string同一个key对应的value)
假如在插入之前不存在数据,插入成功,则被认定为加锁
把从存储介质中删除类比成解锁动作
假如在插入之前存在,则持续轮训,直到数据被删除,并有自己插入成功
由于是并发场景,需要保证【 (1)检查数据是否已被插入(2)数据不存在则插入数据 】这两个步骤之间是原子化不可拆分的(在 redis 中是 set only if not exist —— SETNX 操作)

死锁问题

使用 redis 时,通过过期时间 expire time自动删除.
过期机制问题:锁的持有者并不能精确预判到自己持锁后处理业务逻辑的实际耗时,假如因为一些异常情况导致占有锁的使用方在业务处理流程中的耗时超过了设置的过期时间阈值,就会导致锁被提前释放,其他取锁方可能取锁成功,最终引起数据不一致的并发问题.
解决方案:在锁的持有方未完成业务逻辑的处理时,会持续对分布式锁的过期阈值进行延期操作.

弱一致性问题

redis是ap形式,为保证服务的吞吐性,主从节点之间的数据同步是异步延迟进行。
问题 :倘若 使用方 A 在 redis master 节点加锁成功,但是对应的 kv 记录在同步到 slave 之前,master 节点就宕机了. 此时未同步到这项数据的 slave 节点升为 master,这样分布式锁被 A 持有的“凭证” 就这样凭空消失了. 于是不知情的使用方 B C D 都可能加锁成功,于是就出现了一把锁被多方同时持有的问题,导致分布式锁最基本的独占性遭到破坏.

watch 回调型

差别在于

倘若在插入数据时,发现该条记录已经存在,说明锁已被他人持有,此时选择监听这条数据记录的删除事件,当对应事件发生时说明锁被释放了,此时才继续尝试取锁

你可能感兴趣的:(redis,分布式,学习)