Tendis 在银河麒麟 V10 SP3 + 鲲鹏 ARM64(QEMU 模拟)环境下的适配验证与性能评估
Tendis 在银河麒麟 V10 SP3 + 鲲鹏 ARM64(QEMU 模拟)适配与验证记录
环境:Windows + Intel i5-13600K + QEMU 全系统模拟 ARM64
目标:验证 Tendis 是否能够在银河麒麟 V10 SP3 SP3 + 鲲鹏 ARM64 环境离线部署运行
结论:可以编译、可以运行、可以通信,但存在明显 ARM + RocksDB 性能特征差异,需要针对性调优
一、项目背景
最终部署目标环境:
- 银河麒麟高级服务器操作系统 V10 SP3 2403
- CPU:鲲鹏 ARM64
当前开发环境:
- Windows 11
- Intel i5-13600K
- QEMU 全系统模拟 ARM64
由于缺少真实鲲鹏物理机,因此采用 QEMU 模拟整机环境进行前置验证,确保:
- 编译链可用
- 依赖可满足
- 服务可启动
- 基础功能可运行
- 性能具备参考价值(非最终值)
二、技术验证方案
2.1 选型对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| Docker + QEMU | 简单 | 与真实系统差异较大 |
| QEMU 全系统 ARM64 | 最接近真实环境 | 性能偏差较大 |
最终选择:
QEMU 全系统 ARM64 + 银河麒麟 V10 SP3
2.2 QEMU 启动环境
关键启动参数:
qemu-system-aarch64.exe -M virt -cpu cortex-a72 -m 8192 -smp 8 -bios D:\Dev\Tools\qemu\share\edk2-aarch64-code.fd -drive if=virtio,file=D:\Dev\Env\kylin-arm64.qcow2,format=qcow2 -cdrom D:\Dev\Projects\ISO\Kylin-Server-V10-SP3-2403-Release-20240426-ARM64.iso -device virtio-gpu-pci -device qemu-xhci -device usb-kbd -device usb-mouse -nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 -nographic
三、系统安装与基础环境
3.1 系统信息
查看架构:
uname -m
输出:
aarch64
查看系统版本:
cat /etc/os-release
关键输出:
Kylin Linux Advanced Server V10 (Halberd)
3.2 网络问题修复
初始状态:
- 网卡 disconnected
- 无 IP
修复操作:
nmcli connection up emp0s1
恢复后 IP:
10.0.2.15
验证网络连通性:
ping -c 4 10.0.2.2
3.3 基础依赖安装
安装编译及工具链依赖:
yum install -y gcc gcc-c++ make cmake git wget curl tar unzip zip openssl-devel zlib-devel
四、第一个核心问题:GCC 版本过低
默认 GCC 版本:
gcc --version
gcc 7.3.0
问题:Tendis 依赖 C++17 特性,GCC 7.3 对 C++17 支持不完整,编译会报错。
解决方案:手动安装 GCC 8.4 到 /usr/local/gcc-8.4,并在 CMake 时显式指定编译器路径。
cmake -DCMAKE_C_COMPILER=/usr/local/gcc-8.4/bin/gcc -DCMAKE_CXX_COMPILER=/usr/local/gcc-8.4/bin/g++ ..
注:GCC 8.4 安装包需提前从可信源获取,或通过源码编译安装(离线环境可提前准备 RPM 包)。
五、源码编译问题修复记录
5.1 submodule 未拉取
源码中的第三方依赖(如 RocksDB)以 git submodule 形式管理,克隆时需一并拉取:
git submodule update --init --recursive
5.2 C_STANDARD=17 不兼容
错误信息:
C_STANDARD is set to invalid value '17'
原因:CMake 版本较低,不识别 C_STANDARD 17。
修复:将 CMakeLists.txt 中的标准改为 C++11(Tendis 实际可用 C++11 编译)。
set(CMAKE_C_STANDARD 11)
5.3 缺少
编译 ldb_tendis.cpp 时报错:
error: 'setw' is not a member of 'std'
error: 'setfill' is not a member of 'std'
修复:在该文件头部添加 #include 。
sed -i '1i #include <iomanip>' \
src/tendisplus/tools/ldb_tendis.cpp
5.4 ldb_tendis 链接失败
错误:
undefined reference: rocksdb::Iterator
该工具是辅助 CLI,不影响 Tendis 服务主程序。若仅需服务端,可单独编译 tendisplus 目标:
make tendisplus
5.5 RocksDB patch 未应用
编译时报错:
rocksdb/tendis_extension.h: No such file or directory
原因:Tendis 对 RocksDB 有定制补丁,需先打补丁才能生成扩展头文件。
修复步骤:
cd src/thirdparty/rocksdb/rocksdb
patch -p1 < ../../patch/0002-add-latency-statistic-log.patch
打补丁后重新编译 RocksDB 和 Tendis。
六、Tendis 服务启动验证
使用默认配置文件启动:
$ ./build/bin/tendisplus tendisplus.conf
报错,因为目录不存在:
IO error: No such file or directory:
While mkdir if missing: ./home/db/catalog
说明:
dir="./home/db"
logDir="./home/log"
dumpdir="./home/dump"
但 ./home/db 这个父目录不存在,所以 RocksDB 创建 catalog 失败了。
直接执行:
mkdir -p ./home/db
mkdir -p ./home/dump
mkdir -p ./home/log
然后确认:
ls -ld ./home ./home/db ./home/dump ./home/log
重新启动:
./build/bin/tendisplus tendisplus.conf
然后立即执行:
ps -ef | grep tendisplus
启动成功。
6.3 端口监听确认
ss -lntp | grep 51002
输出示例:
LISTEN 0 128 127.0.0.1:51002 *:* users:(("tendisplus",pid=1234,fd=10))
确认服务已成功监听在默认端口 51002。
七、Redis 协议兼容性验证
使用 Redis 客户端连接 Tendis 并执行 PING:
./src/redis-cli -h 127.0.0.1 -p 51002 ping
报错:
无法执行二进制文件: 可执行文件格式错误
基本只有一个原因:
❗ 这个 redis-cli 是 x86_64 编译的,你现在是 ARM64(鲲鹏)
确认 redis-cli 架构:
file ./bin/redis-cli
直接测协议(Redis RESP):
telnet 127.0.0.1 51002
然后输入:
ping
或者更标准 RESP:
*1
$4
PING
返回:
+PONG
编译ARM64 redis-cli:
cd /root
wget https://download.redis.io/releases/redis-7.2.4.tar.gz
tar -xvf redis-7.2.4.tar.gz
cd redis-7.2.4
只编 redis-cli(不用全量 Redis):
make redis-cli
make -j$(nproc) redis-cli MALLOC=libc
检查是否是 ARM64:
file src/redis-cli
输出:
ELF 64-bit LSB executable, aarch64
直接使用:
./src/redis-cli -h 127.0.0.1 -p 51002 ping
八、性能测试
确认 benchmark 工具
./src/redis-benchmark --help
如果有输出说明OK。
报错,因为刚才只编译了redis-cli,重新全量编译:
make -j$(nproc)
- 测试指标QPS (Queries Per Second):这些测试会输出 Redis 每秒能处理多少请求,数值越高性能越好。通常单机 Redis 的 QPS 能达到 10 万左右。
基础压测(重点)
./src/redis-benchmark -h 127.0.0.1 -p 51002 -t set,get -n 100000 -c 50
用Redis/Tendis 自带的压测工具redis-benchmark,测试两种操作(读,写),总请求数20万次,50个客户端并发连接。
SET 性能:每秒处理 880 次写请求
| 指标 | 数值 | 含义 |
|---|---|---|
| avg | 56 ms | 平均一次写 56ms |
| p95 | 111 ms | 95%请求 < 111ms |
| p99 | 136 ms | 99%请求 < 136ms |
| max | 224 ms | 最慢 224ms |
GET 性能:每秒处理 1296 次读请求
| 指标 | 数值 | 含义 |
|---|---|---|
| avg | 37 ms | 平均一次读 37ms |
| p95 | 79 ms | 95%请求 < 79ms |
| p99 | 101 ms | 99%请求 < 101ms |
| max | 181 ms | 最慢 181ms |
模拟真实负载(更关键)
- 小并发读写混合
./src/redis-benchmark -h 127.0.0.1 -p 51002 -t set,get,incr -n 200000 -c 100
用Redis/Tendis 自带的压测工具redis-benchmark,测试三种操作(读,写,原子自增),总请求数20万次,100个客户端并发连接。
| 指标 | 数值 | 含义 |
|---|---|---|
| avg | 136.177 ms | 平均一次请求 136.177ms |
| p95 | 239.999 ms | 95% 请求 < 239.999ms |
| p99 | 278.015 ms | 95% 请求 < 278.015ms |
| max | 422.143 ms | 最慢 422.143ms |
- 高并发测试(看极限)
./src/redis-benchmark -h 127.0.0.1 -p 51002 -t set,get -n 500000 -c 200
用Redis/Tendis 自带的压测工具redis-benchmark,测试两种操作(读,写),总请求数50万次,200个客户端并发连接。
| 指标 | 数值 | 含义 |
|---|---|---|
| avg | 162.770 ms | 平均一次写 162.770ms |
| p95 | 285.439 ms | 95% 请求 < 285.439ms |
| p99 | 322.559 ms | 99% 请求 < 322.559ms |
| max | 436.479 ms | 最慢 436.479ms |
延迟测试
./src/redis-benchmark -h 127.0.0.1 -p 51002 -t set -n 100000 -c 10 -q
用Redis/Tendis 自带的压测工具redis-benchmark,测试一种操作(写),总请求数10万次,10个客户端并发连接,并以精简模式输出结果。
| 指标 | 数值 | 含义 |
|---|---|---|
| 吞吐量 | 737.75 req/s | 每秒处理 737.75 次 SET 写请求 |
| p50 | 9.631 msec | 50% 的请求在 9.631ms 内完成(即中位数延迟) |
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐
所有评论(0)