Ubuntu 22.04 安装 Apache ResilientDB 指南
在 Ubuntu 22.04 上源码编译部署 Apache ResilientDB,涵盖 Bazel 6.0.0 构建、证书密钥生成、4 副本加客户端代理启动、systemd 托管与客户端读写验证,命令与回显均实测
Ubuntu 22.04 安装 Apache ResilientDB 指南
目标:在真实 Ubuntu 22.04 服务器上从零源码编译部署 Apache ResilientDB(高吞吐 PBFT 授权区块链账本,KV 服务形态),覆盖依赖安装、Bazel 构建、证书密钥生成、4 副本 + 1 客户端代理启动、systemd 托管与客户端读写验证。以下命令与回显均在 Ubuntu 22.04.5 真实环境逐步实测。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- 编译器:gcc 11.4.0、cmake 3.22.1
- Python:3.10.12
- Bazel:6.0.0(Bazelisk v1.29.0,按源码
.bazelversion固定) - 源码:master 分支 commit
4de5cb43686276ace4307f44839a1de920ab524a(2026-09-27) - 源码目录:
/root/incubator-resilientdb - 服务端口:4 副本 10001-10004,客户端代理 10005(均监听 127.0.0.1)
- 运行用户:root
- 配置文件:
service/tools/config/server/server.config、service/tools/config/interface/service.config
💡 说明:Apache ResilientDB 于 2026-09-16 正式从 Apache 孵化器毕业成为顶级项目(TLP),官方发行版可在 https://downloads.apache.org/incubator/resilientdb/ 获取(当前 1.11.0 / 1.12.0),本文实测基于 master 分支源码。
二、前置条件
- 一台 Ubuntu 22.04 服务器,root 权限,建议 8 核以上 CPU、8GB 以上内存(完整编译实测在 12 核环境约 25 分钟)。
- 可访问 GitHub(源码克隆与 Bazel 外部依赖下载)。
- 磁盘剩余空间 10GB 以上(源码约 43MB,Bazel 输出与依赖缓存约 3GB)。
三、版本选型说明
| 组件 | 版本 | 说明 |
|---|---|---|
| Apache ResilientDB | master(commit 4de5cb4) | 源码编译;官方同时发布 1.11.0 / 1.12.0 二进制包 |
| Bazel / Bazelisk | 6.0.0 / v1.29.0 | INSTALL.sh 安装 Bazelisk v1.29.0,按仓库 .bazelversion 拉取 Bazel 6.0.0 |
| gcc | 11.4.0(Ubuntu 22.04 自带) | C++17 构建 |
| Python | 3.10.12 | 构建脚本与 SDK 依赖 |
| LevelDB | 可选编译开关 | 默认使用内存存储,--define=enable_leveldb=True 启用落盘 |
💡 存储引擎说明:默认构建的
kv_service使用内存存储,进程重启后数据清空(本文实测验证,见「注意事项」);需要落盘持久化时使用--define=enable_leveldb=True重新编译(开关定义位于源码chain/storage/setting/BUILD,默认False)。
四、部署步骤
4.1 安装系统依赖
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y build-essential cmake python3 python3-pip openssl libssl-dev \
git automake autoconf libtool wget curl unzip zip psmisc net-tools \
default-jre-headless protobuf-compiler rapidjson-dev python3-dev clang-format
💡
psmisc提供killall(官方启停脚本依赖),default-jre-headless供 Bazel 运行,net-tools提供netstat便于端口核查。
4.2 获取源码
cd /root
git clone https://github.com/apache/incubator-resilientdb
cd incubator-resilientdb
git log -1 --format='%H %cd %s'
回显:
4de5cb43686276ace4307f44839a1de920ab524a Sun Sep 27 10:03:08 2026 -0700 Update README.md
4.3 运行官方安装脚本 INSTALL.sh
INSTALL.sh 会安装 apt 依赖并把 Bazelisk v1.29.0(下载后做 sha256 校验)安装到 /usr/local/bin/bazel,再按仓库 .bazelversion(6.0.0)拉取对应 Bazel:
./INSTALL.sh
关键回显(末段):
Setting up psmisc (23.4-2build3) ...
安装后核查 Bazel:
bazel --version
回显:
bazel 6.0.0
⚠️ 若
INSTALL.sh在下载 Bazelisk 时因网络波动报curl: (56) OpenSSL SSL_read: Connection reset by peer,重跑脚本即可;离线或弱网环境可先在有网机器下载 Bazel 6.0.0 官方二进制(发布页提供 sha256 校验文件)放置到/usr/local/bin/bazel,效果与 Bazelisk 按.bazelversion拉取一致。
4.4 生成证书与公私钥
ResilientDB 各副本间通信使用证书签名,先用官方脚本生成 5 组密钥(4 副本 + 1 客户端代理)与 admin 密钥。脚本内部会先编译 //tools:certificate_tools 与 //tools:key_generator_tools(首次触发 Bazel 拉取全部外部依赖并编译基础库,12 核实测约 9 分钟):
./service/tools/kv/server_tools/generate_keys_and_certs.sh
关键回显:
Building certificate and key generation tools...
Target //tools:certificate_tools up-to-date:
INFO: Elapsed time: 523.450s, Critical Path: 437.13s
INFO: Build completed successfully, 245 total actions
Target //tools:key_generator_tools up-to-date:
INFO: Elapsed time: 1.557s, Critical Path: 1.24s
INFO: Build completed successfully, 6 total actions
- Node 1 keys: /root/incubator-resilientdb/service/tools/data/cert//node1.key.pri, /root/incubator-resilientdb/service/tools/data/cert//node1.key.pub
- Node 1 certificate: /root/incubator-resilientdb/service/tools/data/cert//cert_1.cert
- Node 2 keys: /root/incubator-resilientdb/service/tools/data/cert//node2.key.pri, /root/incubator-resilientdb/service/tools/data/cert//node2.key.pub
- Node 2 certificate: /root/incubator-resilientdb/service/tools/data/cert//cert_2.cert
- Node 3 keys: /root/incubator-resilientdb/service/tools/data/cert//node3.key.pri, /root/incubator-resilientdb/service/tools/data/cert//node3.key.pub
- Node 3 certificate: /root/incubator-resilientdb/service/tools/data/cert//cert_3.cert
- Node 4 keys: /root/incubator-resilientdb/service/tools/data/cert//node4.key.pri, /root/incubator-resilientdb/service/tools/data/cert//node4.key.pub
- Node 4 certificate: /root/incubator-resilientdb/service/tools/data/cert//cert_4.cert
- Node 5 keys: /root/incubator-resilientdb/service/tools/data/cert//node5.key.pri, /root/incubator-resilientdb/service/tools/data/cert//node5.key.pub
- Node 5 certificate: /root/incubator-resilientdb/service/tools/data/cert//cert_5.cert
确认证书目录:
ls service/tools/data/cert/
回显:
admin.key.pri
admin.key.pub
cert_1.cert
cert_2.cert
cert_3.cert
cert_4.cert
cert_5.cert
node1.key.pri
node1.key.pub
node2.key.pri
node2.key.pub
node3.key.pri
node3.key.pub
node4.key.pri
node4.key.pub
node5.key.pri
node5.key.pub
💡 证书生成脚本默认对 5 个
127.0.0.1节点按PORT_BASE=10000生成密钥与证书,与本机 4 副本 + 1 客户端代理的默认拓扑一致。
4.5 启动 KV 服务(4 副本 + 1 客户端代理)
官方脚本会先增量编译 //service/kv:kv_service,再以 nohup 依次拉起 4 个副本与 1 个客户端代理进程(客户端代理负责批量转发客户端请求给主副本):
./service/tools/kv/server_tools/start_kv_service.sh
构建完成回显(duckdb 等大文件编译在 12 核实测约 20 分钟):
INFO: Build completed successfully, 169 total actions
核查进程与端口:
ps aux | grep [k]v_service | wc -l
netstat -tlnp | grep 1000
回显:
5
tcp 0 0 127.0.0.1:10001 0.0.0.0:* LISTEN 18807/./bazel-bin/s
tcp 0 0 127.0.0.1:10002 0.0.0.0:* LISTEN 18808/./bazel-bin/s
tcp 0 0 127.0.0.1:10003 0.0.0.0:* LISTEN 18809/./bazel-bin/s
tcp 0 0 127.0.0.1:10004 0.0.0.0:* LISTEN 18810/./bazel-bin/s
tcp 0 0 127.0.0.1:10005 0.0.0.0:* LISTEN 18811/./bazel-bin/s
💡 副本进程日志写在启动目录的
server0.log~server3.log与client.log;出现consensus_manager.cpp:228] receive public size:5 primary:1即代表 4 副本 PBFT 共识已就绪。
4.6 构建客户端工具
bazel build service/tools/kv/api_tools/kv_service_tools
回显:
INFO: Elapsed time: 3.141s, Critical Path: 2.60s
INFO: Build completed successfully, 8 total actions
4.7 客户端 set/get 验证
写入并读取一个键值(客户端工具经由客户端代理端口 10005 访问集群):
./bazel-bin/service/tools/kv/api_tools/kv_service_tools \
--config service/tools/config/interface/service.config \
--cmd set --key user1001 --value alice
回显:
WARNING: Logging before InitGoogleLogging() is written to STDERR
E20261012 14:36:10.798208 19633 resdb_config_utils.cpp:146] parse json id:1 ip:127.0.0.1 port:10005
set key = user1001, value = alice done, ret = 0
./bazel-bin/service/tools/kv/api_tools/kv_service_tools \
--config service/tools/config/interface/service.config \
--cmd get --key user1001
回显:
WARNING: Logging before InitGoogleLogging() is written to STDERR
E20261012 14:36:10.803941 19627 resdb_config_utils.cpp:146] parse json id:1 ip:127.0.0.1 port:10005
get key = user1001 value = alice
💡 输出首行的
WARNING: Logging before InitGoogleLogging()与parse json ...是 glog 在初始化前打印的配置解析提示(STDERR),不影响功能。
4.8 systemd 托管(生产推荐)
创建 /etc/systemd/system/resilientdb-kv.service:
[Unit]
Description=Apache ResilientDB KV Service (4 replicas + 1 client proxy)
After=network.target
[Service]
Type=forking
User=root
WorkingDirectory=/root/incubator-resilientdb
ExecStart=/bin/bash /root/incubator-resilientdb/service/tools/kv/server_tools/start_kv_service.sh
ExecStop=/usr/bin/killall -9 kv_service
RemainAfterExit=yes
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
⚠️
ExecStart必须以/bin/bash调用官方脚本:start_kv_service.sh文件头没有 shebang,直接ExecStart=.../start_kv_service.sh会报status=203/EXEC(Exec format error),实测日志如下:systemd[21223]: resilientdb-kv.service: Failed to execute /root/incubator-resilientdb/service/tools/kv/server_tools/start_kv_service.sh: Exec format error systemd[1]: resilientdb-kv.service: Failed with result 'exit-code'.
启动并设置开机自启:
systemctl daemon-reload
systemctl start resilientdb-kv
systemctl enable resilientdb-kv
systemctl is-active resilientdb-kv
回显:
active
核查端口与进程(应看到 5 个 LISTEN):
netstat -tln | grep -c 1000
回显:
5
停止服务:
systemctl stop resilientdb-kv
systemctl is-active resilientdb-kv
回显:
inactive
五、配置说明
5.1 服务端配置
服务端配置为 service/tools/config/server/server.config,声明 4 个副本(10001-10004)、存储与共识开关,关键内容:
{
region : {
replica_info : {
id:1,
ip:"127.0.0.1",
port: 10001,
},
replica_info : {
id:2,
ip:"127.0.0.1",
port: 10002,
},
replica_info : {
id:3,
ip:"127.0.0.1",
port: 10003,
},
replica_info : {
id:4,
ip:"127.0.0.1",
port: 10004,
},
region_id: 1,
},
self_region_id:1,
leveldb_info : {
write_buffer_size_mb:128,
write_batch_size:1,
enable_block_cache: true,
block_cache_capacity: 100
},
require_txn_validation:true,
enable_viewchange:false,
enable_resview:true,
enable_faulty_switch:false
}
5.2 客户端配置
客户端工具使用的入口配置为 service/tools/config/interface/service.config,指向客户端代理端口 10005:
{
"replica_info":[
{
"id":1,
"ip":"127.0.0.1",
"port":10005
}
],
"region_id":1
}
5.3 JVM 说明
Apache ResilientDB 核心为 C++ 实现,不含 Java 业务进程(Bazel 自身运行依赖 JRE,无需调堆);无需 JVM 内存配置项。
六、注意事项
- 默认内存存储:默认构建使用内存存储,重启后数据清空。实测过程:
killall -9 kv_service后重新执行start_kv_service.sh,此前写入的user1001读取结果为空:需要落盘请用get key = user1001 value =bazel build //service/kv:kv_service --define=enable_leveldb=True重新编译,并配合server.config中leveldb_info参数。 - PBFT 要求 3f+1 副本(f 为可容忍拜占庭副本数),默认 4 副本即 f=1;生产至少 4 副本起步。
- 完整编译耗时集中在 duckdb、cryptopp 等大文件,12 核实测约 25 分钟,属正常现象;如构建失败可降低
.bazelrc中--jobs数值(默认 40)重试。 - 版本化函数(
set_with_version/get_with_version)与非版本函数(set/get)使用两套存储,官方明确不可混用于同一应用。
七、常见问题
7.1:INSTALL.sh 报 curl: (56) OpenSSL SSL_read: Connection reset by peer
定位:Bazelisk 下载阶段网络波动,脚本随即中止。
解决:重新执行 ./INSTALL.sh;弱网环境按 4.3 节 ⚠️ 说明改为直接部署 Bazel 6.0.0 官方二进制。
7.2:Bazel 构建外部依赖时 connect timed out(如 rules_foreign_cc 0.6.0.tar.gz)
定位:构建机到 GitHub 的连接不稳定,外部仓库拉取失败,报错形如:
ERROR: Error computing the main repository mapping: no such package '@rules_foreign_cc//foreign_cc': java.io.IOException: Error downloading [https://github.com/bazelbuild/rules_foreign_cc/archive/0.6.0.tar.gz] ...: connect timed out
解决:在有网机器按 WORKSPACE/repositories.bzl 中的 URL 预下载全部依赖包(按 URL 文件名命名),放到如 /root/rdb-dist 目录,并写入 ~/.bazelrc:
build --distdir=/root/rdb-dist
fetch --distdir=/root/rdb-dist
Bazel 会优先从 distdir 取包,不再逐个访问网络;重新执行构建即可。
7.3:systemctl start resilientdb-kv 报 status=203/EXEC
定位:官方 start_kv_service.sh 无 shebang,systemd 直接 exec 报 Exec format error。
解决:ExecStart 改为 /bin/bash /root/incubator-resilientdb/service/tools/kv/server_tools/start_kv_service.sh(见 4.8 节单元文件)。
7.4:启动脚本执行后端口没有监听
定位:副本进程启动即崩溃,多为证书文件缺失或端口占用。
解决:确认 service/tools/data/cert/ 下已有 node1-5.key.pri 与 cert_1-5.cert(未生成先跑 4.4 节脚本);用 netstat -tlnp | grep 1000 核查端口占用,必要时 killall -9 kv_service 后重启。
7.5:客户端 set 报 Failed to open file. No such file or directory
定位:--config 路径不正确,工具在打印 usage 后报该错误。
解决:在源码目录内使用相对路径 service/tools/config/interface/service.config,或改用绝对路径。
八、卸载方式
systemctl stop resilientdb-kv 2>/dev/null # 若已配置 systemd 托管
systemctl disable resilientdb-kv 2>/dev/null
killall -9 kv_service # 停止全部副本进程
rm -rf /root/incubator-resilientdb # 删除源码与构建产物
rm -f /etc/systemd/system/resilientdb-kv.service
systemctl daemon-reload
rm -rf /root/.cache/bazel /root/.cache/bazel-repo # 可选:清理 Bazel 缓存
九、参考链接
- Apache ResilientDB 官网:https://resilientdb.com/
- 源码仓库:https://github.com/apache/incubator-resilientdb
- 官方发行版下载:https://downloads.apache.org/incubator/resilientdb/
- 官方快速上手博客:https://blog.resilientdb.com/2022/09/28/GettingStartedNexRes.html