从零开始入门 K8s | 手把手带你理解 etcd

导读:etcd 是用于共享配置和服务发现的分布式、一致性的 KV 存储系统。本文从 etcd 项目发展所经历的几个重要时刻开始,为大家介绍了 etcd 的总体架构及其设计中的基本原理。希望能够帮助大家更好的理解和使用 etcd。

一、etcd 项目的发展历程

etcd 诞生于 CoreOS 公司,它最初是用于解决集群管理系统中 OS 升级的分布式并发控制以及配置文件的存储与分发等问题。基于此,etcd 被设计为提供高可用、强一致的小型 keyvalue 数据存储服务。

项目当前隶属于 CNCF 基金会,被 AWS、Google、Microsoft、Alibaba 等大型互联网公司广泛使用。

最初,在 2013 年 6 月份由 CoreOS 公司向 GitHub 中提交了第一个版本的初始代码。

到了 2014 年的 6 月,社区发生了一件事情,Kubernetes v0.4 版本发布。这里有必要介绍一下 Kubernetes 项目,它首先是一个容器管理平台,由谷歌开发并贡献给社区,因为它集齐了谷歌在容器调度以及集群管理等领域的多年经验,从诞生之初就备受瞩目。在 Kubernetes v0.4 版本中,它使用了 etcd 0.2 版本作为实验核心元数据的存储服务,自此 etcd 社区得到了飞速的发展。

很快,在 2015 年 2 月份,etcd 发布了第一个正式的稳定版本 2.0。在 2.0 版本中,etcd 重新设计了 Raft 一致性算法,并为用户提供了一个简单的树形数据视图,在 2.0 版本中 etcd 支持每秒超过 1000 次的写入性能,满足了当时绝大多数的应用场景需求。2.0 版本发布之后,经过不断的迭代与改进,其原有的数据存储方案逐渐成为了新时期的性能瓶颈,之后 etcd 启动了 v3 版本的方案设计。

2017 年 1 月份的时候,etcd 发布了 3.1 版本,v3 版本方案基本上标志着 etcd 技术上全面成熟。在 v3 版本中 etcd 提供了一套全新的 API,重新实现了更高效的一致性读取方法,并且提供了一个 gRPC 的 proxy 用于扩展 etcd 的读取性能。同时,在 v3 版本的方案中包含了大量的 GC 优化,在性能优化方面取得了长足的进步,在该版本中 etcd 可以支持每秒超过 10000 次的写入。

2018 年,CNCF 基金会下的众多项目都使用了 etcd 作为其核心的数据存储。据不完全统计,使用 etcd 的项目超过了 30 个,在同年 11 月份,etcd 项目自身也成为了 CNCF 旗下的孵化项目。进入 CNCF 基金会后,etcd 拥有了超过 400 个贡献组,其中包含了来自 AWS、Google、Alibaba 等 8 个公司的 9 个项目维护者。

2019 年,etcd 即将发布全新的 3.4 版本,该版本由 Google、Alibaba 等公司联合打造,将进一步改进 etcd 的性能及稳定性,以满足在超大型公司使用中苛刻的场景要求。

二、架构及内部机制解析

总体架构

etcd 是一个分布式的、可靠的 key-value 存储系统,它用于存储分布式系统中的关键数据,这个定义非常重要。

一个 etcd 集群,通常会由 3 个或者 5 个节点组成,多个节点之间通过 Raft 一致性算法的完成分布式一致性协同,算法会选举出一个主节点作为 leader,由 leader 负责数据的同步与数据的分发。当 leader 出现故障后系统会自动地选取另一个节点成为 leader,并重新完成数据的同步。客户端在多个节点中,仅需要选择其中的任意一个就可以完成数据的读写,内部的状态及数据协同由 etcd 自身完成。

在 etcd 整个架构中,有一个非常关键的概念叫做 quorum,quorum 的定义是 (n+1)/2,也就是说超过集群中半数节点组成的一个团体,在 3 个节点的集群中,etcd 可以容许 1 个节点故障,也就是只要有任何 2 个节点可用,etcd 就可以继续提供服务。同理,在 5 个节点的集群中,只要有任何 3 个节点可用,etcd 就可以继续提供服务,这也是 etcd 集群高可用的关键。

