跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

基准测试

etcd 的性能指标

基准测试

etcd 性能基准测试结果将定期发布,并在以下各版本中持续追踪:

内存使用基准

它记录了在不同场景下的预期内存使用情况。

1 - 存储内存使用量基准测试

etcd 存储的性能指标(内存索引与页面缓存)

etcd 存储的两个组件会占用物理内存。etcd 进程分配了一个 内存索引,用于加速键的查找。进程的 页缓存 由操作系统管理,用于存储从磁盘读取的最近访问数据,以便快速重用。

内存索引将所有键以 B 树 数据结构的形式存储,并附带指向磁盘数据(即值)的指针。B 树中的每个键可能包含多个指针,指向其值的不同版本。因此,内存索引的理论内存消耗可近似表示为以下公式:

N * (c1 + avg_key_size) + N * (avg_versions_of_key) * (c2 + size_of_pointer)

其中 c1 为键元数据开销,c2 为版本元数据开销。

图表展示了内存中索引 B 树的详细结构。



                                In mem index

                               +------------+
                               | key || ... |
  +--------------+             |     ||     |
  |              |             +------------+
  |              |             | v1  || ... |
  |   disk    <----------------|     ||     | Tree Node
  |              |             +------------+
  |              |             | v2  || ... |
  |           <----------------+     ||     |
  |              |             +------------+
  +--------------+       +-----+    |   |   |
                         |     |    |   |   |
                         |     +------------+
                         |
                         |
                         ^
                      ------+
                      | ... |
                      |     |
                      +-----+
                      | ... | Tree Node
                      |     |
                      +-----+
                      | ... |
                      |     |
                      ------+

页面缓存内存 由操作系统管理,本文档不对其进行详细说明。

测试环境

etcd 版本

GCE n1-standard-2 机器类型

  • 7.5 GB 内存
  • 2 个 CPU

内存中索引内存使用量

本测试仅针对内存索引的内存使用情况进行基准测试。目标是查找上述 c1 和 c2,并了解存储系统的内存消耗上限。

我们通过 Go 运行时的 ReadMemStats 计算内存使用量。通过对比创建索引前后的已分配字节数差异来估算内存使用情况。该方法无法完全反映内存中索引本身的内存使用量,但可展示大致的消耗趋势。

N 版本数 键大小 内存占用
100K 1 64 字节 22 MB
100K 5 64 字节 39 MB
1M 1 64 字节 218 MB
1M 5 64 字节 432 MB
100K 1 256 字节 41 MB
100K 5 256 字节 65 MB
1M 1 256 字节 409 MB
1M 5 256 字节 506 MB

根据结果,我们可以计算 c1=120bytes、c2=30bytes。仅需两组数据即可计算 c1 和 c2,因为它们是公式中唯一的未知变量。c1=120bytes 和 c2=30bytes 是我们计算出的 4 组 c1 和 c2 的平均值。对于小键值对,键元数据开销仍相对显著(50%)。然而,这相较于旧存储系统已实现显著改进,后者至少存在 1000% 的开销。

整体内存使用情况

整体内存使用量反映了 etcd 在存储系统上的 RSS 内存占用情况。值的大小对 etcd 的整体内存使用量影响极小,因为值数据存储在磁盘上,仅将热值保留在内存中,由操作系统的页面缓存进行管理。

N versions 键大小 值大小 内存占用
100K 1 64 字节 256 字节 40 MB
100K 5 64 字节 256 字节 89 MB
1M 1 64 字节 256 字节 470 MB
1M 5 64 字节 256 字节 880 MB
100K 1 64 字节 1 KB 102 MB
100K 5 64 字节 1 KB 164 MB
1M 1 64 字节 1 KB 587 MB
1M 5 64 字节 1 KB 836 MB

根据结果可知,值的大小对内存消耗的影响并不显著。由于操作系统页缓存中存储了更多数据,存在轻微的内存增长。

2 - 监听内存使用量基准测试

etcd 监听器的性能指标
说明

监听功能正处于积极开发中,其内存使用量可能随开发进展而变化。我们预计其内存使用量不会显著超过以下所述数值。

etcd 的一个核心目标是支持大量客户端执行海量监听操作。etcd 旨在支持 O(10k) 个客户端、O(100K) 个监听流(每个客户端约 O(10) 个监听流)以及 O(10M) 个总监听操作(每个监听流约 O(100) 个监听)。每个单独监听操作所消耗的内存占 etcd 整体内存使用量的最大部分,因此成为当前及未来优化的重点。

