kunpengcompute / kunpengcompute.github.io

Kunpeng Tech Blog: https://kunpengcompute.github.io/
Apache License 2.0
17 stars 5 forks source link

基于Bucardo建立PostgreSQL 主主混合集群(X86 + ARM)部署 #50

Open bzhaoopenstack opened 4 years ago

bzhaoopenstack commented 4 years ago

作者: bzhaoopenstack(https://github.com/bzhaoopenstack)

PG在混步跨硬件平台的首次試水,此次基於Bucardo部署PG跨硬件平台集群。

基于Bucardo建立PostgreSQL 主主混合集群部署


PostgreSQL集群化部署,有很多种主流方案,包括Bucardo, repmgr, pglogical等方式,并且大致分为两种方式:

  1. 基于物理复制的集群,其中主从节点耦合紧密,在这种情况下,它们应该运行在相同的PG版本和相同的硬件平台上。在这种方案下,需要依赖底层硬件功能,并且跨硬件平台的复制可能存在问题,需要验证。
  2. 基于非物理复制的集群(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虚机

# 更新库
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依赖

# 取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服务创建单独用户,后续切换为新建用户执行

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源码,编译并安装。

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端口的端口转发。

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 :

listen_addresses = '*'

修改PG 配置文件 pg_hba.conf:

# 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服务:

# 导入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

然后,创建同步用户和要同步的表,注意要同步的对象一定要有主键,如果没有主键,在创建同步队列时会失败。虽然可以通过一些办法强行对无主键表进行同步,但会在同步发生数据冲突时产生不可预测的错误。

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需要自行指定:

$ ./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虚机),要保证双向的话,反过来再做一次即可。

# 添加源数据库
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

bucardo start

下面是其他的管理命令:

# 停止同步
bucardo stop

# 暂停 / 恢复某一组同步
bucardo pause/resume sync51to52

# 查看同步状态
bucardo status

这样,所有对两个节点上dbuser用户的public.t1表的操作都会双向同步到各自运行的PG数据库服务上。


3 总结

对于外围同步的Bucardo来部署不同硬件平台的PG服务,是能够运行的。但是在部署过程中,发现不管X86还是ARM平台在运行Bucardo的相关测试用例时都会有失败,包括社区上游,可见该社区似乎不太活跃,导致正常的CI测试都无人问津。这个部署过程有以下几个看法:

  1. PG数据库本身的底层复制模块需要支持跨平台。
  2. 对于DEMO或者性能要求不高的场景可以使用Bucardo,对于性能要求较高的仍然不足。
  3. 对于跨平台的问题跟踪还需要继续深究,同样缺少真实的商用试点样板,这样才能给PG用户足够的信心。