1. etcd 简介

etcd 官网定义:

A highly-available key value store for shared configuration and service discovery.

即一个用于配置共享和服务发现的键值存储系统。

etcd 是一款分布式存储中间件,使用 Go 语言编写,并通过 Raft 一致性算法处理和确保分布式一致性,解决了分布式系统中数据一致性的问题。

而且作为一款分布式、可靠的键值存储组件,etcd 常用于微服务架构中的服务注册与发现中心,相较于 ZooKeeper 部署更简单,而且具有数据持久化、支持 SSL 客户端安全认证的独特优势。

etcd 作为一个可信赖的分布式键值存储服务,它能够为整个分布式集群存储一些关键数据,协助分布式集群的正常运转。

etcd 可集中管理配置信息。服务端将配置信息存储于 etcd,客户端通过 etcd 得到服务配置信息,etcd 监听配置信息的改变,发现改变通知客户端。

etcd 满足 CAP 理论中的 CP(一致性和分区容错性) 指标,由此我们知道,etcd 解决了分布式系统中一致性存储的问题。

2. etcd 特点

etcd 可以用来构建高可用的分布式键值数据库,总结来说有如下特点。

  • 简单:安装简单,且为用户提供了 HTTP API,使用起来也很简单;
  • 存储:数据分层存储在文件目录中,类似于我们日常使用的文件系统;
  • Watch 机制:Watch 指定的键、前缀目录的更改,并对更改时间进行通知;
  • 安全通信:支持 SSL 证书验证;
  • 高性能:etcd 单实例可以支持 2K/s 读操作,官方也有提供基准测试脚本;
  • 一致可靠:基于 Raft 共识算法,实现分布式系统内部数据存储、服务调用的一致性和高可用性;
  • Revision 机制:每个 Key 带有一个 Revision 号,每进行一次事务便加一,因此它是全局唯一的,如初始值为 0,进行一次 Put 操作,KeyRevision 变为 1,同样的操作,再进行一次,Revision 变为 2;换成 Key1 进行 Put 操作,Revision 将变为 3。这种机制有一个作用,即通过 Revision 的大小就可知道写操作的顺序,这对于实现公平锁,队列十分有益;
  • Lease 机制:即租约机制(TTLTime To Live),Etcd 可以为存储的 Key-Value 对设置租约,当租约到期,Key-Value 将失效删除;同时也支持续约,通过客户端可以在租约到期之前续约,以避免 Key-Value 对过期失效;此外,还支持解约,一旦解约,与该租约绑定的 Key-Value 将失效删除;

etcd 是一个实现了分布式一致性键值对存储的中间件,支持跨平台,etcd 集群中的节点基于 Raft 算法进行通信,Raft 算法保证了微服务实例或机器集群所访问的数据的可靠一致性。

在分布式系统或者 Kubernetes 集群中,etcd 可以作为服务注册与发现和键值对存储组件。

3. 应用场景

etcd 在稳定性、可靠性和可伸缩性上表现极佳,同时也为云原生应用系统提供了协调机制。etcd 经常用于服务注册与发现的场景,此外还有键值对存储、消息发布与订阅、分布式锁等场景。

3.1 键值对存储

etcd 是一个用于键值存储的组件,存储是 etcd 最基本的功能,其他应用场景都建立在 etcd 的可靠存储上。比如 Kubernetes 将一些元数据存储在 etcd 中,将存储状态数据的复杂工作交给 etcdKubernetes 自身的功能和架构就能更加稳定。

3.2 服务注册与发现

etcd 基于 Raft 算法,能够有力地保证分布式场景中的一致性。各个服务启动时注册到 etcd 上,同时为这些服务配置键的 TTL 时间。注册到 etcd 上面的各个服务实例通过心跳的方式定期续租,实现服务实例的状态监控。

3.3 消息发布与订阅

在分布式系统中,服务之间还可以通过消息通信,即消息的发布与订阅,如下图所示:

通过构建 etcd 消息中间件,服务提供者发布对应主题的消息,消费者则订阅他们关心的主题,一旦对应的主题有消息发布,就会产生订阅事件,消息中间件就会通知该主题所有的订阅者。

3.4 分布式锁

分布式系统中涉及多个服务实例,存在跨进程之间资源调用,对于资源的协调分配,单体架构中的锁已经无法满足需要,需要引入分布式锁的概念。etcd 基于 Raft 算法,实现分布式集群的一致性,存储到 etcd 集群中的值必然是全局一致的,因此基于 etcd 很容易实现分布式锁。

4. etcd 的核心架构

