
引言
PolarDB-X on OSS 将低成本做到了极致。除了OSS对象存储服务本身的存储成本优势外,还有一个重要的原因就是PolarDB-X极致的数据压缩能力。本文将对多款数据库产品的压缩能力进行测评对比,并展示其背后的设计原理。
压缩能力测评
我们测试所需的数据,以及HBase、MySQL、MongoDB相关的压缩能力测试数据,都来源于文章:
在这篇文章的基础上,我们使用相同测试集对PolarDB-X on OSS的压缩能力进行检验。

TPCH
CREATE TABLE `orders` (`o_orderkey` int(11) NOT NULL,`o_custkey` int(11) NOT NULL,`o_orderstatus` varchar(1) NOT NULL,`o_totalprice` decimal(15, 2) NOT NULL,`o_orderdate` date NOT NULL,`o_orderpriority` varchar(15) NOT NULL,`o_clerk` varchar(15) NOT NULL,`o_shippriority` int(11) NOT NULL,`o_comment` varchar(79) NOT NULL,PRIMARY KEY (`o_orderdate`, `o_orderkey`),KEY `auto_shard_key_o_orderkey` USING BTREE (`o_orderkey`)) ENGINE = InnoDB DEFAULT CHARSET = latin1PARTITION BY KEY(`o_orderkey`)PARTITIONS 4
create table orders like sizetest.orders engine = 'oss' archive_mode = 'loading';
执行结果如下:

