TBase是腾讯自研的分布式数据库,可以轻松应对亿级数据的存储、分析和查询。集高扩展性、高SQL兼容度、完整的分布式事务支持、多级容灾能力以及多维度资源隔离等能力于一身,采用无共享的集群架构,适用于PB级海量 HTAP 场景。
如果大家熟悉PG的发布与订阅的话,那么对于本文理解应该很有帮助。接下来我们来看下分布式数据库TBase如何做多个实例或多个库之间的数据同步多活的。 在业务场景中我们经常可能会用到某一部分数据,但数据源头又是来自多个库的入库数据,比如我希望南区的A实例的某个库或表的数据能够汇集到北区B实例的某个库或者某个表中,只要A库中的数据的增删改的变化,能够即时的同步到B库,但B库的操作对不会影响A库。接下来我们就动手来看下TBase 的数据多活发布订阅。
环境:
TBase实例2个
TBase1,发布端
cn:172.21.16.28 端口:11345
dn1:172.21.32.2 11000 dn2:172.21.32.2 11002
TBase2,订阅端
cn:172.21.32.2 端口:11379
dn1:172.21.16.28 dn2:172.21.16.41
第一步:TBase1 创建要发布的数据库,或数据表
连接cn进行相关数据库和表的创建
psql -h172.21.16.28 -p11345 -U tbase -d postgres
postgres=# create database testdb;
CREATE DATABASE
postgres=#
postgres=# c testdb
You are now connected to database "testdb" as user "tbase".
testdb=#
testdb=# create table test_tab(id int primary key,name varchar(20));
CREATE TABLE
testdb=# insert into test_tab select generate_series(1,100),'TEST'||generate_series(1,100);
INSERT 0 100
testdb=#
testdb=# select * from test_tab limit 5;
id | name
---- -------
1 | TEST1
2 | TEST2
3 | TEST3
4 | TEST4
5 | TEST5
(5 rows)
testdb=#
第二步:针对TBase1通过OSS平台进行test_tab表的发布出去。
如下:
注意:发布数据表需要注意格式,格式为:数据库名.schema名字.表名字
在发布完成之后,我们可以连接到TBase1的任何一个DN数据节点上去查看发布信息如下:
连接dn001
tbase@VM-16-28-centos ~$ psql -h172.21.32.2 -p11000 -Utbase -dpostgres
psql (PostgreSQL 10.0 TBase V2)
Type "help" for help.
postgres=# select * from pg_publication;
pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete
--------- ---------- -------------- ----------- ----------- -----------
(0 rows)
为什么我们在postgres库中,使用tbase用户是看不到的?为什么呢?因为我们发布的是testdb库的test_tab表。
连接testdb数据库,再次进行查询,表的发布信息如下:
postgres=# c testdb
You are now connected to database "testdb" as user "tbase".
testdb=# select * from pg_publication;
代码语言:txt复制 pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete
-------------------------- ---------- -------------- ----------- ----------- -----------
p_testdb_public_test_tab | 10 | f | t | t | t
(1 row)
第三步:我们将TBase2 订阅端的CN的IP地址加入到TBase1的DN数据节点的访问白名单中。
注意:每个TBase1的DN节点都需要加入。
我们为了本次方便演示,直接通过OSS平台将TBase2的CN加入TBase1的DN节点的白名单中进行配置,如下:
注意:DN001和DN002都需要做配置,因为TBase为分布式架构,每个DN节点只存放对应表中的一部分分片数据,并不是全表记录。
第三四步:TBase2 实例进行数据订阅配置
首先进行表结构的创建,建表语句和TBase1的语句相同。连接TBase2的CN节点进行配置即可。
psql -h172.21.32.2 -p11379 -Utbase -dpostgres
psql (10.6, server 10.0 TBase V2)
Type "help" for help.
postgres=# create table test_tab(id int primary key,name varchar(20));
CREATE TABLE
postgres=#
postgres=# d test_tab
代码语言:txt复制 Table "public.test_tab"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-------- ----------------------- ----------- ---------- --------- ---------- -------------- -------------
id | integer | | not null | | plain | |
name | character varying(20) | | | | extended | |
Indexes:
代码语言:txt复制"test_tab_pkey" PRIMARY KEY, btree (id)
postgres=#
订阅TBase1节点1的数据信息如下:
tbase1_node1为订阅的名字,可以自定义
注意p_testdb_public_test_tab 为TBase1 发布出来的名字
WITH后边内容可以按需编写,默认也可以省略。
postgres=# CREATE TBASE SUBSCRIPTION tbase1_node1
CONNECTION 'host = 172.21.32.2 port = 11000 user = tbase dbname = testdb'
PUBLICATION p_testdb_public_test_tab WITH
(connect=true, enabled=true, create_slot=true, copy_data=true, synchronous_commit=on,
ignore_pk_conflict = true, parallel_number= 2 );
NOTICE: created replication slot "tbase1_node1_2_0" on publishe
NOTICE: created replication slot "tbase1_node1_2_1" on publishe
CREATE TBASE SUBSCRIPTION
postgres=#
订阅TBase1节点2的数据信息如下:
postgres=# CREATE TBASE SUBSCRIPTION tbase1_node2
CONNECTION 'host = 172.21.32.2 port = 11002 user = tbase dbname = testdb'
PUBLICATION p_testdb_public_test_tab WITH
(connect=true, enabled=true, create_slot=true, copy_data=true, synchronous_commit=on,
ignore_pk_conflict = true, parallel_number= 2 );
NOTICE: created replication slot "tbase1_node2_2_0" on publishe
NOTICE: created replication slot "tbase1_node2_2_1" on publishe
CREATE TBASE SUBSCRIPTION
postgres=#
postgres=# select * from pg_subscription;
subdbid | subname | subowner | subenabled | subconninfo | su
bslotname | subsynccommit | subpublications
--------- ------------------ ---------- ------------ -------------------------------------------------------------- -----
------------- --------------- ----------------------------
13327 | tbase1_node1_2_0 | 10 | t | host = 172.21.32.2 port = 11000 user = tbase dbname = testdb | tbas
e1_node1_2_0 | on | {p_testdb_public_test_tab}
13327 | tbase1_node1_2_1 | 10 | t | host = 172.21.32.2 port = 11000 user = tbase dbname = testdb | tbas
e1_node1_2_1 | on | {p_testdb_public_test_tab}
13327 | tbase1_node2_2_0 | 10 | t | host = 172.21.32.2 port = 11002 user = tbase dbname = testdb | tbas
e1_node2_2_0 | on | {p_testdb_public_test_tab}
13327 | tbase1_node2_2_1 | 10 | t | host = 172.21.32.2 port = 11002 user = tbase dbname = testdb | tbas
e1_node2_2_1 | on | {p_testdb_public_test_tab}
(10 rows)
postgres=#
查看TBase2订阅的TBase1所发布的test_tab的表数据是否同步过来。
postgres=# select count(*)from test_tab;
count
100
(1 row)
postgres=#
postgres=# select * from test_tab limit 5;
id | name
---- -------
1 | TEST1
2 | TEST2
3 | TEST3
4 | TEST4
5 | TEST5
(5 rows)
postgres=#
接下来我们来看下订阅端和发布段的DML操作是双向还是单项同步的?
在TBase1中进行DML操作,查看TBase2数据是否有变化。
psql连接TBase1 的CN节点
psql -h172.21.16.28 -p11345 -Utbase -dpostgres
postgres=# c testdb
You are now connected to database "testdb" as user "tbase".
testdb=#
=======================================delete操作============================================
testdb=# delete from test_tab where id>4;
DELETE 96
testdb=#
查看TBase2数据是否有变化,如下:数据已同步
testdb=# select * from test_tab;
id | name
---- -------
1 | TEST1
2 | TEST2
3 | TEST3
4 | TEST4
(4 rows)
===============================TBase1做insert操作==============================================
postgres=# insert into test_tab select 666,'小明';
INSERT 0 1
postgres=# insert into test_tab select 888,'小红';
INSERT 0 1
查看TBase2数据是否有变化,如下:数据已同步
postgres=# select * from test_tab;
id | name
----- -------
1 | TEST1
2 | TEST2
3 | TEST3
4 | TEST4
666 | 小明
888 | 小红
(6 rows)
postgres=#
===============================我们反向在TBase2中做delete操作=========================
TBase2
psql -h172.21.32.2 -p11379 -Utbase -dpostgres
postgres=# delete from test_tab;
DELETE 6
postgres=# select * from test_tab;
id | name
---- ------
(0 rows)
查看TBase1数据是否有变化,如下:数据无更新,
postgres=# select * from test_tab;
id | name
----- -------
1 | TEST1
2 | TEST2
3 | TEST3
4 | TEST4
666 | 小明
888 | 小红
(6 rows)
结论:无论是在TBase中,还是在PG中,其实逻辑的订阅发布都是单向的,即发布端在做DML操作时,数据变化会更新同步到订阅端,但订阅做DML操作,发布端是不受影响的。
其实说到这里大家可能会说,很多单向数据同步不都能做到,MySQL的MS,Oracle DG/OGG,以及SQL Server always on等不都能解决,但是跨平台的跨版本的除去OGG上述就显得不是那么好用了 。上述所说的都是传统的集中式数据的同步。那么分布式数据库呢?在进行不同版本之间的数据同步,或者多套库之间如何做数据的同步和复制呢?本次的目的就是解决大家这个疑惑的。希望大家看完能比对传统集中式pg的逻辑订阅发布方式有所收货。