ORC文件格式的三种压缩算法的对比
1.ORC格式简介
ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度,2015年ORC项目被Apache项目基金会提升为Apache顶级项目。ORC格式并不是一个单纯的列式存储格式,首先根据行组分割整个表,然后在每一个行组内进行按列存储。ORC文件是自描述的,它的元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗。ORC具有以下一些优势:
- ORC是列式存储,有多种文件压缩方式,并且有着很高的压缩比。
- 文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储资源,查询任务的输入数据量减少,使用的MapTask也就减少了。
- 提供了多种索引,row group index、bloom filter index。
- ORC可以支持复杂的数据结构(比如Map等)。
目前ORC格式被Spark SQL、Presto等多种查询引擎支持,GaussDB DWS中的HDFS外表和OBS外表也都支持ORC格式。
2. ORC格式的三种压缩算法及其性能对比
由于节省存储空间作为ORC文件格式的一大优势,压缩作为ORC格式的核心特性之一,ORC文件格式目前支持snappy、zlib、lz三种压缩算法,为了更好地了解三种压缩格式的差别,进行对比测试如下:
- 测试内容
通过OBS外表,对比测试ORC文件格式的三种压缩算法snappy、zlib、lz4的读写性能和压缩比。
- 测试方案
使用TPCH 1x的lineitem的表作为测试数据,其原始文件大小为736MB,将其导入GaussDB DWS数据库内。通过OBS 的ORC格式只写外表和只读外表分别导出和读取ORC格式的数据,记录相应的时间和文件的大小。
- 测试环境
部署规格: 2CN 6DN
节点规格: dws.physical.ki.32xlarge.4
规格详情: 标准数仓 | 128 vCPUs | 512 GB 内存 | 14,901 GB SSD
- 测试步骤
- 创建TPCH的lineitem的GaussDB DWS的内表,通过insert-select语句的方式将1x的TPCH的数据插入lineitem表中;
- 通过gsql连接数据库,并通过\timing on开启时间统计功能;
- 创建三张不同压缩格式snappy、zlib,lz4的ORC格式的OBS只写外表;
- 通过Insert-Select语句将内表的数据通过三种不同压缩格式的只写外表导出数据,记录导出时间,并记录导出后OBS文件的大小,得出压缩比。
- 创建三张不同obs的ORC格式的只读外表分别指向三种不同压缩格式的导出路径;
- 通过select带条件查询语句分别查询上述三张只读外表的数据,记录查询时间。
测试脚本如下:
--1.创建OBS SERVER
CREATE SERVER obs_server FOREIGN DATA WRAPPER
dfs_fdw OPTIONS (
address 'obs.XXXX.server',
type 'obs',
encrypt 'off',
access_key 'XXXXXXX',
secret_access_key 'XXXX');
DROP FOREIGN TABLE FT_CUSTOMER_TEXT;
--2 测试OBS ORC三种压缩格式的读写性能和压缩比
--create lineitem
--空间压缩
DROP TABLE lineitem;
CREATE TABLE lineitem (
L_ORDERKEY INTEGER NOT NULL,
L_PARTKEY INTEGER NOT NULL,
L_SUPPKEY INTEGER NOT NULL,
L_LINENUMBER INTEGER NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL);
INSERT INTO lineitem SELECT * from ft_lineitem_orc;
---------------------snappy compress -----------------------------
--export data to obs snappy compres type
DROP FOREIGN TABLE ft_lineitem_orc_wt_snappy;
CREATE FOREIGN TABLE ft_lineitem_orc_wt_snappy(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)SERVER obs_server
OPTIONS (format 'orc',
foldername '/user/obs_test/tpch/orc_lineitem_wt_snappy/',
encoding 'UTF8',
compression 'snappy'
) WRITE ONLY;
insert into ft_lineitem_orc_wt_snappy select * from lineitem;
--read expored data
DROP FOREIGN TABLE ft_lineitem_orc_rd_snappy;
CREATE FOREIGN TABLE ft_lineitem_orc_rd_snappy(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)SERVER obs_server
OPTIONS (format 'orc',
location 'obs://user/obs_test/tpch/orc_lineitem_wt_snappy/',
encoding 'UTF8',
totalrows '6001215'
)DISTRIBUTE BY ROUNDROBIN;
DROP TABLE lineitem_orc_rd_snappy;
CREATE TABLE lineitem_orc_rd_snappy(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
);
INSERT INTO lineitem_orc_rd_snappy SELECT * from ft_lineitem_orc_rd_snappy;
DROP TABLE lineitem_orc_rd_snappy;
--------------------zlib compress ---------------------------------
--export data to obs compres type zlib
DROP FOREIGN TABLE ft_lineitem_orc_wt_zlib;
CREATE FOREIGN TABLE ft_lineitem_orc_wt_zlib(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)SERVER obs_server
OPTIONS (format 'orc',
foldername '/user/obs_test/tpch/orc_lineitem_wt_zlib/',
encoding 'UTF8',
compression 'zlib'
) WRITE ONLY;
insert into ft_lineitem_orc_wt_zlib select * from lineitem;
--read expored data
DROP FOREIGN TABLE ft_lineitem_orc_rd_zlib;
CREATE FOREIGN TABLE ft_lineitem_orc_rd_zlib(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)SERVER obs_server
OPTIONS (format 'orc',
location 'obs://user/obs_test/tpch/orc_lineitem_wt_zlib/',
encoding 'UTF8',
totalrows '6001215'
)DISTRIBUTE BY ROUNDROBIN;
DROP TABLE lineitem_orc_rd_zlib;
CREATE TABLE lineitem_orc_rd_zlib(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
);
insert into lineitem_orc_rd_zlib select * from ft_lineitem_orc_rd_zlib;
--------------------------lz4 compress type -------------------------------
--export data to obs compres type zlib
DROP FOREIGN TABLE ft_lineitem_orc_wt_lz4;
CREATE FOREIGN TABLE ft_lineitem_orc_wt_lz4(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)SERVER obs_server
OPTIONS (format 'orc',
foldername '/user/obs_test/tpch/orc_lineitem_wt_lz4/',
encoding 'UTF8',
compression 'lz4'
) WRITE ONLY;
insert into ft_lineitem_orc_wt_lz4 select * from lineitem;
--read expored data
DROP FOREIGN TABLE ft_lineitem_orc_rd_lz4;
CREATE FOREIGN TABLE ft_lineitem_orc_rd_lz4(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)SERVER obs_server
OPTIONS (format 'orc',
location 'obs://user/obs_test/tpch/orc_lineitem_wt_lz4/',
encoding 'UTF8',
totalrows '6001215'
)DISTRIBUTE BY ROUNDROBIN;
DROP TABLE lineitem_orc_rd_lz4;
CREATE TABLE lineitem_orc_rd_lz4(
L_ORDERKEY BIGINT NOT NULL,
L_PARTKEY BIGINT NOT NULL,
L_SUPPKEY BIGINT NOT NULL,
L_LINENUMBER BIGINT NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
);
insert into lineitem_orc_rd_lz4 select * from ft_lineitem_orc_rd_lz4;
- 测试数据和测试结论
测试类型 |
snappy |
zlib |
lz4 |
|
写性能 |
导出时间 |
27656.261ms |
28572.727ms |
27019.114ms |
单节点速率 |
88.71M/s |
85.86M/s |
90.80M/s |
|
读性能 |
测试时间 |
4042.824ms |
4646.377ms |
4464.472ms |
单节点速率 |
60.68M/s |
52.8M/s |
54.95M/s |
|
压缩性能 |
压缩后文件大小 |
210.288MB |
144.216MB |
187.668MB |
压缩比 |
3.5 |
5.1 |
3.92 |
|
测试结论 |
1. snappy读取性能最优; |
3.三种压缩格式的应用场景
通过上面的性能测试可以看出,ORC格式的三种压缩算法的各自应用场景:
- 当我们需要压缩比更高时,推荐采用zlib压缩算法;
- 当需要orc格式读取性能更高时,推荐采用snappy压缩算法,也是GaussDB DWS中ORC格式外表所默认推荐的压缩算法;
- 当需要orc格式写性能更高时,则推荐采用lz4压缩算法。
- 点赞
- 收藏
- 关注作者
评论(0)