• 原文:分布式锁那些事
  • 本文是在原文基础上用自己的语言试着更简洁的转述一遍,类似提纲,加入自己的小理解,和少部分扩展思考,内容基本为原文

分布式锁机制及几种方案对比

为什么需要分布式锁

  • 保证同一方法同一时间只有一个线程执行
  • 单机性能有限,服务由单体部署拆分成分布式部署
  • 需要跨进程,跨机,跨数据中心一致性方案(单进程内各语言或自身有锁方案,或配合架构有特定的组件集成)

分布式锁要求

  • 同一时刻一个方法只能有一个进程的一个线程执行
  • 高可用
  • 高性能
  • 锁失效方案
  • 支持阻塞锁,获取锁失败可以继续尝试获取
  • 支持非阻塞锁,获取失败立刻返回

分布式锁的三种方案分析

数据库方案

  • 操作
    • 数据库建表,在方法名上创建唯一索引
    • 在表中插入方法名,执行者等的一条数据,插入成功获取锁
  • 优势
    • 借助数据库,结构简单
  • 不足
    • 受限数据库性能(可能要求多机部署,主备复制,数据同步等)
    • 没有锁失效方案
    • 不可重入
    • 没有阻塞锁方案,需要自行循环

Redis方案

  • 操作(2.6.12版之前)
    • setnx设置key-value
    • expire设置过期时间
    • del释放
  • 问题及对应解决方案
    • 每一步的操作都要保证原子性,set完没来得及设expire会导致死锁(2.6.12版实现了将两个操作合并原子化操作)
    • 分布式环境下,A获取锁后阻塞,锁过期被B获取,A恢复后执行完错误释放了此时属于B的锁(经典CAS算法解决被误释放问题,但原本线程操作未完就失去锁的问题并没解决)
    • 高可用要求主从复制机制,而主从复制多为异步,会出现数据不一致(不主从复制,用RedLock算法,该算法的成熟开源实现即Redisson,此处并不明白该算法如何解决主从复制的问题)
  • 整体优势:借助Redis,实现方便
  • 问题:超时作为锁失效机制不可靠,若处理时间过长会在完成前失去锁

Zookeeper方案

  • 结构:内部分层文件系统目录树
  • 操作
    • (原文有不清晰之处,待日后补充)
  • 优点
    • 高可用
    • 可重入
    • 阻塞锁
    • 解决锁失效
  • 缺点:频繁插入删除性能会比Redis差一些

其他

Redlock算法

  • 大致思想为布置多个Redis Master节点,挨个申请锁,获取多数则成功,少数则在所有节点上解锁?

Written with StackEdit.