【Tbase开源版测评】基于PostgreSQL的国产开源数据库初体验

2020-08-17 10:09:46 浏览数 (2)

之前本人主要使用过oracle,mysql,greenplum,tdsql,tidb等数据库。头一次接触基于PostgreSQL的国产开源数据库,如果如下内容有错误的地方,还希望各位朋友批评指正。

当前主流RDBMS数据库架构

1.副本集,通过日志传输实现复制。

1.png1.png

主要代表MySQL Replication,Oracle Dataguard,Postgresql xlog,DB2 HADR。

由于近些年摩尔定律失效通过scale up来提升单台设备的性能来解决日益增长的计算存储需求已经是力不从心了,该架构适合业务量较稳定,负载变化不大的场景。该架构的好处是架构简单易于维护。

2.共享存储。

2.png2.png

主要代表有Oracle rac,多机并行,高可用,高吞吐量,但也存在资源争用,性能受限于存储iops的问题,

3.利用分布式存储实现计算存储分离

3.png3.png

主要代表产品,aws aurora,阿里云 Polardb,腾讯云 CynosDB.弹性伸缩,兼容Mysql/Postgresql,但是该架构一样存在着容量上限,无法进行无限扩容,(目前主流分布式存储池都有容量上限),且该架构也会遇到于计算节点的性能瓶颈问题。

4.Shard Nothing。

4.png4.png

主要代表产品,早期的cobar,mycat,现在的腾讯云的TBASE、TDSQL,pivotal grerenplum

这种架构的特点对应用透明,可以非常快捷的伸缩,支持分布式事务,可实现冷热数据的分离。

5.Shard Nothing。

5.png5.png

主要代表产品,PingCap tidb(兼容mysql),CockroachDB(兼容Postgresql),

这种架构的特点对应用透明,可以非常快捷的伸缩,支持分布式事务,每个节点负载相对平均。

TBASE环境准备

IP

角色

端口

10.252.132.17

GTM Primary

50001

10.252.132.9

GTM Replica

50001

10.252.132.11

CN1

30001

10.252.132.10

CN2

30001

10.252.132.15

DN1 Primary

40001

10.252.132.2

DN1 Replica

40001

10.252.132.11

DN2 Primary

40001

10.252.132.10

DN2 Replica

40001

10.252.132.7

DN3 Primary

40001

10.252.132.8

DN3 Replica

40001

架构图如下

6.png6.png

Coordinator:协调节点(简称CN)

业务访问入口,负责数据的分发和查询规划,多个节点位置对等,每个节点都提供相同的数据库视图;在功能上CN上只存储系统的全局元数据,并不存储实际的业务数据。

Datanode:数据节点(简称DN)

每个节点还存储业务数据的分片在功能上,DN节点负责完成执行协调节点分发的执行请求。

GTM:全局事务管理器(Global Transaction Manager)

负责管理集群事务信息,同时管理集群的全局对象,比如序列等。

在编译安装的过程中出现了多次报错,都是由于缺少对应的rpm依赖包导致,建议tbase的安装也可以参考其他数据库软件提供一个rpm包安装的方式

安装文档参考

https://github.com/Tencent/TBase/wiki/1、TBase_Quick_Start

tbase 公有云和开源版本比较

功能特性

云版本

开源版本

弹性伸缩

☑️

✖️

自动故障切换

☑️

✖️

多核并行计算能力

☑️

☑️

冷热数据分离

☑️

☑️

分布式事务

☑️

☑️

高可用性

☑️

☑️

管理控制台

☑️

✖️

多租户资源隔离

☑️

☑️

FDW

☑️

行列混合存储

☑️

✖️

审计

☑️

✖️

通过github上看未能找到审计,节点扩展,行列混合存储等文档,因为开源版本少了oss管控也无法做到自动的故障转移,事务隔离级别可支持read-committed和repeatable-read满足大部分场景.

Tbase对应的PostgreSql对应版本为10.0

代码语言:txt复制
psql (PostgreSQL 10.0 TBase V2)
Type "help" for help.

postgres=# select version();
                                                     version                                                      
------------------------------------------------------------------------------------------------------------------
 PostgreSQL 10.0 TBase V2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28), 64-bit
