分布式锁有哪些实现方式?

核心问题

可用性,死锁、脑裂、惊群效应

基于关系型数据库实现

  • 悲观锁
  • 乐观锁

基于Zookeeper实现

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

基于ZooKeeper实现分布式锁的步骤如下:

  1. 创建一个目录mylock;

  2. 线程A想获取锁就在mylock目录下创建临时顺序节点;

  3. 获取mylock目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁;

  4. 线程B获取所有节点,判断自己不是最小节点,设置监听比自己次小的节点;

  5. 线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是不是最小的节点,如果是则获得锁。

基于Redis实现

  • setnx方式
  • RedLock 算法

思考

Redis分布式锁问题?

  1. setnx方式:实现锁和超时时间来控制锁的失效

但是Redis集群主备切换、脑裂是 Redis 分布式锁的两个典型不安全的因素,本质原因是 Redis 为了满足高性能,采用了主备异步复制协议。

根据对CAP理论的理解,Redis的设计模型是采用AP模型,分布式锁是一个CP场景,将AP模型应用到CP场景,本身技术选型上就是错误。

  1. RedLock 算法实现:

它的实现建立在一个不安全的系统模型上的,它依赖系统时间,当时钟发生跳跃时,也可能会出现安全性问题。

ZK应对核心分布式锁问题?

 zxid or the znode version number, 临时节点(有效期控制,避免客户端异常死锁发送);

同时提供了 Watch 特性可监听 key 的数据变化

etcd应对核心分布式锁问题?

Lease( 租约,自动续约),  mod_revision,  create_revision, 

watch机制: 每个节点watch上一个节点,以此进行等候排队,不是同时watch一个节点,导致大量锁的竞争,以此避免惊群效应(羊群效应)

如何避免业务执行时间过长,导致锁自动过期提前释放?

version检查: 如果是过期(老)的version,请求abort

你可能感兴趣的:(我的思考,etcd,分布式)