基于鲲鹏Go编译优化的KV存储系统etcd性能调优参考实践
发表于 2026/06/30
0
1 非商用声明
该文档提供的内容为参考实践,仅供用户参考使用,用户可参考实践文档构建自己的软件,但不建议直接将相关Demo或可执行文件集成到商用产品中。
2 背景介绍
etcd 是一个开源的、高可用的由go语言编写的分布式键值(key-value)存储系统。它主要用于共享配置、服务发现以及集群状态感知。在云原生领域,etcd 最著名的角色是作为 Kubernetes 的“大脑”,存储了集群所有的状态数据和元数据。在某教育行业调优项目中,etcd资源占用率高且负载压力大,是集群交易的主要瓶颈,需要对etcd进行单点优化从而释放整个集群的交易性能。
3 方案介绍
GO4oE编译器(Go for openEuler)针对鲲鹏架构深度定制,引入了 kpatomic、标准库 Map 优化及增强内联等关键特性。本篇参考实践通过调整特定的编译选项开启优化特性,对 etcd 进行重新构建。随后,利用 etcd 内置的 benchmark 工具进行压测,从而体现GO4oE编译器在鲲鹏服务器及Go语言应用上的性能优势。
| 环境变量 | 包含优化项 | 描述 |
|---|---|---|
| GOARM64=v8.2,kpatomicopt,intrinsicmatchh2,abiinternal | kpatomic优化、Go标准库map函数优化、bytealg汇编函数切换 | 关LSE+锁优化,降低原子操作开销;消除Hashmap快速哈希匹配假阳性;汇编函数由堆栈调用约定切换到寄存器调用约定 |
| GOEXPERIMENT=stepopt2,atomicvar,revertcopyhashkeys,pageshift14,prefetchmalloc,clearspan,widetrie | step优化方案2、atomic优化、禁用复制哈希值、pagesize优化、内存prefetch优化、span初始化清零、hashtriemap优化 | 优化step函数实现;使用atomic替换dmb指令;回退性能劣化提交;扩大堆页大小;mallocgc增加prefetch操作;span首次使用整体清零;降低trie树层高,减少子节点访问 |
| GCFLAGS='all=-aggressivedse -aggressivelooprotate -aggressivepatterns -aggressiveprove -ccmp_gen -d forceinline=1 -d aarch64ldst=all -d blockpredict=2' | DSE优化增强、LoopRotate优化增强、SSA比较指令模式优化、Prove优化增强、条件比较指令优化、forceinline优化、ARM64 LDR/STR指令优化、基本块分支预测重排 | 增强死代码消除(指针偏移、store后load等场景);调整基本块顺序减少跳转;SSA模式匹配优化;消除边界检查;嵌套条件分支转CCMP/CCMN指令;强制内联mallocgc子函数;LDP/STP替换LDR/STR;基本块按分支属性重排 |
| LDFLAGS='all=-checklinkname=0 -w -funcalign=32' | 函数对齐优化 | 关闭链接名检查、去除DWARF调试信息、函数入口32字节对齐,提升指令缓存命中率 |
更多详细的编译选项用途可参考Go编译优化特性列表。
4 benchmark摸测
4.1 测试配置
| 配置项 | 配置说明 |
|---|---|
| 处理器(CPU) | Kunpeng920 7270Z |
| 宿主机OS | Kylin V10 SP3 (ARM64) |
| 虚拟机OS | Kylin V10 SP3 (ARM64) |
| 测试工具 | etcd自带benchmark |
| 目标软件 | etcd v3.5.13 |
| 虚拟机规格 | 4vCPU / 4GB / NVMe SSD |
| 优化编译器 | Go for openEuler(GO4oE1.24.6) |
| Bootstrap编译器 | go 1.23.10 |
4.2 操作指导书
步骤 1 编译GO4oE
# GO4oE源码
https://gitcode.com/openeuler/golang/tree/go1.24.6
# 获取能编译GO4oE 1.24.6的版本的开源go二进制
cd /home
wget https://mirrors.aliyun.com/golang/go1.23.10.linux-arm64.tar.gz
tar -zxvf go1.23.10.linux-arm64.tar.gz
# 编译GO4oE
yum install -y gcc make git
export GOROOT_BOOTSTRAP=/home/go
cd /home/goservicesopt/src/
./make.bash步骤 2 编译etcd
获取开源etcd二进制
mkdir -p /home/opensource&&cd /home/opensource
wget https://github.com/etcd-io/etcd/releases/download/v3.5.13/etcd-v3.5.13-linux-arm64.tar.gz
tar -zxvf etcd-v3.5.13-linux-arm64.tar.gz
# 解压后etcd二进制路径 ./etcd-v3.5.13-linux-arm64/etcd
# 与毕昇版本保持目录层级一致
mkdir etcd-v3.5.13-linux-arm64/bin
mv etcd-v3.5.13-linux-arm64/etcd etcd-v3.5.13-linux-arm64/bin/毕昇编译etcd
# 获取etcd源码
mkdir -p /home/bisheng&&cd /home/bisheng
git clone https://github.com/etcd-io/etcd.git -b v3.5.13
# 配置编译器
export PATH=/home/goservicesopt/bin:$PATH
# 配置编译选项
export GOARM64=v8.2,intrinsicmatchh2,abiinternal
export GOEXPERIMENT=stepopt,atomicvar,revertcopyhashkeys,pageshift14,prefetchmalloc,clearspan,widetrie,reflectrwlock
## 参考下图修改build.sh,在68行go build后追击如下内容
-gcflags='all=-aggressivedse -aggressivelooprotate -aggressivepatterns -aggressiveprove -ccmp_gen -bytesstringbytesopt -d forceinline=1 -d aarch64ldst=all -d blockpredict=2' -ldflags='all=-checklinkname=0 -w -funcalign=32'
# 编译
cd /home/bisheng/etcd
make build
步骤 3 编译benchmark工具
cd /home/bisheng/etcd
go build -o bin/benchmark ./tools/benchmark步骤 4 虚机绑核
# 编辑虚机配置文件
virsh edit {kylin-vm}
# 修改示例,在 <vcpu placement='static'>4</vcpu> 标签下添加如下内容
<cputune>
<vcpupin vcpu='0' cpuset='12'/>
<vcpupin vcpu='1' cpuset='13'/>
<vcpupin vcpu='2' cpuset='14'/>
<vcpupin vcpu='3' cpuset='15'/>
</cputune>
# 重启虚机
virsh destroy {kylin-vm}
virsh start {kylin-vm}步骤 5 测试
# 虚机启动etcd
# 进入到开源或毕昇etcd目录,执行如下命令,假定虚机ip为192.168.122.118
./bin/etcd --data-dir /data --quota-backend-bytes=85899345920 --listen-client-urls=http://0.0.0.0:2379 --advertise-client-urls=http://192.168.122.118:2379
# put测试
# 在宿主机上执行如下命令
taskset -c 12-27 ./bin/benchmark put --total=2000000 --key-size=128 --val-size=128 --key-space-size=1000 --clients=1000 --endpoints=192.168.122.118:2379
# range测试
# 在宿主机执行如下命令
taskset -c 12-27 ./bin/benchmark range "key_00000" "key_49999" --total=2000000 --clients=1000 --endpoints=192.168.122.118:2379----结束↵
4.3 测试结果

