文章目录

  • 1、分布式锁本质
  • 2、分布式锁存储选型及场景
  • 3、分布式锁接口设计
  • 4、AP 模型的 Redis 分布式锁实现
  • 5、CP 模型的 etcd 分布式锁实现
  • 6、CP 模型的 etcd 分布式锁实现源码

林淮川 毕业于西安交通大学,现任大树金融架构师,技术委员会委员;前大树金融供应链金融技术总监;前天阳宏业交易事业部技术主管。5 年互联网金融行业业务经验。多次主导金融服务平台的设计、策划、实施与交付。拥有丰富的大型软件平台构架设计经验,以及供应链金融业务经验。

孙玄:毕业于浙江大学,现任转转公司首席架构师,技术委员会主席,大中后台技术负责人(交易平台、基础服务、智能客服、基础架构、智能运维、数据库、安全、IT 等方向);前58集团技术委员会主席,高级系统架构师;前百度资深研发工程师;

【架构之美】微信公众号作者;擅长系统架构设计,大数据,运维、机器学习等技术领域;代表公司多次在业界顶级技术大会 CIO 峰会、Artificial、Intelligence、Conference、A2M、QCon、ArchSummit、SACC、SDCC、CCTC、DTCC、Top100、Strata+、Hadoop World、WOT、GITC、GIAC、TID等发表演讲,并为《程序员》杂志撰稿 2 篇。

1、分布式锁本质

提到分布式锁,有很多实现,比如 Redis 分布式锁、ZooKeeper 分布式锁、etcd分布式锁等。但是选择哪个更适合你的项目?在《基于CAP模型设计企业级真正高可用的分布式锁》一文深入分析过分布式锁的哲学本质,以及如何结合场景来选择合适的分布式锁。分析业务场景,得到业务本质,就是架构思维。思维最终是需要落地的,接下去分享一下对分布式锁的思考和实践。

锁的本质是对共享资源的处理,表现很多,有以下作用:

  1. 业务协调
  2. 业务幂等(需配合业务代码实现)
  3. 共享资源竞争

在单体应用时代表现为同步块 lock。随着需求和业务量的增长,系统走向了分布式、微服务时代,多服务和多实例下的应用无法使用本地锁进行控制资源共享。此时就出现了分布式锁,分布式场景下对分布式锁的要求如下:

  1. 强一致性
  2. 服务高可用、系统稳健
  3. 锁自动续约、自动释放
  4. 业务可重入

2、分布式锁存储选型及场景

目前常见分布式锁的实现有 Redis、ZooKeeper、etcd 等,各维度指标对比如下:

一致性算法(CAP):在分布式场景下,CAP 理论是很多架构设计的指导思想。CAP 思想下有两个分支 CP 与 AP;CP 模型不管什么情况下,都要求各服务之间的数据一致;AP 模型高可用下的数据最终一致性。虽然锁原本要求强一致性 CP模型,但 AP 模型分布式锁的使用取决于业务场景对脏数据的最大容忍度,比如SNS 场景,就可以使用AP模型分布式锁,从而在性能上有很大的优势。CP 模型仍然保持原有的一致性要求,保证了业务资源串行竞争,更加适合于金融交易场景的强数据要求。Redis 自身无一致性算法来保证多节点的数据一致性,所以是 AP 模型;ZooKeeper、etcd 都有一致性算法,都是 CP 模式。

高可用:Redis 是一个 K-V 存储,使用主从模式进行集群,Redis Cluster 底层也是主从模式的组合,性能高,保证了高可用。ZooKeeper 是 Tree 的数据结构,节点要求 N + 1,N 必须大于 2,通过 ZAB 选举保障主的可用。etcd 是一个 K-V 存储,节点要求 N + 1,N 必须大于2,通过 Raft 选举保障主的高可用。

3、分布式锁接口设计

根据需求,设计出锁接口,首先锁的基本方法如下:

 /*** @方法名称 lock* @功能描述 <pre>获取锁</pre>* @param ttl 锁过期时间,单位毫秒* @return true-获取锁,false-为获得锁* @throws RuntimeException 操作锁失败,需要业务判断是否重试*/boolean lock(int ttl) throws RuntimeException;

