1.OpenTenBase源码编译:
使用系统:阿里云ECS云主机,g7,4核16GiB,Ubuntu 22.04
选择的依据:由于本机的配置不高,选择使用阿里云ECS云主机进行实践,最开始选择的是c6,2核4GiB,但是在编译中发现CPU使用将近100%,出现了OOM(out of memory)问题。尝试使用增加Swap空间的方式解决这个问题,但所选的4GiB过小,结果很不理想。因此,重新选择g7,4核16GiB,实现源码编译。
安装依赖:
sudo apt-get update
sudo apt-get install -y gcc make libreadline-dev zlib1g-dev libssl-dev libossp-uuid-dev bison flex git
创建目录、opentenbase用户和对应密码(如果要部署集群,则所有主机都需要执行):
mkdir /data
useradd -d /data/opentenbase -s /bin/bash -m opentenbase
passwd opentenbase # 例如可以设置密码为:123
切换到已经创建的opentenbase用户,通过git clone获取OpenTenBase源码:
su opentenbase
git clone https://github.com/OpenTenBase/OpenTenBase
对源码进行编译:
#首先声明一下变量SOURCECODE_PATH和INSTALL_PATH
export SOURCECODE_PATH=/data/opentenbase/OpenTenBase
export INSTALL_PATH=/data/opentenbase/install
#进入源码目录
cd ${SOURCECODE_PATH}
rm -rf ${INSTALL_PATH}/opentenbase_bin_v2.0
#赋予配置脚本执行权限
chmod +x configure*
#配置编译选项
./configure --prefix=${INSTALL_PATH}/opentenbase_bin_v2.0 --enable-user-switch --with-openssl --with-ossp-uuid CFLAGS=-g
#编译安装软件
make clean
make -sj 4
make install
#赋予执行权限
chmod +x contrib/pgxc_ctl/make_signature
编译contrib目录下的工具
cd contrib
make -sj 4
make install
到此源码编译结束。
2.OpenTenBase集群部署:
根据操作指南,可以发现两台主机可以实现有着1GTM主,1GTM备,2CN,2DN主,2DN备的集群,该集群有着最小容灾能力。在此基础上,想要实现2CN+3DN的集群,第一种方式是添加一个主机用做数据节点,第二种方式是扩充主机数量,使用5台主机,其中两台主机分别为CN,另外三台分别为DN。本次使用的是第一种方式。
集群规划:
节点名称 |
IP |
数据目录 |
GTM master |
172.27.47.131 |
/data/opentenbase/data/gtm |
GTM slave |
172.27.47.132 |
/data/opentenbase/data/gtm |
CN1 |
172.27.47.131 |
/data/opentenbase/data/coord |
CN2 |
172.27.47.132 |
/data/opentenbase/data/coord |
DN1 master |
172.27.47.131 |
/data/opentenbase/data/dn001 |
DN1 slave |
172.27.47.132 |
/data/opentenbase/data/dn001 |
DN2 master |
172.27.47.132 |
/data/opentenbase/data/dn002 |
DN2 slave |
172.27.47.133 |
/data/opentenbase/data/dn002 |
DN3 master |
172.27.47.133 |
/data/opentenbase/data/dn003 |
DN3 slave |
172.27.47.131 |
/data/opentenbase/data/dn003 |
集群部署图:
禁用SELinux和防火墙(可选):
这里使用的是Ubuntu 22.04,因为Ubuntu默认不安装SELinux,而是使用AppArmor,因此可以跳过这一步。
机器之间的ssh互信配置(所有的主机都需要执行):
这里和指南上有一点不一样,在操作过程中发现,如果把已经编译过OpenTenBase源码的主机作为集群中的一个节点,在使用pgxc_ctl进行deploy all时会出现错误,这种错误会使得后面的初始化失败。考虑到已经编译过OpenTenBase源码的主机也可以单纯只做一个发送二进制包的主机,不需要在opentenbase集群中充当节点,因此这里相当于是有4个主机,IP分别为:172.27.47.130,172.27.47.131,172.27.47.132,172.27.47.133。每个主机都需要实现一次下面的步骤。
su opentenbase
ssh-keygen -t rsa
# 第一次连接会提示确认主机的真实性,必须输入yes,后面输入目标主机的opentenbase用户密码
ssh-copy-id -i ~/.ssh/id_rsa.pub opentenbase@172.27.47.131
ssh-copy-id -i ~/.ssh/id_rsa.pub opentenbase@172.27.47.132
ssh-copy-id -i ~/.ssh/id_rsa.pub opentenbase@172.27.47.133
成功后会出现类似下图的提示:
配置环境变量(所有的主机都要执行):
vim ~/.bashrc
# 下面是在.bashrc中需要添加的内容
export OPENTENBASE_HOME=/data/opentenbase/install/opentenbase_bin_v2.0
export PATH=$OPENTENBASE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$OPENTENBASE_HOME/lib:${LD_LIBRARY_PATH}
export LC_ALL=C
#使.bashrc生效
source ~/.bashrc
初始化pgxc_ctl.conf文件
在指南中有单节点和双节点配置,现在部署的是2CN+3DN,因此在双节点配置上进行修改。
mkdir /data/opentenbase/pgxc_ctl
cd /data/opentenbase/pgxc_ctl
vim pgxc_ctl.conf
#!/bin/bash
# Double Node Config
# IP地址根据自己的主机IP地址进行修改
IP_1=172.27.47.131
IP_2=172.27.47.132
IP_3=172.27.47.133
pgxcInstallDir=/data/opentenbase/install/opentenbase_bin_v2.0
pgxcOwner=opentenbase
defaultDatabase=postgres
pgxcUser=$pgxcOwner
tmpDir=/tmp
localTmpDir=$tmpDir
configBackup=n
configBackupHost=pgxc-linker
configBackupDir=$HOME/pgxc
configBackupFile=pgxc_ctl.bak
#---- GTM ----------
gtmName=gtm
gtmMasterServer=$IP_1
gtmMasterPort=50001
gtmMasterDir=/data/opentenbase/data/gtm
gtmExtraConfig=none
gtmMasterSpecificExtraConfig=none
gtmSlave=y
gtmSlaveServer=$IP_2
gtmSlavePort=50001
gtmSlaveDir=/data/opentenbase/data/gtm
gtmSlaveSpecificExtraConfig=none
#---- Coordinators -------
coordMasterDir=/data/opentenbase/data/coord
coordArchLogDir=/data/opentenbase/data/coord_archlog
coordNames=(cn001 cn002 )
coordPorts=(30004 30004 )
poolerPorts=(31110 31110 )
coordPgHbaEntries=(0.0.0.0/0)
coordMasterServers=($IP_1 $IP_2)
coordMasterDirs=($coordMasterDir $coordMasterDir)
coordMaxWALsernder=2
coordMaxWALSenders=($coordMaxWALsernder $coordMaxWALsernder )
coordSlave=n
coordSlaveSync=n
coordArchLogDirs=($coordArchLogDir $coordArchLogDir)
coordExtraConfig=coordExtraConfig
cat > $coordExtraConfig <<EOF
#================================================
# Added to all the coordinator postgresql.conf
# Original: $coordExtraConfig
include_if_exists = '/data/opentenbase/global/global_opentenbase.conf'
wal_level = replica
wal_keep_segments = 256
max_wal_senders = 4
archive_mode = on
archive_timeout = 1800
archive_command = 'echo 0'
log_truncate_on_rotation = on
log_filename = 'postgresql-%M.log'
log_rotation_age = 4h
log_rotation_size = 100MB
hot_standby = on
wal_sender_timeout = 30min
wal_receiver_timeout = 30min
shared_buffers = 1024MB
max_pool_size = 2000
log_statement = 'ddl'
log_destination = 'csvlog'
logging_collector = on
log_directory = 'pg_log'
listen_addresses = '*'
max_connections = 2000
EOF
coordSpecificExtraConfig=(none none)
coordExtraPgHba=coordExtraPgHba
cat > $coordExtraPgHba <<EOF
local all all trust
host all all 0.0.0.0/0 trust
host replication all 0.0.0.0/0 trust
host all all ::1/128 trust
host replication all ::1/128 trust
EOF
coordSpecificExtraPgHba=(none none)
coordAdditionalSlaves=n
cad1_Sync=n
# 因为现在是三个DN,所以类比于原来的内容,添加第三个DN的配置
#---- Datanodes ---------------------
dn1MstrDir=/data/opentenbase/data/dn001
dn2MstrDir=/data/opentenbase/data/dn002
dn3MstrDir=/data/opentenbase/data/dn003
dn1SlvDir=/data/opentenbase/data/dn001
dn2SlvDir=/data/opentenbase/data/dn002
dn3SlvDir=/data/opentenbase/data/dn003
dn1ALDir=/data/opentenbase/data/datanode_archlog
dn2ALDir=/data/opentenbase/data/datanode_archlog
dn3ALDir=/data/opentenbase/data/datanode_archlog
primaryDatanode=dn001
datanodeNames=(dn001 dn002 dn003)
datanodePorts=(40004 40004 40004)
datanodePoolerPorts=(41110 41110 41110)
datanodePgHbaEntries=(0.0.0.0/0)
datanodeMasterServers=($IP_1 $IP_2 $IP_3)
datanodeMasterDirs=($dn1MstrDir $dn2MstrDir $dn3MstrDir)
dnWALSndr=4
datanodeMaxWALSenders=($dnWALSndr $dnWALSndr $dnWALSndr)
datanodeSlave=y
datanodeSlaveServers=($IP_2 $IP_3 $IP_1)
datanodeSlavePorts=(50004 54004 58004)
datanodeSlavePoolerPorts=(51110 51110 51110)
datanodeSlaveSync=n
datanodeSlaveDirs=($dn1SlvDir $dn2SlvDir $dn3SlvDir)
datanodeArchLogDirs=($dn1ALDir/dn001 $dn2ALDir/dn002 $dn3ALDir/dn003)
datanodeExtraConfig=datanodeExtraConfig
cat > $datanodeExtraConfig <<EOF
#================================================
# Added to all the coordinator postgresql.conf
# Original: $datanodeExtraConfig
include_if_exists = '/data/opentenbase/global/global_opentenbase.conf'
listen_addresses = '*'
wal_level = replica
wal_keep_segments = 256
max_wal_senders = 4
archive_mode = on
archive_timeout = 1800
archive_command = 'echo 0'
log_directory = 'pg_log'
logging_collector = on
log_truncate_on_rotation = on
log_filename = 'postgresql-%M.log'
log_rotation_age = 4h
log_rotation_size = 100MB
hot_standby = on
wal_sender_timeout = 30min
wal_receiver_timeout = 30min
shared_buffers = 1024MB
max_connections = 4000
max_pool_size = 4000
log_statement = 'ddl'
log_destination = 'csvlog'
wal_buffers = 1GB
EOF
# 这里需要和DN的个数保持一致,所以添加一个none
datanodeSpecificExtraConfig=(none none none)
datanodeExtraPgHba=datanodeExtraPgHba
cat > $datanodeExtraPgHba <<EOF
local all all trust
host all all 0.0.0.0/0 trust
host replication all 0.0.0.0/0 trust
host all all ::1/128 trust
host replication all ::1/128 trust
EOF
# 这里需要和DN的个数保持一致,所以添加一个none
datanodeSpecificExtraPgHba=(none none none)
datanodeAdditionalSlaves=n
walArchive=n
分发二进制包:
pgxc_ctl
# 在出现PGXC后,输入指令deploy all
PGXC deploy all
结果如下图所示:
执行init all命令:
这里需要注意,在初始化时会出现一个错误为:pg_ctl命令找不到。最开始以为是环境变量配置没有生效,但是在检查之后,发现确实已经在所有集群的主机上都进行了opentenbase用户环境配置,并且已经生效。最后的解决方案是在每一台主机上切回root用户,并在/etc/environment中配置PATH。
# 同样的,分发成功后,会继续出现PGXC,输入命令init all
PGXC init all
初始化成功,会出现如下内容:
如果初始化失败,可以在/pgxc_ctl/pgxc_log目录下查看错误日志,根据错误原因,修改pgxc_ctl.conf配置文件,之后执行命令clean all删除已经初始化的文件,并再次执行init all进行初始化。
查看集群状态:
# 同样是在PGXC后面输入
PGXC monitor all
输出结果如下图所示:
进行集群访问:
# 首先退出pgxc_ctl
PGXC exit
# 连接集群,包括IP,Port,database和user,连接的可以是任何一个CN节点
psql -h 172.27.47.131 -p 30004 -d postgres -U opentenbase
启动集群和停止集群:
# 启动集群
PGXC start all
#停止集群
PGXC stop all
3.OpenTenBase基础操作实践:
在进行基础操作实践,也就是创建不同的表以及进行增删改查之前,需要先创建default_group和sharding表。值得注意的是,有一种表的类型为单表,在创建单表的时候,不能使用位于default_group中的dn节点,如果使用,则会创建失败。猜测失败的原因是可能是为了严格区分分布式表和单表,便于数据分布的清晰性和管理便利性,且位于default_group中的节点可能已经用于分布式存储,不能简单转换为单表存储。好在现在是由三个DN节点,因此可以将前两个DN节点作为default_group,第三个DN节点作为单独的single_group,用于创建单表。
postgres=# create default node group default_group with (dn001,dn002);
CREATE NODE GROUP
postgres=# create sharding group to group default_group;
CREATE SHARDING GROUP
postgres=# create node group single_group with (dn003);
CREATE NODE GROUP
创建四种表(使用\d+ 跟上表名可以查看创建的表的结构):
创建分布式表:
分片表中以主键f1作为分布键,分布键选择后不可以修改字段类型、字段长度和字段值。
创建分布+分区表:
同样是以主键f1作为分布键,根据f1的值判断存储在哪一个数据节点上。
在某个数据节点上,根据f2的值进行分区存储。当前f2的类型为timestamp,其中begin表示开始的时间,step表示分区的跨度,partition表示初始创建分区的个数。
创建复制表:
复制表是在每一个节点中都保存全量的数据,不适合大数据量的数据表。
创建单表:
只存在于某一个结点上的数据表
实现增删改查操作(在SQL命令前加上explain,可以查看执行计划):
INSERT:
可以直接插入多条记录
UPDATE:
在执行更新操作时,对于分布式表来说,基于分布键条件更新会比非分布键更新更高效。因为基于分布键更新,CN节点可以快速解析update语句,根据分布键f1的值确定数据节点dn001,且一般使用主键作为分布键,此时可以在dn001上根据主键索引,快速定位要更新的行。而非分布键更新,不能确定到底在哪一个数据节点进行操作,需要CN将更新操作推给所有数据节点,各个节点独立执行更新操作,并且没有索引,继而需要执行全表扫描。
SELECT:
查询和更新一样,对于分布式表,也是基于分布键查询优于非分布键查询。
DELETE: