欢迎光临
我们一直在努力

我用 2G 服务器跑通了 OpenTenBase!分布式数据库 Docker 化部署全过程

前言

说实话,我差点被 OpenTenBase 的部署逼疯了。

作为一个学生,只有一台 2G 内核、1 核 CPU 的腾讯云服务器,想要研究国产分布式数据库 OpenTenBase 的源码和架构。

结果发现:

官方部署流程太复杂了!

需要:

  • 编译 30-60 分钟
  • 手动配置 14 个步骤
  • 分别初始化 GTM、Coordinator、Datanode
  • 手动注册节点到 pgxc_node 表
  • 配置一堆端口和参数

而且,编译到一半就报错,内存不够,CPU 跑满,Docker 容器各种依赖问题…

折腾了三天,我终于把 OpenTenBase 做成了 Docker 一键部署 版本!

现在,只需要 2 命令就能启动完整的 OpenTenBase 集群。


一、OpenTenBase 是什么

OpenTenBase 是腾讯开源的分布式 HTAP 数据库,基于 PostgreSQL 10 开发。

简单说:

  • HTAP: 同时支持 OLTP(事务)和 OLAP(分析)
  • 分布式: 支持水平扩展,数据自动分片
  • 高可用: 支持主备切换、故障自动恢复

架构是这样的:

┌─────────────────────────────────────────────────────────────┐
│ OpenTenBase 集群 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ GTM │ ← 全局事务管理器(Port: 6666) │
│ └─────┬────┘ │
│ │ │
│ ┌─────┴────┐ │
│ │ │ │
│ ┌──▼───┐ ┌──▼───┐ ┌────────┐ │
│ │ CN1 │ │ CN2 │ … │ CNx │ ← 协调节点(Port: 5432) │
│ └──┬───┘ └──┬───┘ └────────┘ │
│ │ │ │
│ └────┬───┘ │
│ │ │
│ ┌────┴────┐ │
│ │ │ │
│ ┌──▼───┐ ┌──▼───┐ ┌────────┐ │
│ │ DN1 │ │ DN2 │ … │ DNx │ ← 数据节点(Port: 15432) │
│ └──────┘ └──────┘ └────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

在这里插入图片描述


二、为什么官方部署痛苦

2.1 官方部署流程(14 个步骤!)

# 1. 克隆源码
git clone https://github.com/OpenTenBase/OpenTenBase.git

# 2. 安装依赖(30+ 个包)
apt install build-essential bison flex perl \\
libreadline-dev zlib1g-dev libssl-dev libpam0g-dev \\
libxml2-dev libldap2-dev libossp-uuid-dev uuid-dev \\
libcurl4-openssl-dev liblz4-dev libzstd-dev \\
libcli11-dev libpqxx-dev libtool pkg-config

# 3. 编译(30-60 分钟)
./configure –prefix=/usr/local/opentenbase
make -j4
make install

# 4. 初始化 GTM
initgtm -D /path/to/gtm_data

# 5. 初始化 Coordinator
initdb -D /path/to/coord_data \\
–nodename=coord1 –nodetype=coordinator \\
–master_gtm_nodename=gtm_master \\
–master_gtm_ip=127.0.0.1 \\
–master_gtm_port=6666

# 6. 初始化 Datanode
initdb -D /path/to/dn_data \\
–nodename=dn001 –nodetype=datanode \\
–master_gtm_nodename=gtm_master \\
–master_gtm_ip=127.0.0.1 \\
–master_gtm_port=6666

# 7. 配置 postgresql.conf
vim /path/to/coord_data/postgresql.conf
vim /path/to/dn_data/postgresql.conf

# 8. 启动 GTM
gtm_ctl -D /path/to/gtm_data start

# 9. 启动 Coordinator
pg_ctl -D /path/to/coord_data start

# 10. 启动 Datanode
pg_ctl -D /path/to/dn_data start

# 11. 注册节点(在 Coordinator 上执行)
psql -p 5432 -c "CREATE GTM NODE gtm_master WITH (HOST='127.0.0.1', PORT=6666, PRIMARY);"
psql -p 5432 -c "CREATE NODE coord1 WITH (TYPE='coordinator', HOST='127.0.0.1', PORT=5432, FORWARD=6669);"
psql -p 5432 -c "CREATE NODE dn001 WITH (TYPE='datanode', HOST='127.0.0.1', PORT=15432, FORWARD=6670, PRIMARY, PREFERRED);"

