保存成功
订阅成功
保存失败,请重试
提交成功

分布式锁的最佳实践之:基于 Etcd 的分布式锁

毕业于 C9 高校,硕士学历,曾在 IEEE ITS、VSD 等 Top 期刊发表论文。深耕 Java 技术栈,在 Python、C 语言方面亦有丰富经验,擅长预测算法,分布式中间件;曾在华为、阿里、上海电气等公司重要项目中担任技术负责人或核心研发成员,现专注于中间件技术,同时长期负责招聘。
查看本场Chat

引言

目前,可实现分布式锁的开源软件还是比较多的,其中应用最广泛、大家最熟悉的应该就是 ZooKeeper,此外还有数据库、Redis、Chubby 等。但若从读写性能、可靠性、可用性、安全性和复杂度等方面综合考量,作为后起之秀的 Etcd 无疑是其中的 “佼佼者” 。它完全媲美业界“名宿” ZooKeeper,在有些方面,Etcd 甚至超越了 ZooKeeper。本场 Chat 将继续“分布式锁”这一主题,介绍基于 Etcd 分布式锁方案。

本场 Chat 主要内容:

  1. Raft 算法解读;
  2. Etcd 介绍;
  3. Etcd 实现分布式锁的原理;
  4. Etcd Java 客户端 Jetcd 介绍;
  5. 从原理出发:基于 Etcd 实现分布式锁,全方位细节展示;
  6. 从接口出发:基于 Etcd 的 Lock 接口实现分布式锁。

敬请关注 :达人课《分布式中间件实践之路》,内容涵盖分布式消息队列、缓存和锁。

本场 Chat 分为两大部分:

  • 一、分布式一致性算法 Raft 原理 及 Etcd 介绍;
  • 二、基于 Etcd 的分布式锁实现原理及方案。

本场 Chat 内容丰富,建议读者在 PC 端阅读。

第一部分:分布式一致性算法 Raft 原理 及 Etcd 介绍

1. 分布式一致性算法 Raft 概述

“工欲善其事,必先利其器。” 懂得原理方能触类旁通,立于不败之地。本场 Chat 将分 4 节详细解读著名的分布式一致性算法——Raft,在此基础上,再介绍 Etcd 的架构和典型应用场景。

1.1 Raft 背景

在分布式系统中,一致性算法至关重要。在所有一致性算法中,Paxos 最负盛名,它由莱斯利 · 兰伯特(Leslie Lamport)于 1990 年提出,是一种基于消息传递的一致性算法,被认为是类似算法中最有效的。

Paxos 算法虽然很有效,但复杂的原理使它实现起来非常困难,截止目前,实现 Paxos 算法的开源软件很少,比较出名的有 Chubby、libpaxos。此外 Zookeeper 采用的 ZAB(Zookeeper Atomic Broadcast)协议也是基于 Paxos 算法实现的,不过 ZAB 对 Paxos 进行了很多的改进与优化,两者的设计目标也存在差异——ZAB 协议主要用于构建一个高可用的分布式数据主备系统,而 Paxos 算法则是用于构建一个分布式的一致性状态机系统。

由于 Paxos 算法过于复杂、实现困难,极大的制约了其应用,而分布式系统领域又亟需一种高效而易于实现的分布式一致性算法,在此背景下,Raft 算法应运而生。

Raft 算法由斯坦福的 Diego Ongaro 和 John Ousterhout 于 2013 年发表:《In Search of an Understandable Consensus Algorithm》。相较于 Paxos,Raft 通过逻辑分离使其更容易理解和实现,目前,已经有十多种语言的 Raft 算法实现框架,较为出名的有 etcd、Consul 。

1.2 Raft 角色

一个 Raft 集群包含若干节点,Raft 把这些节点分为三种状态:Leader、 Follower 、Candidate,每种状态负责的任务也是不一样的,正常情况下,集群中的节点只存在 Leader 与 Follower 两种状态。

  • Leader(领导者):负责日志的同步管理,处理来自客户端的请求,与 Follower 保持 heartBeat 的联系;
  • Follower(追随者):响应 Leader 的日志同步请求,响应 Candidate 的邀票请求,以及把客户端请求到 Follower 的事务转发(重定向)给 Leader;
  • Candidate(候选者):负责选举投票,集群刚启动或者 Leader 宕机时,状态为 Follower 的节点将转为 Candidate 并发起选举,选举胜出(获得超过半数节点的投票)后,从 Candidate 转为 Leader 状态;

1.3 Raft 概述

通常,Raft 集群中只有一个 Leader,其它节点都是 Follower 。Follower 都是被动的:它们不会发送任何请求,只是简单的响应来自 Leader 或者 Candidate 的请求。Leader 负责处理所有的客户端请求(如果一个客户端和 Follower 联系,那么 Follower 会把请求重定向给 Leader)。为简化逻辑和实现,Raft 将一致性问题分解成了三个相对独立的子问题:

  • 选举(Leader election):当 Leader 宕机或者集群初创时,一个新的 Leader 需要被选举出来;
  • 日志复制(Log replication):Leader 接收来自客户端的请求并将其以日志条目的形式复制到集群中的其它节点,并且强制要求其它节点的日志和自己保持一致。
  • 安全性(Safety):如果有任何的服务器节点已经应用了一个确定的日志条目到它的状态机中,那么其它服务器节点不能在同一个日志索引位置应用一个不同的指令。

2. Raft 算法之 Leader election 原理

根据 Raft 协议,一个应用 Raft 协议的集群在刚启动时,所有节点的状态都是 Follower,由于没有 Leader,Followers 无法与 Leader 保持心跳(Heart Beat),因此,Followers 会认为 Leader 已经 down,进而转为 Candidate 状态。然后,Candidate 将向集群中其它节点请求投票,同意自己升级为 Leader,如果 Candidate 收到超过半数节点的投票(N/2 + 1),它将获胜成为 Leader。

第一阶段:所有节点都是 Follower

根据 Raft 协议,一个应用 Raft 协议的集群在刚启动时(或者 Leader 宕机),所有节点的状态都是 Follower,初始 Term(任期)为 0。同时启动选举定时器,每个节点的选举定时器超时时间都在 100-500 毫秒之间且并不一致(避免同时发起选举)。

enter image description here

第二阶段:Follower 转为 Candidate 并发起投票

由于没有 Leader,Followers 无法与 Leader 保持心跳(Heart Beat),节点启动后在一个选举定时器周期内未收到心跳和投票请求,则状态转为候选者 candidate 状态、Term 自增,并向集群中所有节点发送投票请求并且重置选举定时器。

注意:由于每个节点的选举定时器超时时间都在 100-500 毫秒之间,且不一致,因此,可以避免所有的 Follower 同时转为 Candidate 并发起投票请求。换言之,最先转为 Candidate 并发起投票请求的节点将具有成为 Leader 的 “先发优势”。

enter image description here

第三阶段:投票策略

节点收到投票请求后会根据以下情况决定是否接受投票请求:

  1. 请求节点的 Term 大于自己的 Term,且自己尚未投票给其它节点,则接受请求,把票投给它;
  2. 请求节点的 Term 小于自己的 Term,且自己尚未投票,则拒绝请求,将票投给自己。

enter image description here

互动评论
评论
S.X.H ☀ 🌙 ⭐1 年前
这篇文章个人觉得不值10元,不过能写这么长也是很棒了
评论
查看更多