第二,分布式锁可以处理业务幂等,可用作为消息去重等场景,设计竞争锁方法如下:

 /*** @方法名称 acquire* @功能描述 <pre>竞争锁,并自动续租</pre>* @param ttl 锁过期时间,单位毫秒* @return true-获取锁,false-为获得锁* @throws RuntimeException 操作锁失败,需要业务判断是否重试*/default boolean acquire(int ttl)throws RuntimeException {if (lock(ttl)) {logger.debug(MSG_LOCK, getName());startHeartBeatThread();return true;}return false;}

第三,作为锁的基本要求,业务的串行执行,设计等待锁方法如下:

   /*** @方法名称acquireOrWait* @功能描述 <pre>竞争锁或等待锁</pre>* @param ttl 锁过期时间,单位毫秒* @param waitTime 等待时间,单位毫秒* @return true-获取锁,false-为获得锁* @throws InterruptedException* @throws RuntimeException 操作锁失败,需要业务判断是否重试*/default boolean acquireOrWait(int ttl, int waitTime)throws InterruptedException,RuntimeException {while (!lock(ttl)) {waitTime =waitTime - ttl / 2;Thread.sleep(ttl / 2);if (waitTime<= 0) {logger.debug(MSG_LOCK_TIMEOUT, getName());return false;}}startHeartBeatThread();return true;}

第四,分布式场景,锁需要自动续租方法,保障锁内业务完整执行,如下:

 /*** @方法名称startHeartBeatThread* @功能描述 <pre>续租心跳</pre>*/void startHeartBeatThread();

第五,锁需要自动释放,为保证使用简单,所以重写 Closeable 接口:

 /*** @方法名称 close* @功能描述 <pre>释放锁</pre>*/@Overridevoid close();/*** @方法名称 release* @功能描述 <pre>释放锁</pre>*/default void release() {close();}

4、AP 模型的 Redis 分布式锁实现

5、CP 模型的 etcd 分布式锁实现

etcd 有 V2 和 V3 两种接口:V2 接口可以使用 http 直接访问,天然客户端物理解耦,但需要自动续租保证锁的完整性。V3 接口默认 grpc 形式,是长链接机制,天然续租,但 grpc 有客户端依赖要求。可以根据场景要求,适度选择合适版本接口。

锁参数有:

  1. prevExits:检查是否存在,true:新增,false:更新;
  2. prevIndex:检查上一个的 key,既操作返回的 uuid;
  3. prevValue:检查上一个的值;

Linux curl 锁操作:

  1. 取锁:curl http://ip:port/v2/keys/锁名 -XPUT -d ttl=10 -d prevExits=false
    -d value=锁值
  2. 续租:curl http://ip:port/v2/keys/锁名?prevValue=锁值 -XPUT -d ttl=3 -dprevExits=true -d refresh=true
  3. 释放锁:curl
    http://ip:port/v2/keys/锁名?prevValue=锁值 -XDELETE

6、CP 模型的 etcd 分布式锁实现源码

全部源代码请访问以下链接:
https://github.com/linhuaichuan/ecp-uid/tree/master/src/test/java/com/myzmds/ecp/core/standard/distributed/lock

