分布式锁实战-基于Etcd的实现很优雅

网站建设3年前发布
60 0 0

虽然Kubernetes 给云原生时代带来了颠覆性的新气象,但却很少人了解被钦定作为其后端存储的 etcd ,本篇从分布式锁视角梳理etcd的各种机制,探索基于etcd的锁实现是怎样。,etcd 能被Kubernetes 如此青睐,是因为它一直在聆听社区的声音并快速改进,积极配合 Kubernetes 项目向前推进,解决社区反馈的痛点;发起 V2 到 V3 的重大版本更新,尤其是 19 年由 Google、Alibaba 等公司联合打造的 3.4 版本,满足了 Kubernetes 在超大型公司大规模使用中严苛的可用性、扩展性和性能等要求。,20230306134435959443c0580575d7dab892aa568805bb55ab2a190,上图描述了 etcd 名字的由来,其寓意是为大规模分布式系统提供存储配置信息;华为 Kubernetes 专家杜军老师专门为 etcd 著书《云原生分布式存储基石-etcd》,称它基石足见何等重要,另一位大咖etcd 的作者李响老师曾讲:“etcd 就是用来存储云上最重要的数据的”;相信随着云原生架构的演进,etcd 会担任越来越多重要的角色;技术人员在云原生时代,除了拥抱 Kubernetes,也要拥抱 etcd。,很长一段时间 ZooKeeper(后文简称 ZK) 被作为默认首选项,用于解决分布式系统的协同和元数据存储,但其太复杂、迭代慢、难维护、性能缺陷等问题逐渐成为槽点;而 etcd 吸取了 ZK 的教训,从设计和实现上具有后见之明,提供了更好的工程和运维体验,其主要改进在于如下几个方面:,据说在一个由 3 台 8 核节点组成的云服务器上, etcd v3 版本可以做到每秒数万次的写操作和数十万次的读操作(ZK:20230306134528c3db8ad177a0c2b343d587f7f16c18323a0f59277);后续会有其他篇章结合QA的测试结果来探讨etcd服务端的设计和性能情况。,为满足本篇目标所需,也考虑到对 etcd 熟悉的读者不多,这里着重介绍以下几个关键特性:,2023030613443624eb0b7595f431067ae040bcdf8062845ec986771,2023030613443746888de15e422da0dc74846cf7368c58bc488f299,20230306134439312837129b149803f3790561c964aa8716f951980,20230306134439d890108756073e545be903291199bfd395ea37137,2023030613444096a621b544bd8d4c8d4674d045025f12508c80951,etcd 的分布式锁正是基于以上特性来实现的,简单来说是:,20230306134528774361f074d389790b08945d881af7b1f3fff0784,client-a 线程 1 的 key 为"/lock/lock1/uuid1",申请 lock1,client-a 线程 2 的 key 为"/lock/lock1/uuid2",申请 lock1,client-c 线程 1 的 key 为"/lock/lock2/uuid3",申请 lock2,client-b 线程 1 的 key 为"/lock/lock2/uuid4",申请 lock2,持锁状态:当业务未完成时,不能让租约到期,需定时续租;当业务完成时可主动解除租约,持锁 Key 会被删除;若客户端异常,租约到期后持锁 Key 也会被删除;等锁的客户端监听到持锁 Key 被删除后,可开始抢锁。,等锁状态:等锁超时会主动解除租约,或客户端异常时等锁 key 被删除,后边排队的就前进一步,尝试抢锁。,可能读者是单篇阅读,这里引入第一篇《分布式锁上-初探》中的一些内容,一个分布式锁应具备这样一些功能特点:,基于上边对 etcd 分布式锁的介绍,这里简单总结一下 etcd 的能力矩阵,ZK 的情况请看《分布式锁中-基于 Zookeeper 的实现》,redis锁的情况会在后续文章中补充,etcd 针对 java 语言的客户端有官方的 jetcd-core 还有 IBM 的 etcd-java,下文使用 jetcd-core 做示例。,jetcd-core 中提供了高阶的 Lock API(无需使用者准备唯一 key、前缀查询 Key-Value 列表、排序判断自己是否 revision 最小的、监听前一个 Key-Value 的删除),使用者只需关注最原始的诉求:申请的锁是什么名称、用多久,申请不到就等多久;使用高阶 API 实现分布式锁的流程会比第 2 部分原生的流程要简单许多,流程如下:,方案 1-创建定时任务定时续租,方案 2-使用自动续约,本篇从 etcd V3 版本的 Lease、Prefix 、Watch 等关键特性切入,介绍了如何基于这些特性来实现一个分布式锁,并基于jetcd-core库提供了一个分布式锁的示例,呈现了其关键API的用法;此示例尚未达到生产级可用,如异常、可重入、可重试、超时控制等功能都未补全,计划在下一篇介绍完redis之后,再介绍一个健壮的分布式锁客户端要如何抽象设计,如何适配 ZK 、Redis 、etcd 。,本文转载自微信公众号「架构染色」,可以通过以下二维码关注。转载本文请联系【架构染色】公众号作者。,20230306134441383554f53dd1f445c8f091ed84c2f942a1f54f141,

© 版权声明

相关文章