(1 row)

tbase 测评

测试数据来源于美国交通运输部2010至2020年4000w条航班起降数据

https://github.com/Percona-Lab/ontime-airline-performance/blob/master/download.sh

建表sql

代码语言:txt复制
drop table if exists faa_otp_load;
create table faa_otp_load (
Flt_Year smallint,
Flt_Quarter smallint,
Flt_Month smallint,
Flt_DayofMonth smallint,
Flt_DayOfWeek smallint,
FlightDate date,
UniqueCarrier text,
AirlineID integer,
Carrier text,
TailNum text,
FlightNum text,
OriginAirportID integer,
OriginAirportSeqID integer,
OriginCityMarketID integer,
Origin text,
OriginCityName text,
OriginState text,
OriginStateFips text,
OriginStateName text,
OriginWac smallint,
DestAirportID integer,
DestAirportSeqID integer,
DestCityMarketID integer,
Dest text,
DestCityName text,
DestState text,
DestStateFips text,
DestStateName text,
DestWac smallint,
CRSDepTime text,
DepTime text,
DepDelay numeric,
DepDelayMinutes numeric,
DepDel15 numeric,
DepartureDelayGroups smallint,
DepTimeBlk text,
TaxiOut numeric,
WheelsOff text,
WheelsOn text,
TaxiIn numeric,
CRSArrTime text,
ArrTime text,
ArrDelay numeric,
ArrDelayMinutes numeric,
ArrDel15 numeric,
ArrivalDelayGroups smallint,
ArrTimeBlk text,
Cancelled numeric,
CancellationCode text,
Diverted numeric,
CRSElapsedTime numeric,
ActualElapsedTime numeric,
AirTime numeric,
Flights numeric,
Distance numeric,
DistanceGroup smallint,
CarrierDelay numeric,
WeatherDelay numeric,
NASDelay numeric,
SecurityDelay numeric,
LateAircraftDelay numeric,
FirstDepTime text,
TotalAddGTime numeric,
LongestAddGTime numeric,
DivAirportLandings numeric,
DivReachedDest numeric,
DivActualElapsedTime numeric,
DivArrDelay numeric,
DivDistance numeric,
Div1Airport text,
Div1AirportID integer,
Div1AirportSeqID integer,
Div1WheelsOn text,
Div1TotalGTime numeric,
Div1LongestGTime numeric,
Div1WheelsOff text,
Div1TailNum text,
Div2Airport text,
Div2AirportID integer,
Div2AirportSeqID integer,
Div2WheelsOn text,
Div2TotalGTime numeric,
Div2LongestGTime numeric,
Div2WheelsOff text,
Div2TailNum text,
Div3Airport text,
Div3AirportID integer,
Div3AirportSeqID integer,
Div3WheelsOn text,
Div3TotalGTime numeric,
Div3LongestGTime numeric,
Div3WheelsOff text,
Div3TailNum text,
Div4Airport text,
Div4AirportID integer,
Div4AirportSeqID integer,
Div4WheelsOn text,
Div4TotalGTime numeric,
Div4LongestGTime numeric,
Div4WheelsOff text,
Div4TailNum text,
Div5Airport text,
Div5AirportID integer,
Div5AirportSeqID integer,
Div5WheelsOn text,
Div5TotalGTime numeric,
Div5LongestGTime numeric,
Div5WheelsOff text,
Div5TailNum text,
trailer smallint
) PARTITION BY range (Flt_Year);
CREATE TABLE faa_otp_load_1 PARTITION OF faa_otp_load FOR VALUES from (2010) TO (2013);
CREATE TABLE faa_otp_load_2 PARTITION OF faa_otp_load FOR VALUES from (2014) TO (2015);
CREATE TABLE faa_otp_load_3 PARTITION OF faa_otp_load FOR VALUES from (2016) TO (2020);

通过copy的方式导入数据

代码语言:txt复制
COPY faa_otp_load from '/data/airline/On_Time_Reporting_Carrier_On_Time_Performance_(1987_present)_2010_1.csv' with csv header;
代码语言:txt复制
test=> select count(*) from faa_otp_load;
  count   
----------
 45047856
(1 row)