# 12. 注册节点(在 Datanode 上执行)
psql -p 15432 -c "CREATE GTM NODE gtm_master WITH (HOST='127.0.0.1', PORT=6666, PRIMARY);"
psql -p 15432 -c "CREATE NODE coord1 WITH (TYPE='coordinator', HOST='127.0.0.1', PORT=5432);"

# 13. 重载连接池
psql -p 5432 -c "SELECT pgxc_pool_reload();"

# 14. 设置默认节点组
psql -p 5432 -c "CREATE NODE GROUP default_group WITH (dn001);"

在这里插入图片描述

任何一个步骤出错,整个集群就无法启动。

而且:

  • 编译需要 30-60 分钟
  • 2G 服务器内存不够
  • 依赖包问题频繁
  • 端口冲突、权限问题
  • 配置文件复杂

2.2 我遇到的坑

坑 1:编译内存不够

错误信息:

c++: internal compiler error: Killed (program cc1plus)

原因:2G 内存不够编译 OpenTenBase

解决:增加 swap 或者用更大的服务器

[占位符:编译报错截图]

坑 2:依赖包找不到

错误信息:

E: Unable to locate package libcli11-dev
E: Package libpqxx-dev is not available

原因:不同 Ubuntu 版本包名不同

解决:

apt-get install -y libcli11-dev || apt-get install -y libcli-dev
apt-get install -y libpqxx-dev || apt-get install -y libpqxx-7-dev

坑 3:GTM 初始化失败

错误信息:

initgtm: could not initialize GTM

原因:端口冲突或权限问题

解决:检查端口占用,确保用户权限

坑 4:节点注册失败

错误信息:

ERROR: can not get master gtm info from pgxc_node

原因:OpenTenBase v5.0 改用 pgxc_node 表注册节点

解决:

CREATE GTM NODE gtm_master WITH (HOST='127.0.0.1', PORT=6666, PRIMARY);
CREATE NODE coord1 WITH (TYPE='coordinator', HOST='127.0.0.1', PORT=5432, FORWARD=6669);

坑 5:Docker 网络问题

错误信息:

could not connect to GTM: Connection refused

原因:Docker 容器网络隔离

解决:使用 Docker network 和 hostname 连接

坑 6:128-bit atomics 链接错误

错误信息:

undefined reference to `__sync_val_compare_and_swap_16'

原因:Debian 11/12 的 libatomic 不支持 128-bit atomics

解决:使用 __atomic_compare_exchange_n 替代


三、我的解决方案:Docker 一键部署

3.1 整体思路

不做源码编译,直接用 .deb 包 + Docker Compose。

在这里插入图片描述

3.2 环境准备

服务器要求:

  • CPU: 1 核+
  • 内存: 2GB+
  • 磁盘: 10GB+
  • 操作系统: Ubuntu 20.04/22.04/24.04, Debian 11/12

安装 Docker:

# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# 安装 Docker Compose
sudo apt-get install docker-compose-plugin


四、Dockerfile 编写

4.1 运行时镜像

FROM ubuntu:24.04

# 非交互模式
ENV DEBIAN_FRONTEND=noninteractive

# 安装依赖
RUN apt-get update && apt-get install -y \\
libreadline8 \\
libssl3 \\
libpam0g \\
libxml2 \\
libldap-2.5-0 \\
libossp-uuid16 \\
uuid-runtime \\
libcurl4 \\
liblz4-1 \\
libzstd1 \\
libssh2-1 \\
&& rm -rf /var/lib/apt/lists/*

# 创建用户
RUN useradd -r -m -s /bin/bash opentenbase

# 复制 .deb 包
COPY opentenbase_5.0-1ubuntu1_all.deb /tmp/
COPY opentenbase-server_5.0-1ubuntu1_amd64.deb /tmp/
COPY opentenbase-client_5.0-1ubuntu1_amd64.deb /tmp/
COPY opentenbase-contrib_5.0-1ubuntu1_amd64.deb /tmp/

# 安装包
RUN dpkg -i /tmp/*.deb || apt-get install -f -y

# 设置工作目录
WORKDIR /usr/lib/opentenbase

# 暴露端口
EXPOSE 5432 6666 15432 6667 6668 6669 6670

# 默认用户
USER opentenbase

# 默认命令
CMD ["postgres"]

**[占位符:Dockerfile 完整文件截图]**

4.2 构建镜像

# 1. 下载 .deb 包
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase_5.0-1ubuntu1_all.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase-server_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase-client_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase-contrib_5.0-1ubuntu1_amd64.deb

# 2. 构建镜像
docker build -t opentenbase/opentenbase:5.0 .

# 3. 查看镜像
docker images | grep opentenbase

**[占位符:构建过程截图]**# 1. 下载 .deb 包
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase_5.0-1ubuntu1_all.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase-server_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase-client_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase-contrib_5.0-1ubuntu1_amd64.deb

2. 构建镜像

docker build -t opentenbase/opentenbase:5.0 .

3. 查看镜像

docker images | grep opentenbase

![**\\[占位符:构建过程截图\\]**](https://i-blog.csdnimg.cn/direct/a89eb52d7a3c45bcb06b92a035fd543f.png)

## 五、deb 包制作

### 5.1 包结构

OpenTenBase 分成 6 个包:

| 包名 | 描述 | 大小 |
|——|——|——|
| `opentenbase` | 元包 | 2.2 KB |
| `opentenbase-server` | 服务器端 | 6.2 MB |
| `opentenbase-client` | 客户端工具 | 737 KB |
| `opentenbase-contrib` | 扩展组件 | 1.4 MB |
| `libopentenbase-dev` | 开发库 | 1.5 MB |
| `opentenbase-doc` | 文档 | 2.6 MB |

### 5.2 一键安装脚本

```bash
curl -sLO https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/install.sh
sudo bash install.sh

