作者: bzhaoopenstack(https://github.com/bzhaoopenstack )
PG在混步跨硬件平台的首次試水,此次基於Bucardo部署PG跨硬件平台集群。
基于Bucardo建立PostgreSQL 主主混合集群部署
PostgreSQL集群化部署,有很多种主流方案,包括Bucardo, repmgr, pglogical等方式,并且大致分为两种方式:
基于物理复制的集群,其中主从节点耦合紧密,在这种情况下,它们应该运行在相同的PG版本和相同的硬件平台上。在这种方案下,需要依赖底层硬件功能,并且跨硬件平台的复制可能存在问题,需要验证。
基于非物理复制的集群(binlog复制等等),主备节点之间没有耦合关系,所以这种部署方式往往性能比较差,因为其不使用底层PG的复制功能,而是使用外围的形式进行复制,比如基于语句或触发器的复制。另外,由于缺少硬件耦合,PG服务器不能提供数据一致性保证,因此部分部署工具必须确保没有数据丢失。
那么Bucardo在这里是属于第二种部署形式,而repmgr是使用第一种部署形式,因为它使用了PG内建的复制支持。
Bucardo是一个异步的PostgreSQL复制系统,支持主主、主从方案。它是一款能在PG中实现双向同步的软件,可以实现更多的源数据库(主数据库)以及更多的目标数据库(备份数据库)之间的同步,还可以复制到其他类型的目标数据库,包括Mysql, MariaDB, Oracle, SQLite, MongoDB和Redis等。基于 BSD 的开源协议。本文中,主要是描述主主模式的搭建过程。
Bucardo是异步同步,因此实现多主方案时,只能做到数据的最终一致,Bucardo的同步通过触发器来记录变化,并利用PG中的Notify
消息事件通知机制实现高效同步,并且同步相当灵活,可以只同步数据库中选定的几张表或者几列。
由于资源限制,我们当前仅有一台X86虚机,有一台装有Docker的ARM虚机。考虑这种形式:
ARM: 运行在Docker环境中,用容器起PG,并尝试连向对端PG
X86: 运行在比较常规的虚机中,PG服务直接起在虚机中,尝试连向对端PG
那么我们现有的测试环境为:
ARM PG container:
HostOS version: ubuntu 1804
ARCH: aarch64
Docker image: ubuntu 1804 latest in Dockerhub
Host Intranet IP: 192.168.0.111
Host Public IP: 1.1.1.1
Container Intranet IP: 172.17.0.111
X86 VM:
Host OS version: ubuntu 1804
ARCH: X86
Host Intranet IP: 192.168.0.222
Host Public IP: 2.2.2.2
PG version : PG-10 稳定版
Barcudo version: Master Branch
Perl version: v5.26.1
注意: 这里PG version之所以选用稳定版,是因为os库里有现成的PG包提供下载,为了简化部署流程,我们选用apt来安装。
1. 安装 在ARM容器和X86虚机
1 2 3 4 5 6 7 8 9 10 11 # 更新库 sudo apt-get update # 安装依赖库 sudo apt-get install zlib1g zlib1g-dev bzip2 libbz2-dev readline-common libreadline-dev bison libgmp-dev libmpfr-dev libmpc-dev -y # 安装工具软件 sudo apt-get -q install -y --no-install-recommends build-essential autoconf automake libtool cmake zlib1g-dev pkg-config libssl-dev libssl1.0.0 libsasl2-dev bats curl sudo git wget # Barcudo 依赖的perl安装 sudo apt-get install perl -y
安装PG及bucardo依赖
1 2 3 4 5 6 7 8 # 取PG版本为10 PGVERSION=10 # 安装PG server/client 以及perl依赖 sudo apt-get install -y postgresql-${PGVERSION} postgresql-client-${PGVERSION} postgresql-${PGVERSION}-pgtap postgresql-server-dev-${PGVERSION} postgresql-server-dev-all postgresql-plperl-${PGVERSION} debhelper fakeroot libdbd-pg-perl libtap-parser-sourcehandler-pgtap-perl # 导入PATH export PATH=/usr/lib/postgresql/${PGVERSION}/bin:${PATH}
为PG服务创建单独用户,后续切换为新建用户执行
1 2 sudo useradd -m -d /home/pgtest -s /bin/bash pgtest && echo pgtest:pgtest | chpasswd && adduser pgtest sudo sudo echo "pgtest ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
用新建用户下载bucardo源码,编译并安装。
1 2 3 4 5 6 7 8 9 10 11 12 13 export PATH=/usr/lib/postgresql/${PGVERSION}/bin:${PATH} git clone https://github.com/bucardo/bucardo cd bucardo/ # 安装缺少的Perl modules sudo cpan install CGI sudo cpan install DBIx::Safe # 编译安装bucardo perl Makefile.PL export USER=pgtest BUCARDO_LOG_ERROR_CONTEXT=1 PATH=$PATH:/usr/lib/postgresql/${PGVERSION}/bin make test sudo make install
另外,bucardo共依赖perl模块为:
DBI
DBIx::Safe
DBD::Pg
Test::Simple
boolean
可根据缺少的模块进行安装。
此时,所有的安转工作就绪。开始双主配置。
2. 配置 对于双方都是虚机,都有公网IP,且ARM使用的是docker环境,所以对于HostOS上的配置,需要在云平台或者防火墙放通PG的TCP:5432默认端口。
在ARM容器HostOS上,添加一条对于容器内部5432端口的端口转发。
1 2 3 4 iptables -t nat -A PREROUTING -d 192.168.0.111/32 -p tcp -m tcp --dport 5432 -j DNAT --to-destination 172.17.0.111:5432 # 由于docker在Forward链默认规则是DROP,我们需要针对放通 iptables -A FORWARD -d 172.17.0.111/32 -p tcp -m tcp --dport 5432 -j ACCEPT
此时,ARM虚机上的5432端口会转发给运行在其上的PG容器,对应的容器出公网的流量会走Docker配置的MASQUERADE SNAT出去。OK,ARM hostOS 网络配置完毕。
同样对于X86,由于PG是直接运行在上面,没有再加任何虚拟化层,所以只要保证云平台安全组或者防火墙放通即可。
下面我们先配置PG,让它能够暴露在公网。
修改PG 配置文件postgresql.conf :
修改PG 配置文件 pg_hba.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust # Allow replication connections from localhost, by a user with the # replication privilege. local replication all trust host replication all 127.0.0.1/32 trust host replication all ::1/128 trust host replication all 1.1.1.1/32 trust host replication all 2.2.2.2/32 trust host all all 1.1.1.1/32 md5 host all all 2.2.2.2/32 md5
其他PG配置保持默认即可。配置完成后就可以启动PG服务:
1 2 3 4 5 6 7 8 9 10 # 导入PG到环境变量 PGVERSION=10 export PATH=/usr/lib/postgresql/${PGVERSION}/bin:${PATH} # 初始化PG数据库服务,注意PG_DATA_DIR 和 PG_LOG_DIR变量需要自行设置,保证当前运行用户有权限访问 initdb --pgdata=$PG_DATA_DIR --encoding=UTF8 pg_ctl -D $PG_DATA_DIR -l $PG_LOG_DIR start # 创建测试数据库 testdb createdb -O pgtest testdb
然后,创建同步用户和要同步的表,注意要同步的对象一定要有主键 ,如果没有主键,在创建同步队列时会失败。虽然可以通过一些办法强行对无主键表进行同步,但会在同步发生数据冲突时产生不可预测的错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 pgtest@pg-x86:~/bucardo$ psql -d testdb psql (10.14 (Ubuntu 10.14-0ubuntu0.18.04.1)) Type "help" for help. testdb=# create user dbuser with password '123456'; CREATE ROLE testdb=# create table t1 (col1 numeric NOT NULL, col2 numeric, CONSTRAINT pk_1 PRIMARY KEY (col1)); CREATE TABLE testdb=# \q pgtest@pg-x86:~/bucardo$ psql -U dbuser -d testdb psql (10.14 (Ubuntu 10.14-0ubuntu0.18.04.1)) Type "help" for help. testdb=> \q
OK,开始在两个节点(ARM容器和X86虚机)上部署Bucardo辅助对象,其中PG_PID_DIR需要自行指定:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $ ./bucardo install Enter a number to change it, P to proceed, or Q to quit: 3 Change the user to: greenplum Changed user to: greenplum Current connection settings: 1. Host: <none> 2. Port: 5432 3. User: pgtest 4. Database: bucardo 5. PID directory: $PG_PID_DIR Enter a number to change it, P to proceed, or Q to quit: P Creating superuser 'bucardo' Attempting to create and populate the bucardo database and schema Database creation is complete Updated configuration setting "piddir" Installation is now complete.
现在可以利用bucardo配置双向同步,以下展示的仅为单向(ARM容器 to X86虚机),要保证双向的话,反过来再做一次即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 添加源数据库 bucardo add database pg51 dbname=testdb port 5432 host=127.0.0.1 user=dbuser pass=123456 # 添加目标数据库 bucardo add database pg52 dbname=testdb port 5432 host=2.2.2.2 user=dbuser pass=123456 # 添加数据库组 bucardo add dbgroup grp1 pg51:source pg52:target # 添加表集群, 注意:同步的表需要有主键 bucardo add table public.t1 herd=herd_test # 添加同步信息, conflict_strategy为解决冲突的方式共有6种方式,source,target,skip,random,latest,abort bucardo add sync sync51to52 herd=herd_test dbs=grp1 conflict_strategy=latest
然后按着相同的配置反向在X86虚机 to ARM容器再做一次配置。这样所有的同步配置就完成了。
最后两个节点启动bucardo
下面是其他的管理命令:
1 2 3 4 5 6 7 8 # 停止同步 bucardo stop # 暂停 / 恢复某一组同步 bucardo pause/resume sync51to52 # 查看同步状态 bucardo status
这样,所有对两个节点上dbuser用户的public.t1表的操作都会双向同步到各自运行的PG数据库服务上。
3 总结 对于外围同步的Bucardo来部署不同硬件平台的PG服务,是能够运行的。但是在部署过程中,发现不管X86还是ARM平台在运行Bucardo的相关测试用例时都会有失败,包括社区上游,可见该社区似乎不太活跃,导致正常的CI测试都无人问津。这个部署过程有以下几个看法:
PG数据库本身的底层复制模块需要支持跨平台。
对于DEMO或者性能要求不高的场景可以使用Bucardo,对于性能要求较高的仍然不足。
对于跨平台的问题跟踪还需要继续深究,同样缺少真实的商用试点样板,这样才能给PG用户足够的信心。