etcd 实现与选型分析(二)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: etcd 实现与选型分析(二)

变更通知

概念

etcd 通过对 watcher 进行分类,来实现事件的可靠性:

  • synced watcher,此类 watcher 监听的数据都已经同步完毕,在等待新的变更。
  • unsynced watcher,此类 watcher 监听的数据还未同步完成,落后于当前最新数据变更,正在努力追赶。
  • victim watcher,此类 slower watcher 的推送 channel buffer 堆满,etcd 会将其移动到专门的队列中异步机制重试。

订阅流程

  • 当 Client 发起一个 watch key 请求的时候,etcd 的 WatchServer 收到 watch 请求后,会创建一个 serverWatchStream, 它负责接收 client 的 gRPC Stream 的 create/cancel watcher 请求 (recvLoop goroutine),并将从 MVCC 模块接收的 Watch 事件转发给 client(sendLoop goroutine)。
  • 当 serverWatchStream 收到 create watcher 请求后,serverWatchStream 会调用 MVCC 模块的 WatchStream 子模块分配一个 watcher id,并将 watcher 注册到 MVCC 的 WatchableKV 模块。
  • etcd 启动后,WatchableKV 模块会运行 syncWatchersLoop 和 syncVictimsLoop goroutine,分别负责不同场景下的事件推送。

etcd 使用 map 记录了监听单个 key 的 watcher,但是你要注意的是 Watch 特性不仅仅可以监听单 key,它还可以指定监听 key 范围、key 前缀,因此 etcd 还使用了区间树。当收到创建 watcher 请求的时候,它会把 watcher 监听的 key 范围插入到上面的区间树中,区间的值保存了监听同样 key 范围的 watcher 集合 /watcherSet。

当产生一个事件时,etcd 首先需要从 map 查找是否有 watcher 监听了单 key,其次它还需要从区间树找出与此 key 相交的所有区间,然后从区间的值获取监听的 watcher 集合。区间树支持快速查找一个 key 是否在某个区间内,时间复杂度 O(LogN),因此 etcd 基于 map 和区间树实现了 watcher 与事件快速匹配,具备良好的扩展性。

推送流程

  • 当你创建完成 watcher 后,此时你执行 put hello 修改操作时,如上图所示,请求经过后的 mvccpb.KeyValue 保存到一个 changes 数组中。
  • 在 put 事务结束时,它会将 KeyValue 转换成 Event 事件,然后回调 watchableStore.notify 函数。notify 会匹配出监听过此 key 并处于 synced watcherGroup 中的 watcher,同时事件中的版本号要大于等于 watcher 监听的最小版本号,才能将事件发送到此 watcher 的事件 channel 中。

注意

若 watcher 监听的版本号已经小于当前 etcd server 压缩的版本号,历史变更数据就可能

已丢失,因此 etcd server 会返回 ErrCompacted 错误给 client。client 收到此错误后,需重新获取数据最新版本号后,再次 Watch。在业务开发过程中,使用 Watch API 最常见的一个错误之一就是未处理此错误。

其次,Watch 返回的  WatchChan  有可能在运行过程中失败而关闭,此时  WatchResponse.Canceled  会被置为  trueWatchResponse.Err()  也会返回具体的错误信息。所以在 range WatchChan 的时候,每一次循环都要检查  WatchResponse.Canceled,在关闭的时候重新发起 Watch 或报错。

选型分析

方案选型可以从业务系统的需求和 etcd 的特性、性能,两个方面着手。

业务系统

先看使用 etcd 提供服务的目标系统。如果你正在深入 Kubernetes 或开始使用服务网格,您可能会遇到术语“控制平面(control plane)”和“数据平面(data plane)”。术语 “控制平面” 和 “数据平面” 都是关于关注点的分离,即系统内职责的明确分离。控制平面是一切与策略建立和下发有关的部分,而数据平面是一切与执行策略有关的部分。当控制平面出现故障,只会影响新的策略变更变更,但不会影响已有策略执行,即,数据平面的功能。

以 Kubernetes 为例,其核心服务包括:

组件 描述
kube-apiserver 提供了资源的唯一入口,并提供认证、授权、访问控制、API 注册和发现等
kube-scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上
kube-controller-manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
etcd 存储整个集群的状态
kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡

以上服务故障,并不会影响当前已有 Pod 正常对外提供服务。

Why etcd

再看 etcd 本身。要了解 etcd 适用的场景,质量最高的来源是其官网。

介绍:

“etcd” 名字来源于两个想法:unix “/etc” 文件夹和 分布式( “d”istributed)系统。“/etc” 文件夹是存储单个系统的配置数据的地方,而 etcd 存储大规模分布式系统的配置信息。因此,“d”istributed “/etc” 是 “etcd”。

etcd 被设计为大规模分布式系统的通用基座。这类系统永远不容忍裂脑操作,并愿意牺牲可用性来实现该目标。

分布式系统使用 etcd 用于配置管理、服务发现和协调分布式工作。etcd 的常见分布式模式包括领导者选举、分布式锁和监控机器活动。

使用场景:

  • CoreOS 的 Container Linux:在 Container Linux 上运行的应用程序可以获得自动、零停机的 Linux 内核更新。Container Linux 使用 Locksmith 来协调更新。Locksmith 在 etcd 上实现了分布式信号量,以确保在任何给定时间只有集群的一个子集在重新启动。
  • Kubernetes 将配置数据存储到 etcd 中,用于服务发现和集群管理;etcd 的一致性对于正确调度和操作服务至关重要。Kubernetes API 服务器将集群状态持久化为 etcd。它使用 etcd 的 watch API 来监视集群并生效关键的配置变更。( 2016 年 Kubernetes 1.6 发布,默认启用 etcd v3,助力 Kubernetes 支撑 5000 节点集群规模)

