从动图来理解 Raft 协议关键概念

节点状态FollowerCandidateLeaderLearner领导选举(Leader Selection)节点的初始状态为 Follower。选举超时(Election Timeout)当处于 Follower 状态的节点没有收到 Leader 节点的心跳时,会开启计时,经过 Election

节点状态

  • Follower
  • Candidate
  • Leader
  • Learner

领导选举(Leader Selection)

节点的初始状态为 Follower

选举超时(Election Timeout)

当处于 Follower 状态的节点没有收到 Leader 节点的心跳时,会开启计时,经过 Election Timeout 后,他们会变成 Candidate 状态。

Election Timeout

当节点变成 Candidate 状态后,会开始为自己拉票做 Leader。当多数人投票给当前节点时,当前节点当选 Leader

Election Timeout

心跳超时(Heartbeat Timeout)

节点当选 Leader 之后,会周期性地向 Follower 发送心跳包;当 Follower 收到心跳后,会重置自己的 Election Timeout 计时,并向 Leader 发送响应。

Election Timeout

Leader 处于不可用的状态时,率先结束 Election TimeoutFollower 节点,会发起选举投票。

  • 得到大多数投票后,当选下个 Term 的 Leader
sQOHwL

同时存在两个 Follower 在拉票,且双方都不能得到大多数投票时,此次选举作废,并开启下一轮投票。具体情景说明如下:

A、B 节点几乎同时发起投票,并且各自为各自投一张票

utgkAL

此时,D 未收到投票请求,发起了自己的投票,并为自己投了一票。

zcxXRn

B 为 C 投了一票,此时的得票为 A(1),C(2),D(1),无论谁都不能获取到大多数的投票,因此此次投票作废,等待下次某个幸运的节点发起选举投票。

q8AF0W

日志复制(Log Replication)

0yw3oU

假设客户端是将修改的请求发送给 Leader,则修改的流程如下:

  1. 写入 Leader 的 log 中;
  2. 等待下次 HeartBeat,将修改信息同步给 Follower
  3. FollowerLeader 发出确认响应;
  4. Leader 收到大多数 Follower 确认的信息后,将修改确认;
  5. 在下次 HeartBeat 时,将修改确认的信息同步给所有 Follower

节点出现网络隔离

假设出现网络隔离后,出现两个独立的网络,此时:

  • 少数派:只读,修改不能确认,因为得不到大多数 Follower 节点的确认。
  • 多数派:能正常读写。
48xl7v

假设两个网络对同一个 key 做了操作,当网络隔离取消后,会以多数派的数据为准。

Reference

Read more

容器镜像(4):镜像的常用工具箱

容器镜像(4):镜像的常用工具箱

前几篇在讲多架构镜像时已经用过 skopeo 和 crane 做镜像复制,这篇系统整理这两个工具的完整能力,同时介绍几个日常操作镜像时同样好用的工具。 一、skopeo:不依赖 Daemon 的镜像瑞士军刀 skopeo 的核心价值是绕过 Docker daemon,直接与 Registry API 交互。上一篇用它做镜像复制和离线传输,但它的能力远不止于此。 1.1 安装 # Ubuntu / Debian sudo apt install -y skopeo skopeo --version # skopeo version 1.15.1 1.2 inspect:免拉取检查镜像元数据 docker inspect 需要先把镜像拉到本地,skopeo inspect 直接向 Registry

容器镜像(3):多架构镜像构建

容器镜像(3):多架构镜像构建

一、什么是多架构镜像 1.1 OCI Image Index 上一篇介绍了单平台镜像的结构:一个 Manifest 指向 Config 和若干 Layer blob。多架构镜像在此之上多了一层——OCI Image Index(也叫 Manifest List),是一个轻量的索引文件,把多个单平台 Manifest 组织在一起: $ docker manifest inspect golang:1.22-alpine { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests&

容器镜像(2):containerd 视角下的镜像

容器镜像(2):containerd 视角下的镜像

一、为什么需要了解 containerd 如果你只用 docker run 跑容器,从来不关心底层,那可以不了解 containerd。但如果你在用 Kubernetes,或者想真正理解"容器运行时"是什么,containerd 是绕不开的。 事实上,当你执行 docker run 的时候,containerd 早就在后台悄悄工作了——Docker 从 1.11 版本开始,就把核心运行时剥离出来交给 containerd 负责。 1.1 Docker 的架构演变 早期的 Docker(1.10 及之前)是一个"大一统"的单体程序:一个 dockerd