AnalyticDB PostgreSQL版(简称ADB PG)是阿里云数据库团队基于PostgreSQL内核(简称PG)打造的一款云原生数据仓库产品。在PB级数据实时交互式剖析、HTAP、ETL、BI报表天生等业务场景,ADB PG都有着独特的技能上风。作为一个数据仓库产品,ADB PG是如何具备湖仓一体剖析能力呢?本文将会先容ADB PG如何基于PG外表、打造数据湖剖析能力。
ADB PG继续了PG的外表(Foreign Table)功能,目前ADB PG的湖仓一体能力紧张是基于外表打造的。基于PG外表,ADB PG可以对其他数据剖析系统的数据进行查询和写入,在兼容多种数据源的同时,复用ADB PG原有的优化器和实行引擎上风。ADB PG的湖仓一体剖析能力目前已经支持OSS、MaxCompute、Hadoop、RDS PG、Oracle、RDS MySQL等多种数据源的剖析或者写入。用户可以灵巧地将ADB PG运用于数据存储、交互式剖析、ETL平分歧领域,可以在单个实例中实现多种数据剖析功能。即可以用ADB PG完成数据剖析的核心流程,也可以作为浩瀚环节中的一环去搭建数据链路。
不过,外表数据的剖析依赖于外部SDK和网络IO来实现数据读写,由于网络本身的特性与本地磁盘有巨大差异,因此须要在技能层面与本地存储不同、须要不同的性能优化方案。本文以OSS外表数据读写为例,先容ADB PG在构建湖仓一体剖析能力时,所碰着的一些主要问题和解决方案。