从上图可知,etcdetcd ServergRPC Server、存储相关的 MVCCSnapshotWAL,以及 Raft 模块。

其中:

  • etcd Server 用于对外接收和处理客户端的请求;
  • gRPC Server 则是 etcd 与其他 etcd 节点之间的通信和信息同步;
  • MVCC 即多版本控制,etcd 的存储模块,键值对的每一次操作行为都会被记录存储,这些数据底层存储在 BoltDB 数据库中;
  • WAL 预写式日志,etcd 中的数据提交前都会记录到日志;
  • Snapshot 快照,以防 WAL 日志过多,用于存储某一时刻 etcd 的所有数据;
  • SnapshotWAL 相结合,etcd 可以有效地进行数据存储和节点故障恢复等操作;

虽然 etcd 内部实现机制复杂,但对外提供了简单的 API 接口,方便客户端调用。我们可以通过 etcdctl 客户端命令行操作和访问 etcd 中的数据,或者通过HTTP API 接口直接访问 etcd

etcd 中的数据结构很简单,它的数据存储其实就是键值对的有序映射。etcd 还提供了一种键值对监测机制,即 Watch 机制,客户端通过订阅相关的键值对,获取其更改的事件信息。Watch 机制实时获取 etcd 中的增量数据更新,使数据与 etcd 同步。

etcd 目前有 V2.xV3.x 两个大版本。etcd V2V3 是在底层使用同一套 Raft 算法的两个独立应用,但相互之间实现原理和使用方法上差别很大,接口不一样、存储不一样,两个版本的数据互相隔离。

至于由 etcd V2 升级到 etcd V3 的情况,原有数据只能通过 etcd V2 接口访问,V3 接口创建的数据只能通过新的 V3 的接口访问。

etcd 架构图:
通常,etcd 会监听两个端口,默认是 2379 端口和 2380 端口。其中,2380 端口用于集群内部通信,主要涉及集群间数据同步、心跳、选举等。2379 端口用于与客户端通信,比如接收客户端发起的读/写数据请求。

etcd 节点在部署的时候有两种运行模式:集群模式和代理模式。

etcd 节点以集群模式运行时,它会加入已有集群中,作为集群的一部分。也就是说,后续的心跳、数据同步、选举等它都会参与。

集群模式中的节点数一般采用奇数个。为什么呢?因为假如同时有两个 Candidate 发起选举,如果是偶数节点的话,可能存在两个 Candidate 获得相同票数。

这会导致什么问题?如果两个 Candidate 票数一样,就需要再次发起选举,而再次发起选举还是有一定概率出现票数一样,这会导致选举耗时较多,影响稳定性。所以,采用奇数个节点,能有效降低票数一样的概率,提升选举的效率。另外,使用奇数节点来部署,也能让 etcd 很好地处理分区容错问题。

当某个 etcd 节点以代理模式运行时,该节点负责将接收到的请求转发给 etcd 集群节点。目前 etcd 接口有 v2v3 两个版本,其中 v2HTTP 接口,v3gRPC 接口。需要注意的是,代理模式只支持转发 v2 版本的请求,也就是只支持转发 HTTP 请求。

不过,由于 etcd v3 接口在性能、安全、稳定性等方面要比 v2 接口优秀很多,新项目倾向于使用 v3 接口,老项目也逐渐从 v2 接口迁移到 v3 接口。也就是说,代理模式以后可能逐渐被淘汰掉。

5. 分布式中的 CAP 理论

CAP 原理是描述分布式系统下节点数据同步的基本定理,分别指

  • Consistency(一致性)

指数据一致性,表示一个系统的数据信息(包括备份数据)在同一时刻都是一致的。在分布式系统下,同一份数据可能存在于多个不同的实例中,在数据强一致性的要求下,修改其中一份数据后必须同步到它的所有备份中。在数据同步的任何时候,都需要保证所有对该份数据的请求将返回同样的状态。

  • Availability(可用性)

指服务可用性,要求服务在接收到客户端请求后,都能够给出响应。服务可用性考量的是系统的可用性,要求系统在高并发情况和部分节点宕机的情况下,系统整体依然能够响应客户端的请求。

  • Partition tolerance(分区容错性)

指分区容忍性。在分布式系统中,不同节点之间通过网络进行通信。由于网络的不可靠性,位于不同网络分区的服务节点可能会通信失败,如果系统能够容忍这种情况,说明它是满足分区容忍性的。如果系统不能满足,将会限制分布式系统的扩展性,即服务节点的部署数量和地区都会受限,也就违背了分布式系统设计的初衷,所以一般来说分布式系统都会满足分区容忍性。