NGSIM
CREATE TABLE `ngsim` (`ID` int(11) NOT NULL AUTO_INCREMENT,`Vehicle_ID` int(11) NOT NULL,`Frame_ID` int(11) NOT NULL,`Total_Frames` int(11) NOT NULL,`Global_Time` bigint(20) NOT NULL,`Local_X` decimal(10, 3) NOT NULL,`Local_Y` decimal(10, 3) NOT NULL,`Global_X` decimal(15, 3) NOT NULL,`Global_Y` decimal(15, 3) NOT NULL,`v_length` decimal(10, 3) NOT NULL,`v_Width` decimal(10, 3) NOT NULL,`v_Class` int(11) NOT NULL,`v_Vel` decimal(10, 3) NOT NULL,`v_Acc` decimal(10, 3) NOT NULL,`Lane_ID` int(11) NOT NULL,`O_Zone` char(10) DEFAULT NULL,`D_Zone` char(10) DEFAULT NULL,`Int_ID` char(10) DEFAULT NULL,`Section_ID` char(10) DEFAULT NULL,`Direction` char(10) DEFAULT NULL,`Movement` char(10) DEFAULT NULL,`Preceding` int(11) NOT NULL,`Following` int(11) NOT NULL,`Space_Headway` decimal(10, 3) NOT NULL,`Time_Headway` decimal(10, 3) NOT NULL,`Location` char(10) NOT NULL,PRIMARY KEY (`ID`)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4PARTITION BY KEY(`ID`)PARTITIONS 4/*+TDDL:load_data_auto_fill_auto_increment_column=true*/load data local infile './dataset/Next_Generation_Simulation__NGSIM__Vehicle_Trajectories_and_Supporting_Data.csv' into table ngsim FIELDS TERMINATED BY ',' IGNORE 1 LINES (Vehicle_ID,Frame_ID,Total_Frames,Global_Time,Local_X,Local_Y,Global_X,Global_Y,v_length,v_Width,v_Class,v_Vel,v_Acc,Lane_ID,O_Zone,D_Zone,Int_ID,Section_ID,Direction,Movement,Preceding,Following,Space_Headway,Time_Headway,Location)
create table ngsim like sizetest.ngsim engine = 'oss' archive_mode = 'loading';
执行结果如下:

ACCESS_LOG
CREATE TABLE `ACCESS_LOG` (`ID` int(11) NOT NULL AUTO_INCREMENT,`CONTENT` varchar(10000) DEFAULT NULL,PRIMARY KEY (`ID`)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4PARTITION BY KEY(`ID`)PARTITIONS 4/*+TDDL:load_data_auto_fill_auto_increment_column=true*/load data local infile './dataset/access.log' into table ACCESS_LOG FIELDS TERMINATED BY '\n' IGNORE 1 LINES (CONTENT)
执行冷数据一键迁移归档:
create table ACCESS_LOG like sizetest.ACCESS_LOG engine = 'oss' archive_mode = 'loading';
执行结果如下:

IJCAI-15
CREATE TABLE `USER_LOG` (`ID` int(11) NOT NULL AUTO_INCREMENT,`USER_ID` int(11) NOT NULL,`ITEM_ID` int(11) NOT NULL,`CAT_ID` int(11) NOT NULL,`SELLER_ID` int(11) NOT NULL,`BRAND_ID` int(11) DEFAULT NULL,`TIME_STAMP` char(4) NOT NULL,`ACTION_TYPE` char(1) NOT NULL,PRIMARY KEY (`ID`)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4PARTITION BY KEY(`ID`)PARTITIONS 4/*+TDDL:load_data_auto_fill_auto_increment_column=true*/load data local infile './dataset/user_log_format1.csv' into table user_log FIELDS TERMINATED BY ',' IGNORE 1 LINES (user_id,item_id,cat_id,seller_id,brand_id,time_stamp,action_type)
执行冷数据一键迁移归档:
create table USER_LOG like sizetest.USER_LOG engine = 'oss' archive_mode = 'loading';
执行结果如下:




select logical_table_name, sum(table_rows),sum(extent_size)/1024/1024 as `size(MB)`from information_schema.fileswhere logical_schema_name = 'sizetest_oss'and remove_ts is nulland life_cycle = 1and logical_table_name in ('ACCESS_LOG', 'ngsim', 'orders', 'USER_LOG')group by logical_table_name;
查询结果如下:





基于LSM Tree的HBase,通常基于compaction做通用场景的优化,具备普适性,这也是业界NewSQL数据库基于LSM Tree做存储引擎所具备的能力,通用在3~4倍的压缩率。 PolarDB-X的热数据,默认采用MySQL InnoDB,整体的空间基本和开源MySQL对齐,PolarDB-X的冷数据,相比于PolarDB-X的热数据场景,平均有3~4倍的压缩,基本对齐LSM Tree的压缩场景,另外,面向字符和数值类型居多的场景最多有10倍的压缩效果。 PolarDB-X基于存储介质的选型和优化,PolarDB-X On OSS的冷数据归档,结合高压缩率以及HDD存储成本的优势,成本仅为PolarDB-X热数据的1/20,具体计算公式 = 1 (3~4倍压缩率 * 6倍的OSS存储成本优势)。
原理


参考文档:
《PolarDB-X on OSS: 冷热数据分离存储》
极低的冷数据存储成本,仅为在线热数据的1/20成本。
一个数据库实例,一个SQL引擎可以同时访问热数据和冷数据,具备跨数据的join/union/subquery等。在数据库运维上,冷热数据具备一体化的备份恢复能力,支持任意时间点恢复。
数据入湖,冷数据基于开源ORCFile通用格式,可以轻松对接Spark/Flink等开源生态,后续我们会开放对应Connector扩展接入大数据生态。

PolarDB-X 冷数据以开源格式ORC作为表文件的存储格式。ORC采用列式存储,并采取run-length encoding、dictionary encoding等算法对数值类型和字符类型进行高效编码。在此基础上,再选取LZ4压缩算法对编码后的数据进行通用压缩。由于PolarDB-X是MySQL生态下的分布式数据库,对MySQL数据类型完全兼容,因此还需要对MySQL主要数据类型进行不同的序列化设计,来适配ORC本身的压缩能力,从而将最终的存储空间优化到极致。


run-length encoding
run-length encoding是用于整数类型的一套编码算法,其思路来源于Protobuf 提出的varint数值压缩。主流语言都使用32bit或64bit的固定长度来存储数值,但是在实际场景中,绝大多数的数值是比较小的,有效数据只集中在低位字节。varint压缩算法将数值中每7个bit进行一次分隔,将分隔后的比特串按小端序排列;再用最高位的1bit来标识编码是否继续:比特位为为1代表编码继续,为0代表编码终止。以Java long类型数字551为例,原始数据占据64bit,二进制串为:00000000 00000000 00000000 00000000 00000000 00000000 00000010 00100111 varint算法先按7bit进行有效位的拆分,并以小端序排列,得到:0100111 0000100 再补齐最高的比特位:10100111 00000100

这样我们变得到了最终的压缩数据:0xA7 0x04。相比于原来8字节的固定长度,编码后的数据只占据2字节的空间。对于数值x,其压缩后的空间占用为:

例如将上述例子中的数值551带入,可以得到空间占用为2字节。
dictionary encoding



MySQL的数值类型中,bigint等整数类型可以直接应用于ORC;需要重点解决的是decimal类型的序列化设计。PolarDB-X采取多项式的形式来表示任意精度、任意小数的decimal;每个多项式系数使用integer整型存储,系数取值范围在10的9次方以内:

我们可以在此表示形式的基础上,将每个多项式的系数以更紧密的形式进行字节排列。例如对于数字1234567890.1234,可以拆分成多项式系数 1-234567890-123400000。将系数转化为16进制形式,再截取系数两端的0值,形成更紧密的字节排列,得到最终序列化结果0x01 0x0D 0xFB 0x38 0xD2 0x04 0xD2:

Decimal精度、小数位数与最终序列化后的大小关系如下,其中i代表整数部分长度,f代表小数部分长度:

例如对于decimal(15,2),其序列化得到的字节长度为7。



总结
参考文献
Apache ORC
https://orc.apache.org/specification/ORCv0/
ProtoBuf Varint
https://developers.google.com/protocol-buffers/docs/encoding
TPCH
http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/183466/cn_zh/1645604888228/tpchData%20%281%29.tar.gz
NGSIM数据集
https://data.transportation.gov/Automobiles/Next-Generation-Simulation-NGSIM-Vehicle-Trajector/8ect-6jqj
server log数据集
https://www.kaggle.com/datasets/eliasdabbas/web-server-access-logs
IJCAI-15数据集
https://tianchi.aliyun.com/dataset/dataDetail?spm=5176.12281978.0.0.1e4268d7WHdFvm&dataId=47
End /







点击"阅读原文" 查看PolarDB-X冷热分离存储评测更多信息