etcd 监听功能的三个相关组件会占用物理内存:每个 grpc.Conn、每个监听流以及每次监听活动的实例。grpc.Conn 维护实际的 TCP 连接及其他 gRPC 连接状态。每个 grpc.Conn 消耗约 10 KB 内存,且可能关联多个监听流。

每个监听流都是一个独立的 HTTP2 连接,消耗额外约 10 kB 的内存。 多个监听操作可能共享一个监听流。

监听是实际用于跟踪键值存储变更的结构。每个监听操作的内存消耗应低于 < 1 KB。

                                          +-------+
                                          | watch |
                              +---------> | foo   |
                              |           +-------+
                       +------+-----+
                       |   stream   |
      +--------------> |            |
      |                +------+-----+     +-------+
      |                       |           | watch |
      |                       +---------> | bar   |
+-----+------+                            +-------+
|            |         +------------+
|   conn     +-------> |   stream   |
|            |         |            |
+-----+------+         +------------+
      |
      |
      |
      |                +------------+
      +--------------> |   stream   |
                       |            |
                       +------------+

监听的理论内存消耗可通过以下公式近似计算:memory = c1 * number_of_conn + c2 * avg_number_of_stream_per_conn + c3 * avg_number_of_watch_stream

测试环境

etcd 版本

GCE n1-standard-2 机器类型

  • 7.5 GB 内存
  • 2 个 CPU

整体内存使用情况

总体内存使用量反映了 etcd 在客户端监听器存在的情况下所消耗的 RSS 。尽管结果可能有高达 10% 的波动,但该数据仍具有意义,因为目标是了解内存使用的粗略情况及分配模式。

根据基准测试结果,我们可以粗略计算出 c1 = 17kb、c2 = 18kb 和 c3 = 350bytes。因此,每个额外的客户端连接消耗 17 KB 内存,每个额外的流消耗 18 KB 内存,而每个额外的监听仅消耗 350 字节。在正常情况下,单个 etcd 服务器可使用几 GB 内存维持数百万个监听。

客户端数量 每客户端流数量 每流监听数量 总监听数量 内存占用
1k 1 1 1k 50MB
2k 1 1 2k 90MB
5k 1 1 5k 200MB
1k 10 1 10k 217MB
2k 10 1 20k 417MB
5k 10 1 50k 980MB
1k 50 1 50k 1001MB
2k 50 1 100k 1960MB
5k 50 1 250k 4700MB
1k 50 10 500k 1171MB
2k 50 10 1M 2371MB
5k 50 10 2.5M 5710MB
1k 50 100 5M 2380MB
2k 50 100 10M 4672MB
5k 50 100 25M OOM

3 - etcd v3 基准测试

etcd v3 性能指标

物理机

GCE n1-highcpu-2 机器类型

  • 1x 专用本地 SSD,挂载于 /var/lib/etcd
  • 1x 专用慢速磁盘,用于操作系统
  • 1.8 GB 内存
  • 2x CPU
  • etcd 版本 2.2.0

etcd 集群

1 以 v3 演示模式运行的 etcd 成员

测试

使用 etcd v3 基准测试工具 。

性能

读取单一键

键大小(字节) 客户端数量 读取 QPS 第 90 百分位延迟(毫秒)
256 1 2716 0.4
256 64 16623 6.1
256 256 16622 21.7

性能几乎与空服务器处理器的情况相同。

读取单个键的操作

键大小(字节) 客户端数量 读取 QPS 第 90 百分位延迟(毫秒)
256 1 2269 0.5
256 64 13582 8.6
256 256 13262 47.5

空服务器处理器的性能不受单次写入操作影响。因此,性能下降应由存储系统导致。

4 - etcd v2.2.0-rc 内存基准测试

etcd v2.2.0-rc-memory 的性能指标

物理机

GCE n1-standard-2 机器类型

  • 1 个专用本地 SSD,挂载于 /var/lib/etcd
  • 1 个专用慢速磁盘,用于操作系统
  • 7.5 GB 内存
  • 2 个 CPU

etcd

etcd Version: 2.2.0-rc.0+git
Git SHA: 103cb5c
Go Version: go1.5
Go OS/Arch: linux/amd64

测试

启动一个由 3 个成员组成的 etcd 集群,每个成员使用 2 个核心。

键名的长度始终为 64 字节,这是一个平均键字节数的合理长度。