这三个要素最多只能同时实现两点,不能三者兼顾。

基于分布式系统的基本特质,P(分区容错性)是必须要满足的,所以接下来需要考虑满足 C(一致性)还是 A(可用性)。

但是在满足了分区容忍性的前提下,分布式系统并不能同时满足数据一致性和服务可用性。

假设服务 A 现在有两个实例 A1A2,它们之间的网络通信出现了异常,基于分区容忍性,这并不会影响 A1A2 独立的正常运行。假如此时客户端请求 A1,请求将数据 BB1 状态修改为 B2,由于网络的不可用,数据 B 的修改并不能通知到实例 A2

如果此时另一个客户端向 A2 请求数据 B,如果 A2 返回数据 B1,将满足服务可用性,但并不能满足数据一致性;如果A2 等待 A1 的通知后才返回数据 B 的正确状态,虽然满足了数据一致性,但并不能响应客户端请求,违背了服务可用性的指标。

在类似银行之类对金额数据要求强一致性的系统中,要优先考虑满足数据一致性;而在大众网页之类的系统中,用户对网页版本的新旧不会有特别的要求,在这种场景下服务可用性会高于数据一致性。

6. 常用术语

7. 分布式原理

7.1 客户端

当 RPC 服务部署在多个节点上时,客户端得到的是一个服务列表,有多个 IP 端口对。客户端的连接池可以随机地挑选任意的 RPC 服务节点进行连接。

每个服务节点应该有个权重值,当所有节点的权重值一样时,它们的流量分配就是均匀的。如果某个节点的相对权重值较小,它被客户端选中的概率也会相对比较小。

class RPCNode {String addr;  // 服务地址int weight; // 节点权重
}class RPCCluster {RPCNode[] nodes; // 节点列表Node random(); // 按权重随机挑选节点
}

7.2 容灾

当有一个服务节点挂掉时,客户端需要采取一定的策略避免请求失败。当请求失败时,客户端还要进行重试,但是也不可以无限重试,要有一定的重试策略。

比如当节点挂掉时,将失效节点摘除,放置到失效节点列表中。然后每隔一段时间检查失效节点是否恢复了,如果恢复了,那就从失效节点中移除,再将节点地址重新加入到有效节点列表中。那如何判断节点真的挂掉了呢,一般需要设置一个时间窗口,统计在一定时间窗口里出现的错误数量。如果这个数量过大,那就意味着失效了。这也是为了防止网络偶然抖动导致服务节点流量的大幅波动。

7.3 降权法

上面提到客户端会为每个节点赋予一个权值,改变权值就可以改变节点的相对流量。如果某个节点出现了一次调用错误,可以对该节点进行降权。如果错误次数过多,降权会降的很快,最终达到一个最小值。之所以不应该降到零,那是为了给节点提供一个恢复的机会。被降权的节点后来只要有一次调用成功,那么 weight 值就应该尽快被还原,这样节点就可以快速恢复为正常节点。

客户端一次调用失败会尝试重试。如果降权太慢,会导致重试次数太多,因为第二次随机挑选节点时还是很有可能再次挑选到失效节点。降权太快也不好,网络抖动会导致节点流量分配的快速抖动,瞬间从正常降到近零,又可以瞬间从近零恢复到正常。

一个简单的策略是权重减半法。错误一次权重减半,连续错误两次权重就降到 1/4,如此直到降到最小值。如果初始权重值是 1024,那么权重值就会逐渐衰减1024=>512=>256=>128=>64=>32=>16=>8=>4=>2=>1。如果节点恢复了,那么调用会成功,权重就可以直接恢复到正常值,也可以通过加倍法逐渐恢复到正常值1=>2=>4=>8=>16=>32=>64=>128=>256=>512=>1024。如果希望恢复的更快一点,可以通过乘 4 法,乘 8 法。

7.4 服务发现

健壮的服务应该是可以支持动态扩容的服务。比如 RPC 服务压力过大,希望通过增加节点的方式来减小单个 RPC 服务的压力。如果使用的是前面的静态 RPC 服务地址列表,那么当节点增加时,我们需要修改客户端的配置重启才能生效。

通过服务发现技术,当 RPC 服务节点增加或减少时,客户端可以动态快速收到服务列表的变更信息,从而可以实时调整连接配置,这样无需重启就可以完成服务的扩容和缩容。

class ServiceDiscovery(object):def register_service(self, name, addr):passdef get_services(self, name):passdef on_services_changed(self, name):pass

