Ubuntu 22.04 安装 Apache ResilientDB 指南

在 Ubuntu 22.04 上源码编译部署 Apache ResilientDB,涵盖 Bazel 6.0.0 构建、证书密钥生成、4 副本加客户端代理启动、systemd 托管与客户端读写验证,命令与回显均实测

Apache ResilientDBApache ResilientDB2026/10/12

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 ResilientDBmaster(commit 4de5cb4)源码编译;官方同时发布 1.11.0 / 1.12.0 二进制包
Bazel / Bazelisk6.0.0 / v1.29.0INSTALL.sh 安装 Bazelisk v1.29.0,按仓库 .bazelversion 拉取 Bazel 6.0.0
gcc11.4.0(Ubuntu 22.04 自带)C++17 构建
Python3.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 缓存

九、参考链接