在允许部分节点故障之后继续提供服务,就需要解决一个非常复杂的问题:分布式一致性。在 etcd 中,该分布式一致性算法由 Raft 一致性算法完成,这个算法本身是比较复杂的有机会再详细展开,这里仅做一个简单的介绍以方便大家对其有一个基本的认知。Raft 一致性算法能够工作的一个关键点是:任意两个 quorum 的成员之间一定会有一个交集(公共成员),也就是说只要有任意一个 quorum 存活,其中一定存在某一个节点(公共成员),它包含着集群中所有的被确认提交的数据。正是基于这一原理,Raft 一致性算法设计了一套数据同步机制,在 Leader 任期切换后能够重新同步上一个 quorum 被提交的所有数据,从而保证整个集群状态向前推进的过程中保持数据的一致。

etcd 内部的机制比较复杂,但 etcd 给客户提供的接口是简单直接的。如上图所示,我们可以通过 etcd 提供的客户端去访问集群的数据,也可以直接通过 http 的方式(类似 curl 命令)直接访问 etcd。在 etcd 内部,其数据表示也是比较简单的,我们可以直接把 etcd 的数据存储理解为一个有序的 map,它存储着 key-value 数据。同时 etcd 为了方便客户端去订阅数据的变更,也支持了一个 watch 机制,通过 watch 实时地拿到 etcd 中数据的增量更新,从而实现与 etcd 中的数据同步等业务逻辑。

API 介绍

接下来我们看一下 etcd 提供的接口,这里将 etcd 的接口分为了 5 组:

  • 第一组是 Put 与 Delete。上图可以看到 put 与 delete 的操作都非常简单,只需要提供一个 key 和一个 value,就可以向集群中写入数据了,删除数据的时候只需要指定 key 即可;
  • 第二组是查询操作。etcd 支持两种类型的查询:第一种是指定单个 key 的查询,第二种是指定的一个 key 的范围;
  • 第三组是数据订阅。etcd 提供了 Watch 机制,我们可以利用 watch 实时订阅到 etcd 中增量的数据更新,watch 支持指定单个 key,也可以指定一个 key 的前缀,在实际应用场景中的通常会采用第二种形势;
  • 第四组事务操作。etcd 提供了一个简单的事务支持,用户可以通过指定一组条件满足时执行某些动作,当条件不成立的时候执行另一组操作,类似于代码中的 if else 语句,etcd 确保整个操作的原子性;
  • 第五组是 Leases 接口。Leases 接口是分布式系统中常用的一种设计模式,其用法后面会具体展开。

数据版本机制

要正确使用 etcd 的 API,必须要知道内部对应数据版本号的基本原理。

首先 etcd 中有个 term 的概念,代表的是整个集群 Leader 的任期。当集群发生 Leader 切换,term 的值就会 +1。在节点故障,或者 Leader 节点网络出现问题,再或者是将整个集群停止后再次拉起,都会发生 Leader 的切换。

第二个版本号叫做 revision,revision 代表的是全局数据的版本。当数据发生变更,包括创建、修改、删除,其 revision 对应的都会 +1。特别的,在集群中跨 Leader 任期之间,revision 都会保持全局单调递增。正是 revision 的这一特性,使得集群中任意一次的修改都对应着一个唯一的 revision,因此我们可以通过 revision 来支持数据的 MVCC,也可以支持数据的 Watch。

对于每一个 KeyValue 数据节点,etcd 中都记录了三个版本:

  • 第一个版本叫做 create_revision,是 KeyValue 在创建时对应的 revision;
  • 第二个叫做 mod_revision,是其数据被操作的时候对应的 revision;
  • 第三个 version 就是一个计数器,代表了 KeyValue 被修改了多少次。

这里可以用图的方式给大家展示一下:

在同一个 Leader 任期之内,我们发现所有的修改操作,其对应的 term 值始终都等于 2,而 revision 则保持单调递增。当重启集群之后,我们会发现所有的修改操作对应的 term 值都变成了 3。在新的 Leader 任期内,所有的 term 值都等于3,且不会发生变化,而对应的 revision 值同样保持单调递增。从一个更大的维度去看,可以发现在 term=2 和 term=3 的两个 Leader 任期之间,数据对应的 revision 值依旧保持了全局单调递增。