服务发现技术依赖于服务之间的特殊中间节点。这个节点的作用就是接受服务的注册,提供服务的查找,以及服务列表变更的实时通知功能。它一般使用支持高可用的分布式配置数据库作为解决方案,如 zookeeper/etcd 等。

  • 服务注册——服务节点在启动时将自己的服务地址注册到中间节点
  • 服务查找——客户端启动时去中间节点查询服务地址列表
  • 服务变更通知——客户端在中间节点上订阅依赖服务列表的变更事件。当依赖的服务列表变更时,中间节点负责将变更信息实时通知给客户端。

etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理相关推荐

  1. Mongodb 笔记01 MongoDB 简介、MongoDB基础知识、启动和停止MongoDB

    MongoDB 简介 1. 易于使用:没有固定的模式,根据需要添加和删除字段更加容易 2. 易于扩展:MongoDB的设计采用横向扩展.面向文档的数据模型使它能很容易的再多台服务器之间进行分割.自动处 ...

  2. JSP学习笔记01 - JSP简介及运行环境配置

    一.什么是JSP 1.jsp简介 JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它是由Sun Microsystems公司倡导.许多 ...

  3. JavaScript学习笔记01【基础——简介、基础语法、运算符、特殊语法、流程控制语句】

    w3school 在线教程:https://www.w3school.com.cn JavaScript学习笔记01[基础--简介.基础语法.运算符.特殊语法.流程控制语句][day01] JavaS ...

  4. ETCD快速入门-01 ETCD概述

    1.ETCD概述 1.1 ETCD概述     etcd是一个高可用的分布式的键值对存储系统,常用做配置共享和服务发现.由CoreOS公司发起的一个开源项目,受到ZooKeeper与doozer启发而 ...

  5. etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程

    1. etcd 项目结构和功能 etcd 项目代码的目录结构如下: $ tree ├── auth ├── build ├── client ├── clientv3 ├── contrib ├── ...

  6. 尚硅谷大数据技术Spark教程-笔记01【Spark(概述、快速上手、运行环境、运行架构)】

    视频地址:尚硅谷大数据Spark教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据技术Spark教程-笔记01[Spark(概述.快速上手.运行环境.运行架构)] 尚硅谷大数据技术Spark教 ...

  7. 【2017cs231n】课程笔记01:计算机视觉概述及历史背景

    [2017cs231n]课程笔记01:计算机视觉概述及历史背景 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.c ...

  8. MyBatis-学习笔记01【01.Mybatis课程介绍及环境搭建】

    Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...

  9. Redis-学习笔记01【Redis环境搭建】

    Java后端 学习路线 笔记汇总表[黑马程序员] Redis-学习笔记01[Redis环境搭建] Redis-学习笔记02[Redis命令操作] Redis-学习笔记03[Redis持久化] Redi ...

最新文章

  1. python流程控制-python之流程控制
  2. css3中transition属性详解
  3. Netty入门官方例子
  4. 【javascript】四舍五入
  5. 一键生成通讯录的软件_橙瓜码字自动写作软件,外貌描写对话描写一键生成
  6. ajax长轮询的问题,Ajax长轮询
  7. golang mysql 超时_Go语言channel超时机制
  8. 计算机制图的简称市什么,计算机地的图制图复习题.doc
  9. 如何修复Win11上的时钟不同步?Win11时钟不同步修复方法
  10. Pycharm快捷键设置(鼠标滚动控制字体大小)
  11. NIM(Network Installation Manager)使用一例(mksysb)
  12. Linux scp连接很慢,ssh连接很慢问题分析
  13. html5在线加密,HTML源代码在线加密解密
  14. c++打印素数表(线性筛)
  15. 对射式光电传感器测速使用CD10406消抖动解决办法
  16. 快醒醒吧!你连基础的JVM运行时内存布局都忘了?Java面试题及解析
  17. 作为一款图片处理应用,Snapseed 的品质如何?
  18. 字符串转换为驼峰格式
  19. 郑州东区鸿蒙学前班,新元鸿蒙教育智能学前班户外大课堂开始啦!
  20. 超级计算机学校,超级计算机排名_计算机院校排名_计算机学校排名

热门文章

  1. java工程webservice的应用案例
  2. 【Sql Server】DateBase-简单的Select查询
  3. 2018年终总结:自由而独立
  4. 【软件工程】RUP与软件开发5大模型
  5. 利用pandas读写HDF5文件
  6. pytorch JIT浅解析
  7. NVIDIA DRIVE AGX开发工具包
  8. 色彩(颜色)空间原理(下)
  9. CVPR2020:点云三维目标跟踪的点对盒网络(P2B)
  10. YOLOv4实用训练实践