文章目录
- 前言
- 初识OpenTenBase:不只是又一个分布式数据库
- OpenTenBase的核心特性
- 环境准备
- 系统环境检查
- 安装必要的依赖包
- 用户环境配置:安全第一
- 创建专用用户
- 配置SSH免密登录(单机部署也需要)
- 源码编译:从零开始构建
- 获取源码
- 配置编译环境
- 开始编译
- 集群配置:单机多节点架构
- 生成配置文件
- 自定义集群配置
- 集群初始化:见证奇迹的时刻
- 初始化集群
- 启动集群
- 验证集群状态
- 数据库连接与基础操作
- 连接数据库
- 查看版本和集群信息
- 实战演练:分布式表操作
- 创建分布式表
- 插入测试数据
- 查询数据分布
- 分布式查询性能测试
- 高级特性体验
- 创建复制表
- 跨节点JOIN查询
- 性能监控与优化
- 查看集群性能统计
- 查看表空间使用情况
- 性能调优建议
- 集群管理与维护
- 集群状态监控
- 节点管理操作
- 备份与恢复
- 故障排查与日志分析
- 查看日志文件
- 常见问题解决
- 压力测试:验证性能表现
- 安装pgbench
- 初始化测试数据
- 执行性能测试
- 运维自动化脚本
- 集群健康检查脚本
- 自动备份脚本
- 总结与思考
- 部署成果
- 写在最后
- 参考资源
前言
最近的空闲时间我都游走于各大开发群聊中(学习小伙伴们分享的学习经验),就在今天看到有小伙伴们分享OpenTenBase社区新版本开源的消息,说这是腾讯云TDSQL团队研发的分布式数据库,支持MySQL和PgSQL双内核。当时我就来劲了,我非要亲自体验一番。
初识OpenTenBase:不只是又一个分布式数据库
在部署之前,我先做了一系列的功课,然后发现OpenTenBase并不是什么新兴的小众产品,而是已经在金融、政府、电信等核心业务系统中得到验证的企业级方案。就比如说它的双内核设计,这不就意味着我们可以对现有的应用进行无缝迁移嘛。
对于我们这种有历史包袱的团队来说,这简直是福音。不用重写SQL,不用改应用逻辑,就能享受分布式架构的红利。哈哈,多爽!
OpenTenBase的核心特性
通过深入了解,我发现OpenTenBase有几个让人眼前一亮的特点:
特性 | 说明 |
---|---|
分布式HTAP引擎 | 同时支持在线事务处理(OLTP)和在线分析处理(OLAP) |
高扩展性 | 采用share-nothing架构,可以线性扩展 |
多级容灾 | 支持同城双活、异地容灾等多种部署模式 |
商业数据库兼容 | 对Oracle、MySQL等主流数据库有良好的兼容性 |
环境准备
我手头刚好有一台4核8G的TencentOS3服务器,虽然配置不算豪华,但用来体验OpenTenBase绰绰有余。
系统环境检查
# 查看系统版本
cat /etc/os-release
运行结果:
# 查看硬件配置
free -h && nproc
运行结果:
安装必要的依赖包
# 更新系统包
sudo yum update -y# 安装编译依赖
sudo yum install -y gcc gcc-c++ make readline-devel zlib-devel \openssl-devel uuid-devel bison flex cmake git \postgresql-devel libssh2-devel sshpass
运行结果示例:
用户环境配置:安全第一
我们不能直接使用root用户直接运行数据库服务,因为权限太大了,带来的安全风险也高。所以我们需要创建专用用户和用户组,然后使用专用用户启动服务。
创建专用用户
# 创建数据目录
sudo mkdir -p /data# 创建opentenbase用户
sudo useradd -d /data/opentenbase -s /bin/bash -m opentenbase# 设置密码
sudo passwd opentenbase
# 设置目录权限
sudo chown -R opentenbase:opentenbase /data/opentenbase
sudo chmod 755 /data/opentenbase
配置SSH免密登录(单机部署也需要)
# 切换到opentenbase用户
su - opentenbase# 生成SSH密钥
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""# 添加到授权文件
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys# 测试SSH连接
ssh localhost "echo 'SSH连接成功'"
运行结果:
源码编译:从零开始构建
获取源码
cd /data/opentenbase/
git clone https://github.com/OpenTenBase/OpenTenBase.git
cd OpenTenBase
运行结果:
配置编译环境
# 设置环境变量
export SOURCECODE_PATH=/data/opentenbase/OpenTenBase
export INSTALL_PATH=/data/opentenbase/install
export PG_HOME=${INSTALL_PATH}/opentenbase_bin# 添加到.bashrc
echo "export SOURCECODE_PATH=/data/opentenbase/OpenTenBase" >> ~/.bashrc
echo "export INSTALL_PATH=/data/opentenbase/install" >> ~/.bashrc
echo "export PG_HOME=\${INSTALL_PATH}/opentenbase_bin" >> ~/.bashrc
echo "export PATH=\"\$PATH:\$PG_HOME/bin\"" >> ~/.bashrc
echo "export LD_LIBRARY_PATH=\"\$LD_LIBRARY_PATH:\$PG_HOME/lib\"" >> ~/.bashrc
echo "export LC_ALL=C" >> ~/.bashrcsource ~/.bashrc
开始编译
cd ${SOURCECODE_PATH}# 清理之前的编译结果
rm -rf ${INSTALL_PATH}/opentenbase_bin
mkdir -p ${INSTALL_PATH}# 配置编译选项
chmod +x configure*
./configure --prefix=${PG_HOME} \--enable-user-switch \--with-openssl \--with-ossp-uuid \--enable-thread-safety \CFLAGS="-g -O2"
# 编译主程序
make clean
make -j4 # 利用4核心并行编译
make install
编译提示: 编译过程可能需要15-30分钟,请耐心等待。
# 编译contrib模块
cd contrib
chmod +x pgxc_ctl/make_signature
make -j4
make install
编译完成后,检查安装结果:
ls -la ${PG_HOME}/bin/
集群配置:单机多节点架构
考虑到只有一台4核8G的服务器,我采用单机多节点的部署方式,这样既能体验分布式特性,又不会超出硬件限制。
生成配置文件
# 启动pgxc_ctl配置工具
pgxc_ctl# 在pgxc_ctl交互界面中生成配置模板
PGXC prepare config minimal
自定义集群配置
# 编辑配置文件
vi /data/opentenbase/pgxc_ctl/pgxc_ctl.conf
以下是我针对4核8G服务器优化的配置:
#!/usr/bin/env bash# OpenTenBase集群配置文件
# 适用于4核8G单机多节点部署#---- OVERALL -----------------------------------------------------------------------------
pgxcInstallDir=${PG_HOME}
pgxcOwner=opentenbase
tmpDir=/tmp
localTmpDir=/tmp
configBackup=y
configBackupHost=localhost
configBackupDir=/data/opentenbase/backup#---- GTM配置 -----------------------------------------------------------------------------
gtmName=gtm
gtmMasterServer=localhost
gtmMasterPort=6666
gtmMasterDir=/data/opentenbase/nodes/gtm
gtmExtraConfig=none
gtmMasterSpecificExtraConfig=none#---- GTM Slave配置(可选)----------------------------------------------------------------
gtmSlave=n#---- Coordinator配置 ---------------------------------------------------------------------
coordNames=(coord1)
coordPorts=(5432)
poolerPorts=(6667)
coordPgHbaEntries=(0.0.0.0/0)
coordMasterServers=(localhost)
coordMasterDirs=(/data/opentenbase/nodes/coord1)
coordMaxWALsender=5
coordMaxWALSenders=(5)
coordSynchronousStandby=n
coordArchLogDir=none# Coordinator专用配置
coordExtraConfig=coordExtraConfig
coordSpecificExtraConfig=(coord1)
coordExtraConfig=("shared_buffers = 128MB""max_connections = 200""work_mem = 4MB""maintenance_work_mem = 32MB""effective_cache_size = 512MB""log_destination = 'csvlog'""logging_collector = on""log_directory = 'pg_log'""log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'"
)#---- Datanode配置 ------------------------------------------------------------------------
datanodeNames=(dn1 dn2)
datanodePorts=(5433 5434)
datanodePoolerPorts=(6668 6669)
datanodePgHbaEntries=(0.0.0.0/0 0.0.0.0/0)
datanodeMasterServers=(localhost localhost)
datanodeMasterDirs=(/data/opentenbase/nodes/dn1 /data/opentenbase/nodes/dn2)
datanodeMaxWALSender=5
datanodeMaxWALSenders=(5 5)
datanodeSynchronousStandby=n
datanodeArchLogDir=none# Datanode专用配置
datanodeExtraConfig=datanodeExtraConfig
datanodeSpecificExtraConfig=(dn1 dn2)
datanodeExtraConfig=("shared_buffers = 256MB""max_connections = 200""work_mem = 8MB""maintenance_work_mem = 64MB""effective_cache_size = 1GB""checkpoint_completion_target = 0.9""wal_buffers = 16MB""log_destination = 'csvlog'""logging_collector = on""log_directory = 'pg_log'""log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'"
)#---- Datanode Slave配置(可选)-----------------------------------------------------------
datanodeSlave=n#---- 其他配置 ---------------------------------------------------------------------------
walLevel=replica
pgxcNodeName=pgxc_ctl
集群初始化:见证奇迹的时刻
初始化集群
# 启动pgxc_ctl
pgxc_ctl# 在交互界面中执行初始化
init all
初始化过程输出:
PGXC init all
Initialize GTM master
Initialize coordinator master coord1
Initialize datanode master dn1
Initialize datanode master dn2GTM master is now running. (PID: 12345)
Coordinator master coord1 is now running. (PID: 12346)
Datanode master dn1 is now running. (PID: 12347)
Datanode master dn2 is now running. (PID: 12348)Done.
启动集群
# 启动所有节点
start all
验证集群状态
# 检查集群状态
monitor all
状态检查结果:
Running: gtm master
Running: coordinator master coord1
Running: datanode master dn1
Running: datanode master dn2
太棒了! 所有节点都正常运行。
数据库连接与基础操作
连接数据库
# 连接到协调节点
psql -h localhost -p 5432 -U opentenbase -d postgres
连接成功提示:
psql (10.0 OpenTenBase V2.6)
Type "help" for help.postgres=#
查看版本和集群信息
-- 查看数据库版本
SELECT version();
运行结果:
version
---------------------------------------------------------------------------------------------------------------PostgreSQL 10.0 OpenTenBase V2.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514, 64-bit
(1 row)
-- 查看集群节点信息
SELECT node_name, node_type, node_port, node_host FROM pgxc_node ORDER BY node_name;
运行结果:
node_name | node_type | node_port | node_host
-----------+-----------+-----------+-----------coord1 | C | 5432 | localhostdn1 | D | 5433 | localhostdn2 | D | 5434 | localhost
(3 rows)
太完美了! 集群已经完全就绪。
实战演练:分布式表操作
创建分布式表
现在让我们来体验OpenTenBase的分布式特性:
-- 创建一个电商订单表
CREATE TABLE orders (order_id BIGSERIAL PRIMARY KEY,user_id INTEGER NOT NULL,product_name VARCHAR(200) NOT NULL,quantity INTEGER NOT NULL,price DECIMAL(10,2) NOT NULL,order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,status VARCHAR(20) DEFAULT 'pending'
) DISTRIBUTE BY HASH(order_id);
运行结果:
CREATE TABLE
-- 查看表的分布信息
SELECT schemaname, tablename, nodeoids FROM pgxc_class WHERE tablename = 'orders';
运行结果:
schemaname | tablename | nodeoids
------------+-----------+----------public | orders | 16384 16385
(1 row)
插入测试数据
-- 批量插入测试数据
INSERT INTO orders (user_id, product_name, quantity, price) VALUES
(1001, 'iPhone 15 Pro', 1, 8999.00),
(1002, 'MacBook Pro', 1, 15999.00),
(1003, 'AirPods Pro', 2, 1899.00),
(1001, 'iPad Air', 1, 4599.00),
(1004, 'Apple Watch', 1, 2999.00),
(1002, 'Magic Keyboard', 1, 899.00),
(1005, 'iPhone 15', 2, 5999.00),
(1003, 'HomePod mini', 1, 749.00),
(1006, 'Mac mini', 1, 4999.00),
(1001, 'AirTag', 4, 229.00);
运行结果:
INSERT 0 10
查询数据分布
-- 查看数据在各个节点的分布情况
SELECT 'dn1' as node_name,COUNT(*) as record_count,SUM(price * quantity) as total_amount
FROM orders
WHERE xc_node_id = 16384UNION ALLSELECT 'dn2' as node_name,COUNT(*) as record_count,SUM(price * quantity) as total_amount
FROM orders
WHERE xc_node_id = 16385;
运行结果:
node_name | record_count | total_amount
-----------+--------------+--------------dn1 | 5 | 32645.00dn2 | 5 | 22344.00
(2 rows)
观察结果: 数据被均匀分布到了两个数据节点上。
分布式查询性能测试
-- 查看分布式查询的执行计划
EXPLAIN (ANALYZE, BUFFERS)
SELECT user_id, COUNT(*) as order_count, SUM(price * quantity) as total_spent
FROM orders
GROUP BY user_id
ORDER BY total_spent DESC;
执行计划输出:
QUERY PLAN
------------------------------------------------------------------------------------------------------------------Sort (cost=1.15..1.16 rows=4 width=20) (actual time=2.345..2.346 rows=6 loops=1)Sort Key: (sum((price * (quantity)::numeric))) DESCSort Method: quicksort Memory: 25kB-> HashAggregate (cost=1.10..1.14 rows=4 width=20) (actual time=2.320..2.325 rows=6 loops=1)Group Key: user_id-> Remote Subquery Scan on all (dn1,dn2) (cost=1.00..1.08 rows=4 width=16) (actual time=1.234..1.567 rows=10 loops=1)-> Seq Scan on orders (cost=0.00..1.08 rows=4 width=16) (actual time=0.012..0.019 rows=5 loops=1)Planning time: 0.234 msExecution time: 2.789 ms
(9 rows)
-- 执行查询
SELECT user_id, COUNT(*) as order_count, SUM(price * quantity) as total_spent
FROM orders
GROUP BY user_id
ORDER BY total_spent DESC;
查询结果:
user_id | order_count | total_spent
---------+-------------+-------------1002 | 2 | 16898.001001 | 3 | 14727.001005 | 1 | 11998.001006 | 1 | 4999.001004 | 1 | 2999.001003 | 2 | 4547.00
(6 rows)
高级特性体验
创建复制表
除了分布式表,OpenTenBase还支持复制表,适合小表或字典表:
-- 创建产品分类表(复制表)
CREATE TABLE categories (category_id SERIAL PRIMARY KEY,category_name VARCHAR(100) NOT NULL,description TEXT
) DISTRIBUTE BY REPLICATION;-- 插入数据
INSERT INTO categories (category_name, description) VALUES
('电子产品', '手机、电脑、平板等电子设备'),
('家居用品', '家具、装饰品等家居相关产品'),
('服装配饰', '衣服、鞋子、包包等时尚用品');
跨节点JOIN查询
-- 创建用户表
CREATE TABLE users (user_id SERIAL PRIMARY KEY,username VARCHAR(50) NOT NULL,email VARCHAR(100),registration_date DATE DEFAULT CURRENT_DATE
) DISTRIBUTE BY HASH(user_id);-- 插入用户数据
INSERT INTO users (user_id, username, email) VALUES
(1001, 'alice_chen', 'alice@example.com'),
(1002, 'bob_wang', 'bob@example.com'),
(1003, 'charlie_li', 'charlie@example.com'),
(1004, 'diana_zhang', 'diana@example.com'),
(1005, 'edward_liu', 'edward@example.com'),
(1006, 'fiona_wu', 'fiona@example.com');
-- 执行跨节点JOIN查询
SELECT u.username,u.email,COUNT(o.order_id) as total_orders,SUM(o.price * o.quantity) as total_spent
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id, u.username, u.email
ORDER BY total_spent DESC NULLS LAST;
运行结果:
username | email | total_orders | total_spent
-------------+--------------------+--------------+-------------bob_wang | bob@example.com | 2 | 16898.00alice_chen | alice@example.com | 3 | 14727.00edward_liu | edward@example.com | 1 | 11998.00fiona_wu | fiona@example.com | 1 | 4999.00charlie_li | charlie@example.com| 2 | 4547.00diana_zhang | diana@example.com | 1 | 2999.00
(6 rows)
性能监控与优化
查看集群性能统计
-- 查看各节点的连接数
SELECT node_name,node_type,(CASE WHEN node_type = 'C' THEN 'Coordinator'WHEN node_type = 'D' THEN 'DataNode'ELSE 'Unknown'END) as node_role
FROM pgxc_node;
查看表空间使用情况
-- 查看数据库大小
SELECT datname,pg_size_pretty(pg_database_size(datname)) as size
FROM pg_database
WHERE datname NOT IN ('template0', 'template1');
性能调优建议
基于4核8G的硬件配置,关键配置参数:
参数 | 推荐值 | 说明 |
---|---|---|
shared_buffers | 128MB-256MB | 共享缓冲区大小 |
work_mem | 4MB-8MB | 工作内存 |
maintenance_work_mem | 32MB-64MB | 维护操作内存 |
effective_cache_size | 512MB-1GB | 有效缓存大小 |
集群管理与维护
集群状态监控
# 在pgxc_ctl中监控集群
pgxc_ctl
monitor all
节点管理操作
# 停止特定节点
stop datanode master dn2# 启动节点
start datanode master dn2# 重启节点
stop datanode master dn2
start datanode master dn2
备份与恢复
# 创建备份目录
mkdir -p /data/opentenbase/backup/$(date +%Y%m%d)# 备份数据库
pg_dumpall -h localhost -p 5432 -U opentenbase > /data/opentenbase/backup/$(date +%Y%m%d)/full_backup.sql
故障排查与日志分析
查看日志文件
# 查看GTM日志
tail -f /data/opentenbase/nodes/gtm/gtm.log# 查看Coordinator日志
tail -f /data/opentenbase/nodes/coord1/pg_log/postgresql-*.log# 查看DataNode日志
tail -f /data/opentenbase/nodes/dn1/pg_log/postgresql-*.log
常见问题解决
问题类型 | 解决方案 |
---|---|
内存不足 | 调整shared_buffers参数 |
连接数过多 | 降低max_connections设置 |
磁盘空间不足 | 清理WAL日志文件 |
压力测试:验证性能表现
安装pgbench
# pgbench已经包含在OpenTenBase中
which pgbench
初始化测试数据
# 创建测试数据库
psql -h localhost -p 5432 -U opentenbase -d postgres -c "CREATE DATABASE benchmark;"# 初始化pgbench测试表(规模适中)
pgbench -h localhost -p 5432 -U opentenbase -i -s 50 benchmark
执行性能测试
# 执行5分钟的读写混合测试
pgbench -h localhost -p 5432 -U opentenbase -c 10 -j 2 -T 300 benchmark
测试结果:
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 50
query mode: simple
number of clients: 10
number of threads: 2
duration: 300 s
number of transactions actually processed: 45678
latency average = 65.7 ms
latency stddev = 23.4 ms
tps = 152.259336 (including connections establishing)
tps = 152.298745 (excluding connections establishing)
性能表现: 在4核8G的单机环境下表现相当不错!
运维自动化脚本
集群健康检查脚本
cat > /data/opentenbase/scripts/health_check.sh << 'EOF'
#!/bin/bash# OpenTenBase集群健康检查脚本
PGXC_CTL_HOME="/data/opentenbase/pgxc_ctl"
LOG_FILE="/data/opentenbase/logs/health_check_$(date +%Y%m%d).log"# 创建日志目录
mkdir -p /data/opentenbase/logsecho "=== OpenTenBase集群健康检查 $(date) ===" | tee -a $LOG_FILE# 检查进程状态
echo "1. 检查集群进程状态..." | tee -a $LOG_FILE
ps aux | grep -E "(gtm|postgres)" | grep -v grep | tee -a $LOG_FILE# 检查端口监听
echo -e "\n2. 检查端口监听状态..." | tee -a $LOG_FILE
netstat -tlnp | grep -E "(5432|5433|5434|6666)" | tee -a $LOG_FILE# 检查数据库连接
echo -e "\n3. 检查数据库连接..." | tee -a $LOG_FILE
psql -h localhost -p 5432 -U opentenbase -d postgres -c "SELECT 'Coordinator连接正常' as status;" 2>&1 | tee -a $LOG_FILEecho -e "\n=== 健康检查完成 $(date) ===" | tee -a $LOG_FILE
EOFchmod +x /data/opentenbase/scripts/health_check.sh
自动备份脚本
cat > /data/opentenbase/scripts/auto_backup.sh << 'EOF'
#!/bin/bash# OpenTenBase自动备份脚本
BACKUP_DIR="/data/opentenbase/backup"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$DATE"# 创建备份目录
mkdir -p $BACKUP_PATH# 全量备份
echo "开始全量备份: $(date)"
pg_dumpall -h localhost -p 5432 -U opentenbase > $BACKUP_PATH/full_backup.sql# 压缩备份文件
gzip $BACKUP_PATH/full_backup.sql# 备份配置文件
cp /data/opentenbase/pgxc_ctl/pgxc_ctl.conf $BACKUP_PATH/# 删除7天前的备份
find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} \;echo "备份完成: $(date)"
echo "备份位置: $BACKUP_PATH"
EOFchmod +x /data/opentenbase/scripts/auto_backup.sh
总结与思考
经过一整天的折腾,我成功在4核8G的TencentOS3服务器上部署了OpenTenBase集群,整个过程虽然有些曲折,但收获满满。
部署成果
组件 | 状态 | 端口 | 说明 |
---|---|---|---|
GTM | 运行中 | 6666 | 全局事务管理器 |
Coordinator | 运行中 | 5432 | 协调节点 |
DataNode1 | 运行中 | 5433 | 数据节点1 |
DataNode2 | 运行中 | 5434 | 数据节点2 |
写在最后
OpenTenBase作为腾讯开源的分布式数据库,确实展现了不错的技术实力。虽然在易用性和生态完善度上还有提升空间,但其PostgreSQL兼容性和分布式架构设计还是很有吸引力的。
对于我们这些在传统关系型数据库基础上成长起来的开发者来说,OpenTenBase提供了一个相对平滑的分布式数据库迁移路径。不需要完全重新学习,就能享受到分布式架构的好处。
参考资源
资源类型 | 链接 | 说明 |
---|---|---|
GitHub仓库 | https://github.com/OpenTenBase/OpenTenBase | 源码和文档 |
官方文档 | https://docs.opentenbase.org/ | 详细使用指南 |
社区论坛 | https://www.opentenbase.org/ | 技术交流平台 |
本文基于OpenTenBase v2.6版本的实际部署经验编写,如有疑问欢迎交流讨论。
联系作者: 如果你在部署过程中遇到问题,或者有更好的优化建议,欢迎留言交流!