内存最大使用量

  • 当一个跟随者失效而领导者持续发送快照时,etcd 可能会使用最大内存。
  • max RSS 是在三次运行中记录的最大内存使用量。
键字节数 键数量 数据大小(MB) 最大 RSS(MB) 领导者最大 RSS/数据比
128 50000 6 433 72x
128 100000 12 659 54x
128 200000 24 1466 61x
1024 50000 48 1253 26x
1024 100000 96 2344 24x
1024 200000 192 4361 22x

数据大小阈值

  • 当 etcd 达到数据大小阈值时,可能容易触发选举,并丢弃部分提案。
  • 对于大多数情况,只要 etcd 集群未触及该阈值,即可正常运行。若因资源不足导致运行不佳,应减小其数据规模。
键大小(字节) 键数量限制 建议数据大小阈值(MB) 消耗的 RSS(MB)
128 400K 48 2400
1024 300K 292 6500

5 - etcd v2.2.0-rc 基准测试

etcd 2.2.0-rc 的性能指标

物理机

GCE n1-highcpu-2 机器类型

  • 1 个专用本地 SSD,挂载于 /var/lib/etcd
  • 1 个专用慢速磁盘,用于操作系统
  • 1.8 GB 内存
  • 2 个 CPU

etcd 集群

3 etcd 2.2.0-rc 成员,每个成员运行在单台机器上。

详细版本:

etcd Version: 2.2.0-alpha.1+git
Git SHA: 59a5a7e
Go Version: go1.4.2
Go OS/Arch: linux/amd64

此外,我们使用 3 个 etcd 2.1.0 alpha 阶段成员组成集群以获取基准性能。etcd 的提交头位于 c7146bd5 ,与 etcd 2.1 基准测试 中所用版本相同。

测试

引导另一台机器,并使用 hey HTTP 压力测试工具 向每个 etcd 成员发送请求。请参阅 基准测试黑客指南 以获取详细操作说明。

性能

读取单一键

键大小(字节) 客户端数量 目标 etcd 服务器 读取 QPS 第 90 百分位延迟(毫秒)
64 1 仅领导者 2804 (-5%) 0.4 (+0%)
64 64 仅领导者 17816 (+0%) 5.7 (-6%)
64 256 仅领导者 18667 (-6%) 20.4 (+2%)
256 1 仅领导者 2181 (-15%) 0.5 (+25%)
256 64 仅领导者 17435 (-7%) 6.0 (+9%)
256 256 仅领导者 18180 (-8%) 21.3 (+3%)
64 64 所有服务器 46965 (-4%) 2.1 (+0%)
64 256 所有服务器 55286 (-6%) 7.4 (+6%)
256 64 所有服务器 46603 (-6%) 2.1 (+5%)
256 256 所有服务器 55291 (-6%) 7.3 (+4%)

编写一个键

键大小(字节) 客户端数量 目标 etcd 服务器 写入 QPS 第 90 百分位延迟(毫秒)
64 1 仅领导者 76(+22%) 19.4(-15%)
64 64 仅领导者 2461(+45%) 31.8(-32%)
64 256 仅领导者 4275(+1%) 69.6(-10%)
256 1 仅领导者 64(+20%) 16.7(-30%)
256 64 仅领导者 2385(+30%) 31.5(-19%)
256 256 仅领导者 4353(-3%) 74.0(+9%)
64 64 所有服务器 2005(+81%) 49.8(-55%)
64 256 所有服务器 4868(+35%) 81.5(-40%)
256 64 所有服务器 1925(+72%) 47.7(-59%)
256 256 所有服务器 4975(+36%) 70.3(-36%)

性能变化说明

  • 在大多数场景下,读取 QPS 下降了 5%~8%。原因是 etcd 会为每次存储操作记录存储指标。这些指标对监控和调试至关重要,因此该情况可接受。

  • 写入 QPS 到领导者提升了 20%~30%。这是因为我们将 Raft 主循环与条目应用循环解耦,避免了两者相互阻塞。

  • 所有服务器的写入 QPS 提升了 30% 至 80%,因为跟随者可更早接收到最新的提交索引,从而更快地提交提案。

6 - etcd v2.2.0 基准测试

etcd 2.2.0 的性能指标

物理机

GCE n1-highcpu-2 机器类型

  • 1 块专用本地 SSD,挂载为 etcd 数据目录
  • 1 块专用慢速磁盘,用于操作系统
  • 1.8 GB 内存
  • 2 个 CPU