mvcc & streaming watch

了解 etcd 的版本号控制后,接下来如何使用 etcd 多版本号来实现并发控制以及数据订阅(Watch)。

在 etcd 中支持对同一个 Key 发起多次数据修改,每次数据修改都对应一个版本号。etcd 在实现上记录了每一次修改对应的数据,也就就意味着一个 key 在 etcd 中存在多个历史版本。在查询数据的时候如果不指定版本号,etcd 会返回 Key 对应的最新版本,当然 etcd 也支持指定一个版本号来查询历史数据。

因为 etcd 将每一次修改都记录了下来,使用 watch 订阅数据时,可以支持从任意历史时刻(指定 revision)开始创建一个 watcher,在客户端与 etcd 之间建立一个数据管道,etcd 会推送从指定 revision 开始的所有数据变更。etcd 提供的 watch 机制保证,该 Key 的数据后续的被修改之后,通过这个数据管道即时的推送给客户端。

如下图所示,etcd 中所有的数据都存储在一个 b+tree 中(灰色),该 b+tree 保存在磁盘中,并通过 mmap 的方式映射到内存用来支持快速的访问。灰色的 b+tree 中维护着 revision 到 value 的映射关系,支持通过 revision 查询对应的数据。因为 revision 是单调递增的,当我们通过 watch 来订阅指定 revision 之后的数据时,仅需要订阅该 b+ tree 的数据变化即可。

在 etcd 内部还维护着另外一个 btree(蓝色),它管理着 key 到 revision 的映射关系。当客户端使用 key 查询数据时,首先需要经过蓝色的 btree 将 key 转化为对应的 revision,再通过灰色的 btree 查询到对应的数据。

细心的读者会发现,etcd 将每一次修改都记录下来会导致数据持续增长,这会带来内存及磁盘的空间消耗,同时也会影响 b+tree 的查询效率。为了解决这一问题,在 etcd 中会运行一个周期性的 Compaction 的机制来清理历史数据,将一段时间之前的同一个 Key 的多个历史版本数据清理掉。最终的结果是灰色的 b+tree 依旧保持单调递增,但可能会出现一些空洞。

mini-transactions

在理解了 mvcc 机制及 watch 机制之后,继续看 etcd 提供的 mini-transactions 机制。etcd 的 transaction 机制比较简单,基本可以理解为一段 if-else 程序,在 if 中可以提供多个操作,如下图所示:

If 里面写了两个条件,当 Value(key1) 大于 "bar" 并且 Version(key1) 的版本等于 2 的时候,执行 Then 里面指定的操作:修改 Key2 的数据为 valueX,同时删除 Key3 的数据。如果不满足条件,则执行另外一个操作:Key2 修改为 valueY。

在 etcd 内部会保证整个事务操作的原子性。也就是说 If 操作所有的比较条件,其看到的视图一定是一致的。同时它能够确保多个操作的原子性不会出现 Then 中的操作仅执行了一半的情况。

通过 etcd 提供的事务操作,我们可以在多个竞争中去保证数据读写的一致性,比如说前面已经提到过的 Kubernetes 项目,它正是利用了 etcd 的事务机制,来实现多个 KubernetesAPI server 对同样一个数据修改的一致性。

lease 的概念及用法

lease 是分布式系统中一个常见的概念,用于代表一个分布式租约。典型情况下,在分布式系统中需要去检测一个节点是否存活的时,就需要租约机制。

上图示例中的代码示例首先创建了一个 10s 的租约,如果创建租约后不做任何的操作,那么 10s 之后,这个租约就会自动过期。接着将 key1 和 key2 两个 key value 绑定到这个租约之上,这样当租约过期时 etcd 就会自动清理掉 key1 和 key2,使得节点 key1 和 key2 具备了超时自动删除的能力。

如果希望这个租约永不过期,需要周期性的调用 KeeyAlive 方法刷新租约。比如说需要检测分布式系统中一个进程是否存活,可以在进程中去创建一个租约,并在该进程中周期性的调用 KeepAlive 的方法。如果一切正常,该节点的租约会一致保持,如果这个进程挂掉了,最终这个租约就会自动过期。

