etcd v3.7 的第一个 beta 版已经发布。这个版本对 Kubernetes 集群的核心存储层做了两件大事:一是新增 RangeStream RPC,让大结果集的读取不再一口气吞完;二是彻底移除 v2store,etcd 第一次做到 100% 运行在 v3store 上。如果你还在跑 v3.4,升级窗口正在关闭——3.4 将在 2026 年 5 月底停止一切更新。
大结果集的痛点与 RangeStream
在 v3.6 及更早版本中,一次 Range 请求返回多少条数据,客户端就得等多少条。当结果集很大时(比如遍历整个 Kubernetes namespace 下的所有 key),延迟不可预测,内存占用也难以控制——客户端必须先把完整结果缓冲到内存里才能开始处理。
RangeStream 把这个流程改成了流式返回:服务端分块推送,客户端逐块消费,延迟更平滑,内存用量更可控。这项工作的主要贡献者 Jeffrey Ying 是 etcd 的新贡献者,他在 Google 做软件工程师,因为生产环境中 Kubernetes 对 etcd 大结果集读取的性能瓶颈而投入了这个特性的开发。
用 etcdctl 体验 RangeStream
etcdctl 已经支持 RangeStream,最直接的方式是通过 --stream 标志启用:
# 启动一个测试 etcd 集群(单节点,仅用于本地验证)
etcd --data-dir=/tmp/etcd-test-data --listen-client-urls=http://127.0.0.1:2379 \
--advertise-client-urls=http://127.0.0.1:2379 &
# 写入一批测试数据
for i in $(seq 1 5000); do
etcdctl put "/apps/config/key$i" "value$i"
done
# 传统 Range:一次性返回所有 key,观察延迟和内存峰值
etcdctl get /apps/config/ --prefix --limit-key-number=5000
# RangeStream:流式分块返回,延迟更均匀
etcdctl get /apps/config/ --prefix --stream
--stream 模式下,etcdctl 会逐块打印结果,而不是等全部数据加载完毕后一次性输出。在大规模集群中,这个差异对监控和自动化脚本的行为影响显著。
在 Go 祖宗客户端中使用 RangeStream
如果你在自己的应用里直接调用 etcd gRPC 接口,可以这样使用 RangeStream RPC:
package main
import (
"context"
"fmt"
"log"
"time"
"go.etcd.io/etcd/client/v3"
)
func main() {
cli, err := clientv3.New(clientv3.Config{
Endpoints: []string{"http://127.0.0.1:2379"},
DialTimeout: 5 * time.Second,
})
if err != nil {
log.Fatal(err)
}
defer cli.Close()
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// 使用 RangeStream 获取 /apps/config/ 下所有 key
// client/v3 的 Get 在 v3.7 客户端中已支持流式模式
// 以下为基于 v3.7 客户端 SDK 的预期用法(beta 阶段 API 可能微调)
stream, err := cli.RangeStream(ctx, &clientv3.RangeStreamRequest{
Key: []byte("/apps/config/"),
RangeEnd: []byte("/apps/config0"), // prefix range: key ≥ prefix 且 < prefix+1
})
if err != nil {
log.Fatal(err)
}
count := 0
for resp := range stream.Recv() {
for _, kv := range resp.Kvs {
count++
if count <= 10 {
fmt.Printf("key: %s value: %s\n", string(kv.Key), string(kv.Value))
}
}
}
fmt.Printf("总共收到 %d 条记录(流式分块返回)\n", count)
}
注意:v3.7.0-beta.0 的客户端 SDK 中 RangeStream 的具体 Go API 可能仍在调整。上面的代码基于官方文档描述的 gRPC RangeStream RPC 语义编写,正式发布前请对照 etcd 文档 确认最终接口签名。运行前需将
go.etcd.io/etcd/client/v3替换为 v3.7 对应版本。
v2store 彻底移除:第一次纯 v3store 版本
v3.7 是 etcd 历史上第一个完全不包含 v2store 代码的版本。被移除的部分包括:
- discovery 服务(v2 协议的集群发现机制)
- bootstrap 中的 v2 路径
- v2 请求处理
- v2 客户端接口
- 多个已标记为 deprecated 的实验性 flag
如果你还在使用 v2 相关功能(比如 etcdctl v2 命令、--discovery 参数的旧格式),升级到 v3.7 时会遇到中断。SIG-Etcd 明确表示:他们想知道哪些移除造成了阻碍,请在 GitHub 上报告无法绕过的问题或需要更好升级文档的场景。
升级前的排查命令
在升级之前,先确认你的集群和客户端是否还在依赖 v2:
# 检查集群当前存储版本(v3.6+ 应已完全使用 v3store)
etcdctl endpoint status --write-out=table
# 检查是否还有 v2 key(在 v3.6 及更早版本中可能残留)
ETCDCTL_API=3 etcdctl get "" --prefix --keys-only | grep -c "^"
# 检查 etcd 版本
etcdctl version
# 如果你的集群还在 v3.5 或更早,先升级到 v3.6.11
# v3.6.11 是官方建议的跳板版本,移除 v2 的过渡工作在其中已基本完成
v3.7 还更新了底层依赖:bbolt 升级到 v1.5.0,raft 升级到 v3.7.0。这两个组件的变更对存储引擎稳定性和共识协议行为有直接影响,升级后应重点观察写入延迟和 leader 切换的表现。
v3.4 的最后期限
根据社区支持策略,etcd 只维护最近两个小版本。v3.7 正式发布后,维护范围将变为 v3.7 + v3.5(v3.5 获得一年延长支持)。v3.4 已于 2026 年 5 月 15 日进入 EOL,SIG-Etcd 可能会在 5 月底再发一个安全补丁(如果存在需要修复的漏洞),之后彻底停止更新。
还在跑 v3.4 的集群,现在就该做升级计划:
# 推荐的升级路径:3.4 → 3.5 → 3.6.11 → 3.7(正式版发布后)
# 每一步都应按官方滚动升级文档操作,逐个节点替换
# 单节点测试环境快速验证升级流程
etcdctl member list
# 记录 member ID 后,逐个节点:
# 1. 停止旧版本 etcd
# 2. 用新版本二进制启动,指向同一 data-dir
# 3. 等待集群健康后继续下一个节点
etcdctl endpoint health
测试 beta 并反馈
SIG-Etcd 需要真实用户在真实环境里跑 v3.7.0-beta.0。获取方式:
# 下载二进制
# https://github.com/etcd-io/etcd/releases/tag/v3.7.0-beta.0
# 或直接拉取官方容器镜像
docker pull quay.io/coreos/etcd:v3.7.0-beta.0
docker run --rm quay.io/coreos/etcd:v3.7.0-beta.0 etcd --version
反馈渠道:
- GitHub Issues:etcd-io/etcd 仓库
- Slack:Kubernetes Slack 中的
#SIG-etcd频道 - 邮件列表:etcd-dev mailing list
后续可能还会有额外的 beta 版本(重点是对 protobuf 库使用的重构),Release Candidate 和正式版预计在 6 月到 7 月初之间发布。
升级决策清单
在决定是否跟进 v3.7 之前,逐项确认:
| 检查项 | 说明 |
|---|---|
| 集群当前版本 | 如果低于 v3.6.11,先升级到 v3.6.11 再考虑 v3.7 |
| 是否依赖 v2 API | 搜索代码中 ETCDCTL_API=2、--discovery 旧格式、v2 client 调用 |
| 大结果集读取场景 | 有遍历大量 key 的监控/同步脚本?RangeStream 值得优先验证 |
| bbolt / raft 版本敏感 | 升级后重点观察写入延迟和 leader election 时间 |
| v3.4 集群 | 5 月底前必须完成至少到 v3.5 的升级 |
v3.7 的两个核心变更——RangeStream 和 v2store 移除——分别面向性能和架构清洁度。前者解决的是 Kubernetes 生态中真实存在的生产瓶颈,后者是 etcd 项目多年技术债的最终清算。现在去跑 beta,你的反馈直接决定正式版的质量和发布节奏。