etcd 集群

3 etcd 2.2.0 成员,每个成员运行在单台机器上。

详细版本:

etcd Version: 2.2.0
Git SHA: e4561dd
Go Version: go1.5
Go OS/Arch: linux/amd64

测试

在 etcd 集群外部引导另一台机器,并运行 hey HTTP 基准测试工具 (含连接复用补丁),向每个 etcd 集群成员发送请求。请参阅 基准测试说明 获取补丁及复现我们操作步骤的详细信息。

性能通过 100 次基准测试结果计算得出。

性能

单键读取性能

键大小(字节) 客户端数量 目标 etcd 服务器 平均读取 QPS 读取 QPS 标准差 平均 90th 百分位延迟(毫秒) 延迟标准差
64 1 仅领导者 2303 200 0.49 0.06
64 64 仅领导者 15048 685 7.60 0.46
64 256 仅领导者 14508 434 29.76 1.05
256 1 仅领导者 2162 214 0.52 0.06
256 64 仅领导者 14789 792 7.69 0.48
256 256 仅领导者 14424 512 29.92 1.42
64 64 所有服务器 45752 2048 2.47 0.14
64 256 所有服务器 46592 1273 10.14 0.59
256 64 所有服务器 45332 1847 2.48 0.12
256 256 所有服务器 46485 1340 10.18 0.74

单键写入性能

键大小(字节) 客户端数量 目标 etcd 服务器 平均写入 QPS 写入 QPS 标准差 平均 90th 百分位延迟(毫秒) 延迟标准差
64 1 仅领导者 55 4 24.51 13.26
64 64 仅领导者 2139 125 35.23 3.40
64 256 仅领导者 4581 581 70.53 10.22
256 1 仅领导者 56 4 22.37 4.33
256 64 仅领导者 2052 151 36.83 4.20
256 256 仅领导者 4442 560 71.59 10.03
64 64 所有服务器 1625 85 58.51 5.14
64 256 所有服务器 4461 298 89.47 36.48
256 64 所有服务器 1599 94 60.11 6.43
256 256 所有服务器 4315 193 88.98 7.01

性能变化

  • 由于 etcd 现在会记录每个 API 调用的指标,大多数场景下读取 QPS 性能似乎出现轻微下降。这种极小的性能影响被认为是对所返回监控与调试信息广度的合理投入。

  • 写入 QPS 到集群领导者似乎略有增加。这是因为 etcd Raft 逻辑中主循环与条目应用循环已解耦,消除了两者之间的多个阻塞点。

  • 写入 QPS 向所有成员显著增加,因为跟随者现在能更早接收到最新的提交索引,从而更快地提交提案。

7 - etcd v2.1.0 基准测试

etcd 2.1.0 的性能指标

物理机

GCE n1-highcpu-2 机器类型

  • 1 块专用本地 SSD,挂载于 /var/lib/etcd
  • 1 块专用慢速磁盘,用于操作系统
  • 1.8 GB 内存
  • 2 个 CPU
  • etcd 版本 2.1.0 alpha

etcd 集群

3 个 etcd 成员,每个成员运行在单台机器上

测试

引导另一台机器,并使用 hey HTTP 压力测试工具 向每个 etcd 成员发送请求。请参阅 基准测试黑客指南 以获取详细操作说明。

性能

读取单一键

键大小(字节) 客户端数量 目标 etcd 服务器 读取 QPS 第 90 百分位延迟(毫秒)
64 1 仅领导者 1534 0.7
64 64 仅领导者 10125 9.1
64 256 仅领导者 13892 27.1
256 1 仅领导者 1530 0.8
256 64 仅领导者 10106 10.1
256 256 仅领导者 14667 27.0
64 64 所有服务器 24200 3.9
64 256 所有服务器 33300 11.8
256 64 所有服务器 24800 3.9
256 256 所有服务器 33000 11.5

编写一个键

键大小(字节) 客户端数量 目标 etcd 服务器 写入 QPS 第 90 百分位延迟(毫秒)
64 1 仅领导者 60 21.4
64 64 仅领导者 1742 46.8
64 256 仅领导者 3982 90.5
256 1 仅领导者 58 20.3
256 64 仅领导者 1770 47.8
256 256 仅领导者 4157 105.3
64 64 所有服务器 1028 123.4
64 256 所有服务器 3260 123.8
256 64 所有服务器 1033 121.5
256 256 所有服务器 3061 119.3