5.3 测试验证数据库启动

初始化集群

# 初始化 GTM + Coordinator + Datanode
opentenbase-ctl init

启动集群

# 启动所有节点
opentenbase-ctl start

检查状态

# 查看集群状态
opentenbase-ctl status

连接数据库

# 通过 psql 连接
opentenbase-psql -h 127.0.0.1 -p 5432 -U opentenbase -d postgres

停止集群

# 停止所有节点
opentenbase-ctl stop

在这里插入图片描述
在这里插入图片描述

好了,这个时候就可以使用OpenTenBase数据库了

以上内容是软件包的一键部署教程,如果是需要开发数据库的佬友,目前我们这边也是支持Docker Compose 一键集群部署:

六、docker compose 集群

此处是数据库开发者参考内容

6.1 docker-compose.yml

version: '3.8'

services:
gtm:
image: opentenbase/opentenbase:5.0
container_name: opentenbasegtm
hostname: gtm
ports:
"6666:6666"
volumes:
gtm_data:/var/lib/opentenbase/gtm
gtm_log:/var/log/opentenbase
environment:
NODE_TYPE=gtm
GTM_PORT=6666
NODE_NAME=gtm_master
networks:
opentenbasenet
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/gtm
su – opentenbase -c '/usr/lib/opentenbase/bin/initgtm -Z gtm -D /var/lib/opentenbase/gtm'
su – opentenbase -c '/usr/lib/opentenbase/bin/gtm_ctl -D /var/lib/opentenbase/gtm -l /var/log/opentenbase/gtm.log start'
"

healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 6666"]
interval: 10s
timeout: 5s
retries: 5

coordinator:
image: opentenbase/opentenbase:5.0
container_name: opentenbasecoordinator
hostname: coordinator
ports:
"5432:5432"
volumes:
coord_data:/var/lib/opentenbase/coordinator
coord_log:/var/log/opentenbase
environment:
NODE_TYPE=coordinator
COORD_PORT=5432
GTM_HOST=gtm
GTM_PORT=6666
NODE_NAME=coord1
networks:
opentenbasenet
depends_on:
gtm:
condition: service_healthy
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/coordinator
su – opentenbase -c '/usr/lib/opentenbase/bin/initdb -D /var/lib/opentenbase/coordinator –nodename=coord1 –nodetype=coordinator –master_gtm_nodename=gtm_master –master_gtm_ip=gtm –master_gtm_port=6666 -E UTF8 -U opentenbase'
sed -i 's/port = 5432/port = 5432/' /var/lib/opentenbase/coordinator/postgresql.conf
su – opentenbase -c '/usr/lib/opentenbase/bin/pg_ctl -D /var/lib/opentenbase/coordinator -l /var/log/opentenbase/coord.log start'
sleep 5
su – opentenbase -c '/usr/lib/opentenbase/bin/psql -p 5432 -c \\"CREATE GTM NODE gtm_master WITH (HOST=\\\\'gtm\\\\', PORT=6666, PRIMARY);\\"'
su – opentenbase -c '/usr/lib/opentenbase/bin/psql -p 5432 -c \\"CREATE NODE coord1 WITH (TYPE=\\\\'coordinator\\\\', HOST=\\\\'coordinator\\\\', PORT=5432, FORWARD=6669);\\"'
tail -f /var/log/opentenbase/coord.log
"

healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 5432"]
interval: 10s
timeout: 5s
retries: 5

dn1:
image: opentenbase/opentenbase:5.0
container_name: opentenbasedn1
hostname: dn1
ports:
"15432:15432"
volumes:
dn1_data:/var/lib/opentenbase/dn1
dn1_log:/var/log/opentenbase
environment:
NODE_TYPE=datanode
DN_PORT=15432
GTM_HOST=gtm
GTM_PORT=6666
NODE_NAME=dn001
networks:
opentenbasenet
depends_on:
coordinator:
condition: service_healthy
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/dn1
su – opentenbase -c '/usr/lib/opentenbase/bin/initdb -D /var/lib/opentenbase/dn1 –nodename=dn001 –nodetype=datanode –master_gtm_nodename=gtm_master –master_gtm_ip=gtm –master_gtm_port=6666 -E UTF8 -U opentenbase'
su – opentenbase -c '/usr/lib/opentenbase/bin/pg_ctl -D /var/lib/opentenbase/dn1 -l /var/log/opentenbase/dn1.log start'
sleep 5
su – opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \\"CREATE NODE dn001 WITH (TYPE=\\\\'datanode\\\\', HOST=\\\\'dn1\\\\', PORT=15432, FORWARD=6670, PRIMARY, PREFERRED);\\"'
su – opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \\"SELECT pgxc_pool_reload();\\"'
tail -f /var/log/opentenbase/dn1.log
"

healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 15432"]
interval: 10s
timeout: 5s
retries: 5

dn2:
image: opentenbase/opentenbase:5.0
container_name: opentenbasedn2
hostname: dn2
ports:
"15433:15433"
volumes:
dn2_data:/var/lib/opentenbase/dn2
dn2_log:/var/log/opentenbase
environment:
NODE_TYPE=datanode
DN_PORT=15433
GTM_HOST=gtm
GTM_PORT=6666
NODE_NAME=dn002
networks:
opentenbasenet
depends_on:
coordinator:
condition: service_healthy
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/dn2
su – opentenbase -c '/usr/lib/opentenbase/bin/initdb -D /var/lib/opentenbase/dn2 –nodename=dn002 –nodetype=datanode –master_gtm_nodename=gtm_master –master_gtm_ip=gtm –master_gtm_port=6666 -E UTF8 -U opentenbase'
su – opentenbase -c '/usr/lib/opentenbase/bin/pg_ctl -D /var/lib/opentenbase/dn2 -l /var/log/opentenbase/dn2.log start'
sleep 5
su – opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \\"CREATE NODE dn002 WITH (TYPE=\\\\'datanode\\\\', HOST=\\\\'dn2\\\\', PORT=15433, FORWARD=6671);\\"'
su – opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \\"SELECT pgxc_pool_reload();\\"'
tail -f /var/log/opentenbase/dn2.log
"

healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 15433"]
interval: 10s
timeout: 5s
retries: 5

networks:
opentenbase-net:
driver: bridge

volumes:
gtm_data:
gtm_log:
coord_data:
coord_log:
dn1_data:
dn1_log:
dn2_data:
dn2_log:

6.2 启动集群

# 1. 启动集群
docker compose up -d

# 2. 查看状态
docker compose ps

输出应该是这样:

NAME COMMAND SERVICE STATUS
opentenbase-coordinator "bash -c install -d …" coordinator running
opentenbase-dn1 "bash -c install -d …" dn1 running
opentenbase-dn2 "bash -c install -d …" dn2 running
opentenbase-gtm "bash -c install -d …" gtm running


七、初始化数据库

7.1 等待服务就绪(docker)

# 查看日志
docker compose logs -f coordinator

# 等待看到类似这样的输出:
# LOG: database system is ready to accept connections

7.2 连接数据库(docker)

# 连接 Coordinator
docker exec -it opentenbase-coordinator \\
/usr/lib/opentenbase/bin/psql -U opentenbase -d postgres


八、常见报错解决

8.1 容器启动失败

错误:

Error: Container failed to start

解决:

# 查看日志
docker compose logs coordinator

# 常见原因:
# 1. GTM 没启动成功
# 2. 端口冲突
# 3. 内存不够

