关于数据库:HashData外部表的实现与应用

4次阅读

共计 3672 个字符,预计需要花费 10 分钟才能阅读完成。


背景

内部表是数据仓库十分重要的一个性能个性,包含 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 的高效数据交换》文章中提到的,这将大幅升高内部表性能组件装置部署与运维监控的复杂度,同时缩短数据周转与转换环节(没有额定的过程间序列化 / 反序列化开销),晋升端到端的查问性能。

性能形容

依据咱们的教训,目前内部表次要用在如下三个场景:

  1. 长期查问归档数据(或者其它不沉闷数据);
  2. ETL,将数据从内部存储系统加载到数据仓库;
  3. 将数据从数据仓库卸载到内部存储系统;

对于后面两种场景,咱们能够通过 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 语句即可实现包含数据加载、数据备份、归档数据长期查问等数据工程工作。

随着逻辑数仓以及数据湖需要的日益增长,除了持续实现更多的协定类型以及文件格式来对接更多的数据源外,如何晋升内部表的扫描效率(尽可能地靠近外部表)是咱们将来研发的重点:潜在的技术方向包含像外部表一样提供本地缓存,以及通过数据映射物化在本地缓存中,将原始的文件格式转化为更加高效的存储格局。

正文完
 0