test=> explain select count(*) from faa_otp_load;;
                                         QUERY PLAN                                          
---------------------------------------------------------------------------------------------
 Finalize Aggregate  (cost=130.77..130.78 rows=1 width=8)
   ->  Remote Subquery Scan on all (dn001,dn002,dn003)  (cost=130.75..130.77 rows=1 width=0)
         ->  Partial Aggregate  (cost=30.75..30.76 rows=1 width=8)
               ->  Append  (cost=0.00..30.60 rows=60 width=0)
                     ->  Seq Scan on faa_otp_load_1  (cost=0.00..10.20 rows=20 width=0)
                     ->  Seq Scan on faa_otp_load_2  (cost=0.00..10.20 rows=20 width=0)
                     ->  Seq Scan on faa_otp_load_3  (cost=0.00..10.20 rows=20 width=0)

通过以上执行计划能够看出tbase将count计算下推到每个分片得出结果

多核并行计算能力

在用多核情况下运行

代码语言:txt复制
set max_parallel_workers=20;  
set max_parallel_workers_per_gather =20;  
set parallel_setup_cost =0;  
set parallel_tuple_cost =0;
alter table faa_otp_load set (parallel_workers=20);

测试过程中发现该表无法使用多核能力。

代码语言:txt复制
test=> alter table faa_otp_load set (parallel_workers =20);
ERROR:  unrecognized parameter "parallel_workers"
代码语言:txt复制
test=> select count(*) from faa_otp_load ;
  count   
----------
 45047856
(1 row)

Time: 8325.130 ms (00:08.325)
test=> set max_parallel_workers_per_gather =0;
SET
Time: 0.276 ms
test=>  select count(*) from faa_otp_load ;
  count   
----------
 45047856
(1 row)

Time: 8876.309 ms (00:08.876)

开不开并行时间相差不多

执行计划和没开并行一样

代码语言:txt复制
test=> explain select count(*) from faa_otp_load;
                                              QUERY PLAN                                               
-------------------------------------------------------------------------------------------------------
 Parallel Finalize Aggregate  (cost=130.46..130.47 rows=1 width=8)
   ->  Parallel Remote Subquery Scan on all (dn001,dn002,dn003)  (cost=130.44..130.46 rows=1 width=0)
         ->  Gather  (cost=30.44..30.45 rows=1 width=8)
               Workers Planned: 1
               ->  Partial Aggregate  (cost=30.44..30.45 rows=1 width=8)
                     ->  Parallel Append  (cost=0.00..30.35 rows=36 width=0)
                           ->  Parallel Seq Scan on faa_otp_load_1  (cost=0.00..10.12 rows=12 width=0)
                           ->  Parallel Seq Scan on faa_otp_load_2  (cost=0.00..10.12 rows=12 width=0)
                           ->  Parallel Seq Scan on faa_otp_load_3  (cost=0.00..10.12 rows=12 width=0)

但参考https://blog.csdn.net/ctypyb2002/article/details/79668603按照上面方式建的表可以利用到多核

代码语言:txt复制
create table tmp_t0  (
 c1 int8,
 c2 int8,
 c3 text,
 c4 text
)
;
代码语言:txt复制
insert into tmp_t0
SELECT (random()*(2*10^9))::int8,
       (random()*(2*10^9))::int8,
       md5(random()::text),
       md5(random()::text)
  from generate_series(1,8000000)
 where 1=1
 ;

关闭并行

代码语言:txt复制
set max_parallel_workers_per_gather =0;

执行计划和结果

代码语言:txt复制
test=> set max_parallel_workers_per_gather =0;
SET
Time: 0.329 ms
test=> explain 
test-> select count(1)
test-> from tmp_t0
test-> where 1=1
test-> ;
                                            QUERY PLAN                                             
---------------------------------------------------------------------------------------------------
 Finalize Aggregate  (cost=218059.03..218059.04 rows=1 width=8)
   ->  Remote Subquery Scan on all (dn001,dn002,dn003)  (cost=218059.01..218059.03 rows=1 width=0)
         ->  Partial Aggregate  (cost=217959.01..217959.02 rows=1 width=8)
               ->  Seq Scan on tmp_t0  (cost=0.00..217959.01 rows=7999901 width=0)