林淮川孙玄:分布式锁选型背后的架构设计思维【附源码】相关推荐

  1. 分布式锁选型背后的架构设计思维【附源码】

    1. 分布式锁本质 提到分布式锁,有很多实现,比如Redis分布式锁.ZooKeeper分布式锁.etcd分布式锁等.但是选择哪个更适合你的项目?在<基于CAP模型设计企业级真正高可用的分布式锁 ...

  2. 【SDCC讲师专访】58同城孙玄:一切抛开业务的架构设计都是耍流氓

    本期我们采访的讲师是来自58同城高级系统架构师&技术负责人孙玄,他是58的技术委员会架构组主任,产品技术学院优秀讲师,代表58同城参与多次对外演讲. 58同城高级系统架构师,技术委员会架构组主 ...

  3. 分布式 ID 生成系统 Leaf 的设计思路,源码解读

    什么是分布式ID? ID 最大的特点是 唯一 而分布式 ID,就是指分布式系统下的 ID,它是 全局唯一 的. 为啥需要分布式ID呢? 这就和 唯一 息息相关了. 比如我们用 MySQL 存储数据,一 ...

  4. Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载)

    Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载) 说明:主要是针对一些中大型的项目需要进行分布式以及负载均衡的架构提一些思路与建议. 面对大量用户访问.高并发请求,海量 ...

  5. JAVA计算机毕业设计林家餐厅自助点餐管理系统(附源码、数据库)

    JAVA计算机毕业设计林家餐厅自助点餐管理系统(附源码.数据库) 目运行 环境项配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Ecli ...

  6. 智能锁方案PCBA原理图PCB单片机开发板源码wifi远程开锁。 提供全套技术资料,包括原理图,PCB图,程序源码,bom清单,说明书等

    智能锁方案PCBA原理图PCB单片机开发板源码wifi远程开锁. 提供全套技术资料,包括原理图,PCB图,程序源码,bom清单,说明书等. 该指纹密码锁具有如下功能: 一.指纹开门 二.触摸密码开门 ...

  7. VC++电脑锁屏(附源码)

      VC++开发常用功能一系列文章 (欢迎订阅,持续更新...) 第14章:VC++电脑锁屏(附源码) 源代码demo已上传到百度网盘:永久生效 ,文章尾部附 百度链接 源代码demo已上传到百度网盘 ...

  8. java毕业设计分布式集群的设备维保系统mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计分布式集群的设备维保系统mybatis+源码+调试部署+系统+数据库+lw java毕业设计分布式集群的设备维保系统mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: ...

  9. 分享个微信锁再也不怕别人偷看!附源码

    介绍: 分享个微信锁再也不怕别人偷看!附源码 网盘下载地址: http://kekewl.net/Z2PLSi6gPmb 图片:

  10. 通过路由器或服务器实现多路由多网络接入网路传输提速详细实现(附源码),五万字搞懂双路由、旁路由、分布式路由、CN2线路、IPLC线路、BGP线路的原理和实现

    通过路由器或服务器实现多路由多网络接入网路传输提速详细实现(附源码),搞懂双路由.旁路由.分布式路由.CN2线路.IPLC线路.BGP线路的原理和实现. 双wan口路由器如何实现双线接入(双wan口路 ...

最新文章

  1. 深度观察|工业物联网的应用场景和市场潜力
  2. element-ui中的loading的实际应用
  3. PHP-php.ini中文版
  4. pagehelper插件oracle,带你学习最简单的分页插件PageHelper
  5. windows获取IP和MAC地址【Qt】
  6. 香港mtmit真皮休闲商务双用时尚浮点手拿包1018 烟灰色-大号 均码【图片 价格 品牌 报价】-京东商城...
  7. 【STM32H7教程】第39章 STM32H7的DMAMUX基础知识(重要)
  8. 文库/豆丁网等免账号,积分下载器
  9. 徐耀赐教授系列讲座——车道宽度理论在城市道路路网中的应用(编译文本)...
  10. [bzoj4136][fjoi2015]带字串包含约束lcs问题
  11. Creator技能按钮冷却效果
  12. python炫酷gui界面_如何炫酷的使用Python
  13. 「雷军万字总结」小米十周年公开演讲全文
  14. HTML标签的属性和特性
  15. Linux命令 ln
  16. 再不复工,公司就要发现没有我们也能正常运转了
  17. java表白 520
  18. 一切都结束了。OI退役感言。
  19. 全球限量HarmonyOS周边数字头像卫衣长袖T恤开箱!
  20. 编程的50种基础算法代码,编程常用算法有哪些

热门文章

  1. 谷粒商城项目基础篇总结文档
  2. Spring JdbcTemplate 与 事务管理
  3. 模型☀️Catia模型到Unity的转化过程
  4. 小米路由器青春版刷潘多拉、华硕固件
  5. win11家庭版,如何进入海康摄像头web后台
  6. adb 连接手机 cannot connect to xxx.xxx.x.xx:5555: 由于目标计算机积极拒绝,无法连接。 (10061)
  7. SVN下载安装及入门使用教程_win10_64位
  8. Learun敏捷框架甘特图——摆脱项目管理的泥沼
  9. 时序预测 | MATLAB实现DBN深度置信网络时间序列预测
  10. 谷歌浏览器 js 获取 汉字 乱码