在 etcd 中,允许将多个 key 关联在同一个 lease 之上,这个设计是非常巧妙的,可以大幅减少 lease 对象刷新带来的开销。试想一下,如果有大量的 key 都需要支持类似的租约机制,每一个 key 都需要独立的去刷新租约,这会给  etcd 带来非常大的压力。通过多个 key 绑定在同一个 lease 的模式,我们可以将超时间相似的 key 聚合在一起,从而大幅减小租约刷新的开销,在不失灵活性同时能够大幅提高 etcd 支持的使用规模。

三、典型的使用场景介绍

元数据存储

Kubernetes 将自身所用的状态存储在 etcd 中,其状态数据的高可用交给 etcd 来解决,Kubernetes 系统自身不需要再应对复杂的分布式系统状态处理,自身的系统架构得到了大幅的简化。

Server Discovery (Naming Service)

第二个场景是 Service Discovery,也叫做名字服务。在分布式系统中,通常会出现的一个模式就是需要多个后端(可能是成百上千个进程)来提供一组对等的服务,比如说检索服务、推荐服务。

对于这样一种后端服务,通常情况下为了简化后端服务的运维成本(节点故障时随时被替换),后端的这一进程会被类似 Kubernetes 这样的集群管理系统所调度,这样当用户(或上游服务)调用过来时,我们就需要一个服务发现机制来解决服务路由问题。这一服务发现问题可以利用 etcd 来高效解决,方式如下:

  • 在进程内部启动之后,可以将自身所在的地址注册到 etcd;
  • API 网关够通过 etcd 及时感知到后端进程的地址,当后端进程发生故障迁移时会重新注册到 etcd 中,API 网关也能够及时地感知到新的地址;
  • 利用 etcd 提供的 Lease 机制,如果提供服务的进程运行过程中出现了异常(crash),API 网关也可以摘除其流量避免调用超时。

在这一架构中,服务状态数据被 etcd 接管,API 网关本身也是无状态的,可以水平地扩展来服务更多的客户。同时得益于 etcd 的良好性能,可以支持上万个后端进程的节点,使得这一架构可以服务于大型的企业。

Distributed Coordination: leader election

在分布式系统中,有一种典型的设计模式就是 Master+Slave。通常情况下,Slave 提供了 CPU、内存、磁盘以及网络等各种资源 ,而 Master 用来调和这些节点以使其对外提供一个服务(比如分布式存储,分布式计算)。典型的分布式存储服务(HDFS)以及分布式计算服务(Hadoop)它们都是采用了类似这样的设计模式。这样的设计模式会有一个典型的问题:Master 节点的可用性。当 Master 故障以后,整个集群的服务就挂掉了,没有办法再服务用户的请求。

为了解决这个问题,典型的做法就是启动多个 Master 节点。因为 Master 节点内会包含控制逻辑,多个节点之间的状态同步是非常复杂的,这里最典型的做法就是通过选主的方式,选出其中一个节点作为主节点来提供服务,另一个节点处于等待状态。

通过 etcd 提供的机制可以很容易的实现分布式进程的选主功能,比如可以通过对同一个 key 的事务写来实现抢主的逻辑。一般而言,被选主的 Leader 会将自己的 IP 注册到 etcd 中,使得 Slave 节点能够及时获取到当前的 Leader 地址,从而使得系统按照之前单个 Master 节点的方式继续工作。当 Leader 节点发生异常之后,通过 etcd 能够选取出一个新的节点成为主节点,并且注册新的 IP 之后,Slave 又能够拉取新的主节点的 IP,继续恢复服务。

Distributed Coordination 分布式系统并发控制

在分布式系统中,当我们去执行一些任务,比如说去升级 OS、或者说升级 OS 上的软件的时候、又或者去执行一些计算任务的时候,出于对后端服务的瓶颈或者是业务稳定性的考虑,通常情况下需要控制任务的并发度。如果该任务缺少一个调和的 Master 节点,可以通过 etcd 来完成这样的分布式系统工作。