ADB PG内核可以分为优化器、实行引擎和存储引擎。外表数据剖析可以复用ADB PG原有的优化器和实行引擎的核心部分,仅需少量修正。紧张扩展是存储引擎层的改造,也便是通过外表接口对外表数据进行读写。外表数据是存储在另一个分布式系统当中,须要通过网络与ADB PG进行连接,这是和读取本地文件的最核心的差异。一方面,不同的外表数据会供应不同的远程访问接口,须要在工程上进行兼容,比如OSS、MaxCompute的数据读取接口都不相同。另一方面,通过网络访问远程机器上的数据有一定的共性,比如网络的延迟、网络放大、带脱期制、网络稳定性问题等。
本文将会环绕上述核心寻衅,先容ADB PG外表剖析项目在支持OSS数据剖析过程中的一些主要技能点。OSS是一种阿里云推出的一种低整天职布式存储系统,存储了大量的冷热数据,有较大的数据剖析需求。为了方便开拓者进行扩展,OSS供应了基于Java、Go、C/C++、Python等主流开拓措辞的SDK。ADB PG采取了OSS C SDK进行开拓。目前ADB PG已经完美支持OSS外表剖析的各项功能,除建表语句不同外,用户可以像访问本地表一样访问OSS外表。支持并发读取和写入,支持CSV、ORC、Parquet等常见数据格式。
三. 外表剖析技能优化
接下来,我们先容ADB PG在基于OSS C SDK开拓OSS外表剖析过程中,办理的一些核心技能问题。
3.1 网络碎片要求问题
在剖析型数据库场景,业界普遍认为列式存储在IO性能上强于行式存储。由于列式存储在扫描数据时,只须要扫描特定列,而行式存储毕竟扫描全量数据,因此列式存储可以节约一些IO资源。但是在开拓过程中,团队创造在一些场景下,如字段较多的大宽表扫描,扫描性能较高的列存格式竟然比扫描CSV行存文本格式性能还要差。后经由定位创造一方面扫描ORC/PARQUET 格式时,客户端与OSS做事端交互次数过于频繁,另一方面ADB PG单次向OSS要求的数据量比较小。这两个缘故原由带来了很大的性能问题。
我们知道,比较于本地磁盘IO,网络IO所产生的来回时延每每可以放大几个量级。因此,如果解析一些列存格式(如ORC/PARQUET)时,如果将网络要求当作本地磁盘要求处理,高压缩比所带来的网络带宽占用的减少不敷以抵消碎片化要求带来的来回时延放大,因此性能测试结果低于预期。问题的办理方案,便是通过缓存来减少碎片化的网络要求。ADB PG每次扫描OSS数据都会“预加载”足够的数据并缓存,要求时,剖断是否命中缓存,如果命中,则直接返回缓存;否则,连续下一轮次的“预加载”,从而降落网络要求次数,提高单次要求效率。“预加载”的缓存大小开放配置,默认大小为1MB。
3.2 列过滤与谓词下推
由于网络本身的IO性能每每是低于本地存储的IO性能的,因此在扫描外表数据时,要只管即便减少IO的带宽资源花费。ADB PG在处理ORC、Parquet格式的文件时,采取了列过滤和谓词下推技能,来达到这一目的。
列过滤,即外表只要求SQL查询所需的数据列、忽略不须要的数据列。由于ORC、Parquet都是列式存储格式,以是外表在发起网络要求时,只必要求所需列所在的数据范围即可,从而大幅减小网络I/O。同时,ORC、Parquet会对列数据进行压缩处理,进一步减小I/O。
谓词下推,是将实行操持里的上层的过滤条件(如WHERE子句中的条件),移动到下层的外表扫描节点,使外表扫描进行网络要求时,过滤掉不符合查询条件的数据块,从而减少网络I/O。在ORC/Parquet格式文件中,会在每一个block头部保存该block中每一列数据的min/max/sum等统计信息,当外表扫描时,会先读取该block的头部统计信息,与下推的查询条件进行比较,如果该列的统计信息不符合查询条件,则可以直接跳过该列数据。
这里大略先容ORC格式的外表的谓词下推的实现方案。一个ORC文件按数据行分成多少个Stripe组成,Stripe中数据按列式存储。每个Stripe又分为多少个Row Group, 所有列的每10000行 组成一个Row Group。如下图所示。
ORC文件保存3个层次的统计信息,文件级别与Stripe级别的统计信息存储在ORC文件末端,Row Group级别的统计信息在每个Stripe块头部存放。利用这3个层次的统计信息,ORC外表可以实现文件级过滤,Stripe级过滤以及Row Group级别过滤。详细做法是,每当扫描一个新的ORC文件,会先读取文件末端的文件级统计信息,若不符合查询条件,则直接跳过全体文件的扫描;接着读取文件末端所有Stripe级别的统计信息,过滤掉不符合条件的Stripe块;对付每个符合条件的Stripe块,读取块头部的Row Group 级别的统计信息,过滤掉不必要的数据。
3.3 “996”问题
OSS C SDK定义了一类缺点代码,用于表示非常情形,这里的996是OSS C SDK中定义的缺点码-996。类似的还有缺点码-998、-995、-992等。这一类缺点,常日都是网络非常导致的OSS外表导入导出失落败。-996是最为常见的一种。
OSS C SDK内部利用CURL与OSS做事端进行网络交互,相应的CURL缺点码,常见CURL 56(Connection reset by peer)、52等。这些网络非常,常日是由于OSS做事端在负载较高情形下,做事端主动剔除其认为“不生动”的客户端连接所致。当须要导入或导出较大规模OSS数据时,由于客户端处于实行操持的不同阶段,不能永劫光持有连接进行连续通信,从而被OSS做事端当作“不生动”的客户端连接而关闭。
常日对付这种情形,客户端须要考试测验重试办理。实际开拓过程中创造,纵然客户端接口增加了自动非常重试机制,这种非常依然得不到改进。后经由定位创造,OSS C SDK为提高连接效率,增加了CURL句柄的连接池,但这些网络非常的CURL句柄,也会存放到池中,因此,纵然重试,还是会利用非常的CURL句柄进行通信,以是996非常的问题得不到改进。
既然知道了根本缘故原由,办理的方法也很直不雅观。我们在CURL句柄的回收接口中,增加对CURL句柄状态检讨,对付非常的CURL句柄进行销毁,而不是加回连接池中。这样避免了连接池中存在无效的CURL句柄。客户端接口重试时,选择有效的或者创建新的CURL连接再次通信即可。当然,自动非常重试机制只能针对那些可以重试办理的情形。
① ADB PG访问OSS外表时,先从CURL连接池中获取连接,若不存在则新建。
② ADB PG利用CURL连接句柄与OSS Server要求通信。
③ OSS Server通过CURL连接句柄返回通信结果。
④ 正常返回的CURL连接句柄利用完毕后加回连接池待下次利用。
⑤ 非常状态的CURL连接句柄销毁。
3.4 内存管理方案的兼容问题
ADB PG基于PostgreSQL内核打造,也继续了PostgreSQL的内存管理机制。PostgreSQL的内存管理采取了进程安全的内存高下文MemoryContext,而OSS C SDK是线程安全的内存高下文APR Pool。在MemoryContext内存环境下,每个已经分配的内存,都可以显式的调用free开释,由MemoryContext进行内存碎片的整理,但在APR Pool中,我们只看到内存池的创建、内存的申请和内存池的销毁等操作,却没有内存的显式开释接口。
这种情形意味着,我们须要对付OSS C SDK接口所持有的内存的生命周期有明确的理解,否则极易涌现内存泄露和访问已经开释的内存等问题。常日我们会按照如下两种办法申请APR Pool的内存。
办法一适用于重入低频的操作接口,如获取OSS文件清单列表。办法二适用于多次重入的操作接口,如周期性向OSS要求指定文件指定例模的数据。通过这种方法,可以很好地办理ADB PG与OSS C SDK在内存管理方面的不兼容问题。
3.5 数据格式的兼容和优化
OSS上的数据,大部分采取CSV、ORC、Parquet等格式。由于ORC/Parquet等格式对数据的底层存储编码,与ADB PG的数据编码并不一致,以是当进行外表扫描时,数据类型转换是必不可少的步骤。类型转换,实质上是将数据从一种编码,改变成另一种编码办法。例如ORC对付Decimal类型的表示办法和ADB PG不相同,在ORC中Decimal64类型由一个int64存放数据的数字值,再由precision和scale表示数字个数和小数点位数,而在ADB PG中, Decimal类型由int16 数组来存放数据的数字值。格式转换算法须要对每个数据进行循环的除法与取模操作,这是非常耗费CPU的。
为了减少类型转换带来的CPU花费,进一步优化外表查询性能,ADB PG在利用外表进行导出数据时,跳过类型转换步骤,直接将ADB PG的数据,以二进制形式写入到外表文件中,这样在查询外表时,也无需进行任何数据类型转换。例如,在导出ORC外表时,外表可以将任意的数据类型,都直接写入为ORC的Binary类型,在ORC中存储的二进制数据,都是按照对应ADB PG的数据类型来编码,于是在查询该ORC外表时,可以直接省略类型转换步骤,减少了CPU花费。根据TPCH查询测试结果,整体查询性能可以提升15%-20%旁边。
四. 性能测试关于在ADB PG中如何利用外表剖析功能,请参考阿里云产品手册(https://help.aliyun.com/document_detail/164815.html?spm=a2c4g.11186623.6.602.78db2394eaa9rq)。除建表语句不同外,对外表的操作和对本地表的操作险些没有差异,学习难度很低。我们在这里比拟一下OSS外表剖析场景,与本地表剖析场景的性能问题。
环境配置。我们测试采取的机器是阿里云ECS d1ne.4xlarge机型,单机配置16个Intel Xeon E5-2682v4核心、64GB内存,每台ECS配置4块HDD本地磁盘,每块盘读写速率约200MB/s。测试一共用了4台ECS,两台用于做Master节点、4台用于做Segment节点,共支配16个segment。本次测试利用的是TPCH查询,利用了官方工具天生的1TB数据集。
本地表我们测试了经由压缩的列存表(AOCS)和HEAP表两种格式, OSS外表我们测试了CSV、ORC、Parquet和JSON四种格式。TPCH 22条查询的总实行韶光见下表。从测试数据可以看出,两种本地表中,AOCS表的查询性能略优于HEAP表。外表方面,CSV格式、ORC格式和Parquet格式的外表查询性略慢于本地表的查询性能,差距在50%旁边。JSON格式的外表查询性能明显慢于其他格式,这紧张是由于JSON格式本身解析速率慢导致的,与外表无关。
下图是TPCH 22条查询的详细韶光。本地表与外表的性能差距在不同的查询上差距有所不同。考虑到外表在存储本钱、灵巧性、扩展能力方面的上风,ADB PG外表剖析在运用处景的潜力是巨大的。
五. 总结
湖仓一体是下一代数据仓库产品的一个主要能力,ADB PG作为一款功能强大、扩展性强的数据仓库产品,基于PG 外表开拓了多种数据源的剖析和写入能力,并且沉淀了很多性能优化技能。未来ADB PG将连续在产品功能、性价比、云原生能力、湖仓一体等方向连续发力,为用户供应更多的功能、性能和本钱优化。
本文为阿里云原创内容,未经许可不得转载。