# 检查端口
sudo netstat -tlnp | grep -E '(5432|6666|15432)'

# 检查内存
free -h

8.2 节点注册失败

错误:

ERROR: can not get master gtm info from pgxc_node

解决:

# 检查 GTM 是否运行
docker compose exec gtm pg_isready -p 6666

# 检查节点是否注册
docker compose exec coordinator \\
/usr/lib/opentenbase/bin/psql -c "SELECT * FROM pgxc_node;"

# 手动注册(如果需要)
docker compose exec coordinator \\
/usr/lib/opentenbase/bin/psql -c "CREATE GTM NODE gtm_master WITH (HOST='gtm', PORT=6666, PRIMARY);"

8.3 连接被拒绝

错误:

psql: error: could not connect to server: Connection refused

解决:

# 检查服务是否运行
docker compose ps

# 检查端口是否监听
sudo netstat -tlnp | grep 5432

# 检查防火墙
sudo ufw status

# 检查日志
docker compose logs coordinator

8.4 Docker 内存不够

错误:

OOMKilled

解决:

# docker-compose.yml 添加内存限制
services:
coordinator:
mem_limit: 1g
shm_size: 512mb

dn1:
mem_limit: 1g
shm_size: 512mb


九、SQL 测试

9.1 基础测试

— 查看版本
SELECT version();

— 查看节点
SELECT * FROM pgxc_node;

— 创建测试表
CREATE TABLE test (id INT, name TEXT);

— 插入数据
INSERT INTO test VALUES (1, 'Alice'), (2, 'Bob');

— 查询数据
SELECT * FROM test;

— 聚合查询
SELECT COUNT(*), AVG(id) FROM test;

— 分布式查询
SELECT * FROM test WHERE id = 1;

9.2 性能测试

— 创建大表
CREATE TABLE big_test (id INT, data TEXT);

— 插入 10 万条数据
INSERT INTO big_test
SELECT generate_series(1, 100000), 'test data';

— 查询性能
EXPLAIN ANALYZE SELECT COUNT(*) FROM big_test;

— 分布式查询性能
EXPLAIN ANALYZE SELECT * FROM big_test WHERE id = 50000;


十、最终效果

10.1 资源占用

测试环境:

  • CPU: 1 核
  • 内存: 2GB
  • 磁盘: 20GB

结果:

节点CPU内存磁盘
GTM < 5% 50MB 20MB
Coordinator 10-20% 100MB 50MB
Datanode 1 10-20% 100MB 50MB
Datanode 2 10-20% 100MB 50MB
总计 35-65% 350MB 170MB

2G 服务器完全够用!

10.2 部署时间对比

方式时间步骤
官方编译 2-3 小时 14 步
我的方案 5 分钟 1 命令

10.3 最终效果

# 一键启动
docker compose up -d

# 查看集群状态
docker compose ps

# 连接数据库
docker exec -it opentenbase-coordinator \\
/usr/lib/opentenbase/bin/psql -U opentenbase -d postgres

# 运行 SQL
SELECT * FROM pgxc_node;

[占位符:最终效果完整截图]


十一、总结

通过 Docker Compose,我们实现了:

  • ✅ 部署时间从 2-3 小时 → 5 分钟
  • ✅ 配置步骤从 14 步 → 1 命令
  • ✅ 2G 服务器就能跑通
  • ✅ 一键启动完整集群(GTM + CN + 2 DN)
  • ✅ 资源占用仅 350MB
  • 核心优势:

    • 不需要编译
    • 不需要手动配置
    • 自动处理节点注册
    • 自动处理依赖
    • 环境隔离,易于清理

    适用场景:

    • 学习研究 OpenTenBase
    • 快速搭建测试环境
    • CI/CD 集成测试
    • 演示和教学

    项目地址:

    • GitHub: https://github.com/muzimu217/OpenTenBase-deb
    • Docker Hub: https://hub.docker.com/r/opentenbase/opentenbase

    如果你也在折腾 OpenTenBase,希望这个方案能帮你节省时间!

    有问题欢迎留言交流~


    作者:折腾 OpenTenBase 的学生
    项目地址:

    • GitHub: https://github.com/muzimu217/OpenTenBase-deb
    • Docker Hub: https://hub.docker.com/r/opentenbase/opentenbase
    赞(0)
    未经允许不得转载:171主机测评 » 我用 2G 服务器跑通了 OpenTenBase!分布式数据库 Docker 化部署全过程
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址