在这个模式中通过 etcd 去实现一个分布式的信号量,并且可以利用 etcd leases 机制来实现自动地剔除掉故障节点。在进程执行过程中,如果进程的运行周期比较长,我们可以将进程运行过程中的一些状态数据存储到 etcd,从而使得当进程故障之后且需要恢复到其他地方时,能够从 etcd 中去恢复一些执行状态,而不需要重新去完成整个的计算逻辑,以此来加速整个任务的执行效率。

本文总结

本文分享的主要内容就到此为止了,这里为大家简单总结一下:

  • 第一部分,为大家介绍了 etcd 项目是如何诞生的,以及在 etcd 发展过程中经历的几个重要时刻;
  • 第二部分,为大家介绍了 etcd 的架构以及其内部的基本操作接口,在理解 etcd 是如何实现高可用的基础之上,展示了 etcd 数据的一些基本操作以及其内部的实现原理;
  • 第三部分,介绍了三种典型的 etcd 使用场景,以及在对应的场景下,分布式系统的设计思路。

双12来袭!500元淘宝红包、iPhone11等你拿。
https://www.aliyun.com/1212/2019/home?utm_content=g_1000092611

原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/517215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

minio 单机安装、部署 centos7环境

文章目录一、默认模式下载运行1. 下载2. 访问minio控制台3. 创建目录3. 上传文件二、企业自定义模式2.1. 指定用户密码2.2. 配置目录2.3. 控制台端口2.4. 启动2.5. minio控制台登录2.6. 效果图一、默认模式下载运行 1. 下载 官网地址:https://docs.min.io/docs/ …

Kubernetes 日志查询分析实践

准备工作 为了完成后续的相关操作,我们需要准备一个 K8s 集群,操作步骤如下: 登陆容器服务控制台。创建一个标准托管集群(杭州区域),在向导中勾选上【使用 EIP 暴露 API Server】 和【使用日志服务】。集…

“编程能力差,90%是输在这点上!”谷歌AI开发专家:逆袭并没那么难!

Google 人工智能开发者专家彭靖田老师说——超90%的程序员在初学Python 人工智能时,都会遇到下面3个问题:1.想入门人工智能,但不知从何学起,也不知道该选择什么方向...2.Python语法、机器学习/深度学习框架、算法都能看懂&#xf…

这群程序员疯了!他们想成为IT界最会带货的男人

随着网红主播越来越火,通过直播带货种草的形式也成了今年双12的热点。 不过,网红主播带货早已见怪不怪,但你们见过程序员直播带货吗!? 近日,趁着阿里云双12年末采购节,阿里云邀请了一波程序员GG来为大家直播带货&am…

Minio Docker 单机安装(二种模式) linux

文章目录一、默认单机启动1. docker安装启动2. minio 镜像拉取和启动3. minio登录二、minio纠删码模式2.1. 简述2.2. 启动2.3. minio登录2.4. 总览2.5. 上传文件测试一、默认单机启动 1. docker安装启动 # 在线安装docker yum install docker# 启动docker systemctl start do…

阿里巴巴 Service Mesh 落地的架构与挑战

导读:云原生已成为整个阿里巴巴经济体构建面向未来的技术基础设施,Service Mesh 作为云原生的关键技术之一,顺利完成在 双11 核心应用严苛而复杂场景下的落地验证。本文作者将与大家分享在完成这一目标过程中我们所面临和克服的挑战。 部署架…

看完这篇 HashMap ,和面试官扯皮就没问题了

来源 | Java 建设者责编 | Carol封图 | CSDN 下载自视觉中国(如果你没有时间细抠本文,可以直接看 HashMap 概述,能让你对 HashMap 有个大致的了解)HashMap 是 Map 接口的实现,HashMap 允许空的 key-value 键值对&#…

除了快,5G 有哪些关键技术?

阿里妹导读:5G不仅仅只是网速更快,更多的是生活方式的颠覆,对各行各业都会起到催化作用。5G里不仅仅只有大带宽,而是会有很多与B端用户(企业)相结合的点。接下来,跟阿里大文娱的梓烁一起了解5G的…

聚水潭是如何基于AnalyticDB for PostgreSQL 构筑海量实时数仓平台的