其他:

  • 最大可靠数据库大小: 数 GB
  • 因为缺少数据分片,复制无法水平扩展
  • 租约提供了一种用于减少中止请求数量的优化机制。

——— 来源:etcd versus other key-value stores | etcd

从基本介绍以及使用场景来看,etcd 的定位在于存储数据量小、更新频率低的数据,用于一致性要求高于可用性、无需水平扩展的场景。

性能

硬件推荐

超大型集群 为例,一个超大型型集群服务的客户端超过 1500 个,每秒请求超过 10000 个,存储数据超过 1 GB。

云厂商 机型 CPU 内存 (GB) 最大并发 IOPS 磁盘带宽 (MB/s)
AWS m4.4xlarge 16 64 16,000 250
GCE n1-standard-16 + 500GB PD SSD 16 60 15,000 250
性能指标

压测的硬件配置:

  • Google Cloud Compute Engine
  • 3 machines of 8 vCPUs + 16GB Memory + 50GB SSD
  • 1 machine(client) of 16 vCPUs + 30GB Memory + 50GB SSD
  • Ubuntu 17.04
  • etcd 3.2.0, go 1.8.3

写性能

Key 数量 Key 大小 (byte) Value 大小 (byte) 连接数 Client 数 目标 etcd server 平均写 QPS 平均请求延迟 平均服务 RSS
10,000 8 256 1 1 leader only 583 1.6ms 48 MB
100,000 8 256 100 1000 leader only 44,341 22ms 124MB
100,000 8 256 100 1000 all members 50,104 20ms 126MB

读性能

请求数 Key 大小 (byte) Value 大小 (byte) 连接数 Client 数 一致性 平均读 QPS 平均请求延迟
10,000 8 256 1 1 Linearizable 1,353 0.7ms
10,000 8 256 1 1 Serializable 2,909 0.3ms
100,000 8 256 100 1000 Linearizable 141,578 5.5ms
100,000 8 256 100 1000 Serializable 185,758 2.2ms
总结

一般 etcd 的集群为 3 或 5 个节点,Key 数量为 10w~ 规模下,预估集群性能如下:

  1. 写请求只有 Leader 才能处理,所以写性能不随节点数增加而增加,只取决于单机配置,处理量级大概为 1w~ QPS,平均延迟在 10ms~50ms。
  2. 串行读取所有节点均可处理,无需共识,处理量级大概为 10w~ QPS,平均延迟在 5ms 以内。
  3. 线性读取所有节点均可处理,但需要请求 Leader 获取 ReadIndex,性能会稍差,节点数对其提升有限,且容易受写请求影响,处理量级大概为 10w QPS,平均延迟在 10ms 以内。

适用场景

综合目标系统和 etcd 本身的细节来看:

  1. 首先,不建议将 etcd 用于目标系统的数据面。例如,配置中心产品,不适合使用 etcd 作为存储;
  2. 其次,谨慎将 etcd 用于对数据分片和水平扩展有要求的控制面系统。例如:跨可用区的服务发现,可以对服务类型进行区分,尽量减少多个可用区之间需要复制同步的服务数据量。
  3. 最后,etcd 租约、变更通知等功能的复杂度偏高。技术可控要求较高的系统,应谨慎使用相关功能。

本文作者 : cyningsun

本文地址https://www.cyningsun.com/01-27-2023/etcd-implement-and-tech-selection.html

版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!

# 数据库

  1. 深入理解 Redis cluster GOSSIP 协议
  2. 如何配置 go-redis 连接池
  3. 如何使用 Redis 存储对象
  4. Redis cluster 细节与技术选型
  5. MySQL 设计与查询规范
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
存储 Kubernetes 算法
云原生|kubernetes|etcd集群详细介绍+安装部署+调优(一)
云原生|kubernetes|etcd集群详细介绍+安装部署+调优(一)
1349 0
云原生|kubernetes|etcd集群详细介绍+安装部署+调优(一)
|
存储 Prometheus 监控
高可用prometheus集群方案选型分享
高可用prometheus集群方案选型分享
6122 2
高可用prometheus集群方案选型分享
|
Kubernetes Cloud Native 索引
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统(三)
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统
271 0
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统(三)
|
存储 域名解析 缓存
|
6月前
|
存储 Kubernetes Cloud Native
云原生|kubernetes|etcd集群详细介绍+安装部署+调优
云原生|kubernetes|etcd集群详细介绍+安装部署+调优
1447 0
|
6月前
|
Kubernetes Cloud Native 网络协议
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统
220 0
|
存储 JSON Kubernetes
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统(一)
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统
564 0
|
存储 Kubernetes 算法
etcd 实现与选型分析(一)
etcd 实现与选型分析
98 0
|
存储 Kubernetes Cloud Native
Kubernetes 本地持久化存储方案 OpenEBS LocalPV 落地实践上——使用篇
Kubernetes 本地持久化存储方案 OpenEBS LocalPV 落地实践上——使用篇
722 0
|
Kubernetes Cloud Native Docker
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统(二)
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统
223 0
云原生|kubernetes|搭建部署一个稳定高效的EFK日志系统(二)