基于毕昇编译器进行编译优化后的etcd 在 Benchmark 测试中的性能较开源版本提升明显。
5 典型场景落地与优化
在实际生产环境中,etcd 除了作为 K8s 内置控制面外,更常作为独立的分布式键值数据库与状态存储中心,为上游业务应用提供高并发的配置管理、服务发现及分布式锁服务。
本章将详细介绍在独立数据库部署场景下,如何通过全栈硬件与内核优化保障底层性能,以及如何将第 4 章编译优化的 etcd 成果,以容器化方式无缝应用到业务 K8s 集群中。
5.1 常规优化
作为独立数据库,etcd 需要应对来自业务层频繁的强一致性读写。为确保其在鲲鹏服务器上发挥出最佳的吞吐量并维持极低的时延,需从 BIOS、系统内核及基础虚拟化层面进行全栈协同优化。具体优化矩阵如下:
| 优化项 | 实施方式 | 优化说明 |
|---|---|---|
| BIOS优化 | 高性能模式:BIOS路径“高级->能效配置->电源策略->性能模式” | 通用优化手段 |
| CPU超频:BIOS路径“高级->能效配置->CPU 性能配置->超频->启用” | 通用优化手段 | |
| 内存刷新速率:BIOS路径“内存配置->自定义刷新速率->自动” | 通用优化手段 | |
| SMMU开启:BIOS路径“高级->MISC 配置->支持 SMMU->启用” | 通用优化手段 | |
| 开启超线程:BIOS路径“高级->能效配置->CPU 性能配置->多线程->启用” | 提升逻辑核数量可创建更多虚机 | |
| 虚机绑核 | 参考4.2步骤4修改虚机配置文件,将同一虚机的vcpu绑定在一个NUMA节点 | 减少跨numa访存损耗 |
| 替换毕昇JDK | 毕昇JDK替换指南 | 毕昇jdk对鲲鹏服务器更亲和 |
| 磁盘IO优化 | sysctl -w vm.dirty_ratio = 50 sysctl -w vm.dirty_background_ratio = 5 sysctl -w vm.dirty_expire_centisecs = 5000 | 使用hdd磁盘时可增大缓存使用减少磁盘压力 |
5.2 K8s 场景下的组件替换与应用
针对以 Kubernetes 容器化方式部署的独立 etcd 数据库集群,在完成第 4.2 章节的编译优化后,需通过容器镜像重构的方式,将优化后的二进制文件平滑替换至生产集群中,供上游应用服务调用。
1. 镜像重构与封装
假设原先基础镜像为 ctrimages.aaa.bbb/library/etcd:v3.5.13。我们利用标准镜像作为底座,采用“原地替换”方式制作毕昇优化版镜像:
# 创建临时容器,建立文件通道。基于原版镜像创建一个挂起状态的临时容器,用于提取和注入文件
docker create --name temp-etcd ctrimages.aaa.bbb/library/etcd:v3.5.13
# 注入毕昇etcd,将第 4.2 章节中编译好的鲲鹏亲和版 etcd 二进制文件,拷贝到容器内的指定路径(原二进制文件路径可通过在运行中的应用 Pod 内执行 ps 和 which etcd 确认)
docker cp etcd temp-etcd:/opt/bitnami/etcd/bin/etcd
# 提交镜像,将修改后的容器提交为一个新的标准镜像,并追加毕昇优化版标签
docker commit -m "bisheng etcd" temp-etcd ctrimages.aaa.bbb/library/etcd:v3.5.13-bisheng
# 推送私仓,登录集群私有仓库,并将重构后的独立数据库镜像推送至远端,供 K8s 节点拉取
docker login ctrimages.aaa.bbb
docker push ctrimages.aaa.bbb/library/etcd:v3.5.13-bisheng2. 独立数据库镜像应用与升级
完成镜像推送后,需要更新 K8s 中部署的 etcd 业务数据库实例。由于其作为独立应用服务运行,建议采用标准声明式配置进行平滑升级:
登录集群管理页面,导航至对应的命名空间(Namespace),找到负责部署 etcd 独立数据库的 StatefulSet、Deployment 或 Helm Chart,修改其 YAML 配置文件。将 image 字段的 Tag 替换为优化后的版本,示例如下:
spec:
containers:
- name: etcd
image: ctrimages.aaa.bbb/library/etcd:v3.5.13-bisheng# 替换为优化后的毕昇版本

