背景
内部表是数据仓库十分重要的一个性能个性,包含AWS Redshift、Azure Synapse、Google BigQuery和Snowflake等云数仓产品都有着欠缺的反对。顾名思义,内部表与外部表(或者内置表)对应,后者指的是失常的数据库表,无论是表的元数据还是物理数据文件均由数据库本身治理,而前者是将数据库之外(内部)的数据(能够是动态的数据文件,也能够是动静的数据流)映射成数据库的表对象,其中只有元数据是由数据库治理,物理数据文件或者数据流则是由内部的存储系统治理。例如,在《HashData与HDFS的高效数据交换》中重点介绍的GPHDFS内部表,其元数据由HashData数据仓库保留治理,数据文件则由HDFS保留治理。当咱们删除一张外部表时,除了表定义外,这张表对应的数据文件也会被删除,而当删除的是一张内部表时,只有表定义会被删除,数据文件放弃不动。
除GPHDFS外,HashData还反对其它多种内部表协定与数据格式,其中一部分是从PostgreSQL和Greenplum Database继承过去的,其它是咱们针对客户需要优化和增加的。明天,咱们系统性地介绍一下HashData的内部表性能。
内部表架构
如下为HashData内部表架构示意图。
实质上,内部表是用于HashData集群与内部存储系统进行数据交换的。类比FTP,咱们能够认为HashData集群是FTP的客户端,而内部存储系统是FTP服务器。FTP客户端与服务器端交互会波及两类信息:管制音讯和数据流。其中,管制音讯在内部表的框架下对应的是协定,数据流对应的是数据格式。实践上,协定和数据格式是能够齐全解耦的,就像无论是本地文件系统(file协定)、文件服务器(gpfdist协定)、HDFS(gphdfs协定)还是对象存储(oss协定),都可能存储TEXT、CSV、ORC和NETCDF等格局的文件。但实际上,因为各种历史起因和客户需要侧重点不一样(内部表性能更多是客户场景驱动,不是产品设计驱动),目前HashData罕用内部表实现中,协定和文件格式是紧耦合的(咱们心愿在基于PostgreSQL Foreign Data Wrapper实现新内部表框架时来解决这个问题),某个协定只能反对某些文件格式:
TEXT、CSV和ORC是比拟罕用的数据格式,这里简略阐明一下另外两种格局:SHAPEFILE和NETCDF。GIS数据次要分两类:矢量数据和栅格数据。咱们常说的点、线、面是矢量数据,个别保留成SHAPEFILE格局。栅格数据则是行列组成的像素矩阵,每个像素(矩阵元素)代表一块区域,同时保留与这块区域相干的信息,如温度、高度等。栅格数据能够是航拍图片、卫星图像和数字地图。栅格数据有多种格局,包含TIFF和NETCDF,咱们反对的是NETCDF。
上述HashData反对的所有协定和数据格式,均为C/C++原生实现,让数据库过程间接与指标存储系统交互,只有一次序列化/反序列化开销,没有任何直达过程。如在《HashData与HDFS的高效数据交换》文章中提到的,这将大幅升高内部表性能组件装置部署与运维监控的复杂度,同时缩短数据周转与转换环节(没有额定的过程间序列化/反序列化开销),晋升端到端的查问性能。
性能形容
依据咱们的教训,目前内部表次要用在如下三个场景:
- 长期查问归档数据(或者其它不沉闷数据);
- ETL,将数据从内部存储系统加载到数据仓库;
- 将数据从数据仓库卸载到内部存储系统;
对于后面两种场景,咱们能够通过CREATE READABLE EXTERNAL TABLE 创立可读内部表,实现对外部数据的读拜访。定义可读内部表后,即能够应用 SQL 命令间接查问其映射的数据集。例如,用户能够对可读内部表进行SELECT, JOIN, SORT等查问操作,并反对基于内部表创立视图。DML操作(UPDATE, INSERT, DELETE, TRUNCATE) 在可读内部表上是不容许的,用户也无奈为其创立索引。
对于第三种场景,咱们须要的是可写内部表,通过CREATE WRITABLE EXTERNAL TABLE来创立,实现对外部存储系统的写操作。可写内部表定义后,便能够在数据库中将查问的后果集插入到可写内部表,从而实现数据的卸载。可写内部表仅容许INSERT操作 — SELECT,UPDATE,DELETE或TRUNCATE不被容许。
oss 协定内部表实际数据的导入导出
这里咱们通过oss协定(对象存储)来演示一下如何通过内部表实现数据的导入导出,如下为简略示意图。
整体的演示过程为,先通过可写内部表将一张表的数据导出到对象存储(这里应用的是青云的QingStor对象存储),而后再通过可读内部表将保留在QingStor上的数据恢复到原始表。除了QingStor外,HashData还反对其它支流私有云的对象存储服务,包含AWS的S3、Azure的Blob Storage、阿里云的OSS、腾讯云的COS、金山云的KS3和华为云的OBS,以及基于开源Ceph和Minio构建的公有云对象存储产品。
1 创立可写内部表
---数据库表 zz_hashdata
warehouse=# select * from zz_hashdata;
id
----
6
6
6
6
6
6
6
6
6
6
(10 rows)
---创立对应的可写内部表
warehouse=# CREATE WRITABLE EXTERNAL TABLE ext_hashdata ( like zz_hashdata)
warehouse-# LOCATION ('oss://zz-hashdata.pek3b.qingstor.com/ext-hashdata/zzhashdata.txt access_key_id=<access-key-id> secret_access_key=<secret-access-key> oss_type=qs')
warehouse-# FORMAT 'TEXT' (DELIMITER '|');
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table
CREATE EXTERNAL TABLE
2 将数据库表数据放入可写内部表中
---将数据写入可写内部表
warehouse=# insert into ext_hashdata select * from zz_hashdata;
INSERT 0 10
3 创立可读内部表
---创立对应的可读内部表
warehouse=# CREATE READABLE EXTERNAL TABLE ext_hashdata1 ( like zz_hashdata)
warehouse-# LOCATION ('oss://zz-hashdata.pek3b.qingstor.com/ext-hashdata/zzhashdata.txt access_key_id=<access-key-id> secret_access_key=<secret-access-key> oss_type=qs')
warehouse-# FORMAT 'TEXT' (DELIMITER '|')
warehouse-# LOG ERRORS SEGMENT REJECT LIMIT 10 ROWS;
CREATE EXTERNAL TABLE
4 查看可读内部表数据
---查看可读内部表的数据
warehouse=# select * from ext_hashdata1;
id
----
6
6
6
6
6
6
6
6
6
6
(10 rows)
5 将原始表数据清空,从可读内部表复原数据
---将原始表数据清空,而后通过可读内部表插入数据
warehouse=# truncate table zz_hashdata;
TRUNCATE TABLE
warehouse=# insert into zz_hashdata select * from ext_hashdata1;
INSERT 0 10
warehouse=# select * from zz_hashdata;
id
----
6
6
6
6
6
6
6
6
6
6
(10 rows)
总结与瞻望
在这篇文章中,咱们系统性地介绍了HashData反对的内部表性能。作为数据库内置的性能个性,用户能够在不依赖任何第三方工具的状况下,简略地通过SQL语句即可实现包含数据加载、数据备份、归档数据长期查问等数据工程工作。
随着逻辑数仓以及数据湖需要的日益增长,除了持续实现更多的协定类型以及文件格式来对接更多的数据源外,如何晋升内部表的扫描效率(尽可能地靠近外部表)是咱们将来研发的重点:潜在的技术方向包含像外部表一样提供本地缓存,以及通过数据映射物化在本地缓存中,将原始的文件格式转化为更加高效的存储格局。
发表回复