聚水潭数据仓库业务介绍 上海聚水潭网络科技有限公司成立于2014年。聚水潭创建之初,以电商SaaS ERP切入市场,凭借出色的产品和服务,快速获得市场领先地位。随着客户需求的不断变化,如今聚水潭已经发展成为以SaaS ERP为核心&#…

sqlite3的编译和使用

编译环境准备 这个是nw官网的环境搭建教程,一般需要python2.7、visual studio 2013、node-gyp、 node-pre-gyp,环境这块的文章很多自己可以百度http://docs.nwjs.io/en/latest/For Users/Advanced/Use Native%2 0Node%20Modules/ 编译好之后&#xff0…

阿里巴巴的 Kubernetes 应用管理实践经验与教训

导读:本文整理自孙健波在 ArchSummit 大会 2019 北京站演讲稿记录。首先介绍了阿里巴巴基于 Kubernetes 项目进行大规模应用实践过程中遇到的问题;随后会逐一介绍解决这些问题的现有实践及其本身存在的局限性;最后会介绍阿里巴巴目前正在进行…

Minio 分布式集群部署

文章目录一、分布式存储可靠性常用方法1. 概述2. 冗余3. 校验二、分布式Minio优势2.1. 数据保护2.2. 高可用2.3.一致性三、运行分布式Minio3.1. 启动方案简述3.2. 案例说明3.3. 制作分布式启动脚本3.4. 制作伪分布式启动脚本3.5. 登录minio四、分布式Minio负载均衡4.1. nginx安…

数据分析:为什么说Python比Excel更简单高效 ?

日本最大的证券公司之一野村证券首席数字官马修汉普森,在Quant Conference上发表讲话:“用Excel的人越来越少,大家都在用Python。”甚至直接说:“Python已经取代了Excel。”事实上,为了追求更高的效率和质量&#xff0…

快速搭建 Serverless 在线图片处理应用

简介 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计…

如何在 PyFlink 1.10 中自定义 Python UDF?

我们知道 PyFlink 是在 Apache Flink 1.9 版新增的,那么在 Apache Flink 1.10 中 Python UDF 功能支持的速度是否能够满足用户的急切需求呢? Python UDF 的发展趋势 直观的判断,PyFlink Python UDF 的功能也可以如上图一样能够迅速从幼苗变成…

Node.js从零开发Web Server博客项目笔记

代码运行流程 首先开启服务器,在npm run dev的时候运行了bin目录下的www.js文件,启动http服务 当前端进行访问的时候,经过app.js文件 App.js是整个项目的入口文件,首先判断这个用户在http的header头中带了那些验证的信息&#…

如何度过二十多岁这段又穷又迷茫的岁月?

我们在后台常常会收到读者的留言我马上毕业了,但是现在很迷茫,不知道学校里学的,能不能真正的适应工作...我工作两三年,还是不知道怎么规划自己的技术成长路线,不知道该学什么来提升自己的竞争力...人生需要长线的经营…

Docker-compose 安装Minio 最新版本

文章目录一、环境准备1.安装docker-compose2. 新版本尝鲜3. 镜像下载二、单机编排2.1. 创建docker-compose.yaml2.2. 运行三、集群编排3.1. 下载docker-compose.yaml3.2. nginx.conf3.3.运行一、环境准备 1.安装docker-compose https://gblfy.blog.csdn.net/article/details/…

神龙架构没那么难理解—图解世界领先的阿里云神龙架构(一)缘起

1 概述 1.1 神龙架构的特点 阿里云官方文档对于神龙架构的描述如下: 保留了普通云服务器的资源弹性,并因嵌套虚拟化技术让弹性裸金属服务器保留了物理机的体验。 1.2 理解上的难点 同时拥有云服务器的资源弹性和保留了物理机体验的特点容易让用户在…

react native笔记-个人记录-初始化工程遇到的问题

使用Expo工具 在mac上安装expo,如果是权限问题可以参考以下解决方法 https://blog.csdn.net/testcs_dn/article/details/78869419 https://jingyan.baidu.com/article/9c69d48ff88b3813c9024e9d.html 这是第二条链接的说明:对于Mac OS X 10.11 El Capi…