(4 rows)

Time: 0.817 ms
test=> select count(1) from tmp_t0 where 1=1;
  count  
---------
 8000000
(1 row)

开启并行

代码语言:txt复制
set max_parallel_workers=20;  
set max_parallel_workers_per_gather =20;  
set parallel_setup_cost =0;  
set parallel_tuple_cost =0;
alter table tmp_t0 set (parallel_workers=20);

执行计划和结果

代码语言:txt复制
test=> explain select count(1) from tmp_t0 where 1=1;
                                                 QUERY PLAN                                                 
------------------------------------------------------------------------------------------------------------
 Parallel Finalize Aggregate  (cost=143059.96..143059.97 rows=1 width=8)
   ->  Parallel Remote Subquery Scan on all (dn001,dn002,dn003)  (cost=143059.94..143059.95 rows=1 width=0)
         ->  Gather  (cost=142959.94..142959.95 rows=1 width=8)
               Workers Planned: 20
               ->  Partial Aggregate  (cost=142959.94..142959.95 rows=1 width=8)
                     ->  Parallel Seq Scan on tmp_t0  (cost=0.00..141959.95 rows=399995 width=0)
(6 rows)

Time: 1.383 ms
test=> select count(1) from tmp_t0 where 1=1;
  count  
---------
 8000000
(1 row)

Time: 322.799 ms

执行计划和查询速度都有提升。

关于并行这方面tbase也可以参考oracle添加hint指定并行度,通过修改参数来实现还是较为麻烦。另外也不知道是不是并行查询有一些限制,希望在相关文档能说明。

冷热数据分离

TBASE的冷热分离是通过datanode group来实现以 faa_otp_load为例我们可以将2016年以前的数据都归为冷数据,2016年以后的归热数据。

代码语言:txt复制
postgres=# create node group cold_group with(dn001,dn002);
ERROR:  PGXC node:16385 already in group:default_group
postgres=# 

datanode group无法复用。类似删除datanode group的操作会导致基于之前datanode的表损坏,需要谨慎操作。

代码语言:txt复制
drop sharding in group default_group;
drop node group default_group;
代码语言:txt复制
test=> drop table faa_otp_load;
ERROR:  corrupted catalog, no shard group of 16388 found
代码语言:txt复制
create default node group hot_group with(dn001);
create sharding group to group hot_group;
clean sharding;
代码语言:txt复制
create node group cold_group with(dn002,dn003);
create extension sharding group to group cold_group;
clean sharding;
代码语言:txt复制
test=> create table public.t1_cold_hot
test-> (
test(> f1 int not null,
test(> f2 timestamp not null,
test(> f3 varchar(20),
test(> primary key(f1)
test(> ) 
test-> partition by range (f2) 
test-> begin (timestamp without time zone '2017-01-01 0:0:0') 
test-> step (interval '12 month') partitions (4) 
test-> distribute by shard(f1,f2) 
test-> to group hot_group cold_group;
ERROR:  cold-hot table shoule partition by month
test=> 

由于找不到相关处理方法该特性就没继续测试下去。

测评总结

tbase是一款基于Postgresql生态的数据库,拥有和Postgresql同样丰富的功能,但是目前开源版本文档较少(连最基本的语法树都没有),另外开源版本目前还没行列混合存储,在olap上还有提升空间,较公有云版本少了os管控平台,建议如果有需要直接测试公有云版本。Tbase开源版本对于新手非常不友好。

开源版改进建议

如果要发展开源生态建议完善文档,将更多的公有云功能也开源动用社区力量把tbase做的更好。

另外冷热数据分离操作过于繁琐,建议直接通过sql就能把数据的路由映射到指定的datanode,不用修改配置文件再重启。

使用场景建议及选型建议

1.作为实时数据仓库。

2.通过fdw直接与其他数据库打通减少跨库查询难度,可以拿来做数据中台入口。

3.相比greenplum tbase的oltp功能更加强大使用场景更广泛。

4.冷热分离的特性也能把冷数据给放至更加低廉的存储池。

5.由于能使用多核计算在olap上本比类似架构的分布式mysql更有优势。

0 人点赞