ORC文件格式的三种压缩算法的对比

举报
圆圆木公 发表于 2021/06/10 21:58:13 2021/06/10
【摘要】 ORC文件格式是一种Hadoop生态圈中的列式存储格式,被多种查询引擎支持,而压缩作为ORC格式的核心特性,其支持snappy、zlib、lz三种压缩算法,本文通过对这三种压缩算法进行性能对比测试,得出其三种算法不同的应用场景。

1.ORC格式简介

       ORC的全称是(Optimized Row Columnar)ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度,2015ORC项目被Apache项目基金会提升为Apache顶级项目。ORC格式并不是一个单纯的列式存储格式,首先根据行组分割整个表,然后在每一个行组内进行按列存储。ORC文件是自描述的,它的元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗。ORC具有以下一些优势:

  • ORC是列式存储,有多种文件压缩方式,并且有着很高的压缩比。
  • 文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储资源,查询任务的输入数据量减少,使用的MapTask也就减少了。
  • 提供了多种索引,row group indexbloom filter index
  • ORC可以支持复杂的数据结构(比如Map等)。

     目前ORC格式被Spark SQLPresto等多种查询引擎支持,GaussDB DWS中的HDFS外表和OBS外表也都支持ORC格式。

2. ORC格式的三种压缩算法及其性能对比

       由于节省存储空间作为ORC文件格式的一大优势,压缩作为ORC格式的核心特性之一,ORC文件格式目前支持snappy、zliblz三种压缩算法,为了更好地了解三种压缩格式的差别,进行对比测试如下:

  • 测试内容

      通过OBS外表,对比测试ORC文件格式的三种压缩算法snappyzliblz4的读写性能和压缩比。

  • 测试方案

       使用TPCH 1x的lineitem的表作为测试数据,其原始文件大小为736MB,将其导入GaussDB DWS数据库内。通过OBS ORC格式只写外表和只读外表分别导出和读取ORC格式的数据,记录相应的时间和文件的大小。

  • 测试环境   

      部署规格: 2CN 6DN
      节点规格: dws.physical.ki.32xlarge.4
      规格详情: 标准数仓 | 128 vCPUs | 512 GB 内存 | 14,901 GB SSD

  • 测试步骤
  1. 创建TPCHlineitem的GaussDB DWS的内表,通过insert-select语句的方式将1xTPCH的数据插入lineitem表中;
  2. 通过gsql连接数据库,并通过\timing on开启时间统计功能;
  3. 创建三张不同压缩格式snappyzlib,lz4ORC格式的OBS只写外表;
  4. 通过Insert-Select语句将内表的数据通过三种不同压缩格式的只写外表导出数据,记录导出时间,并记录导出后OBS文件的大小,得出压缩比。
  5. 创建三张不同obsORC格式的只读外表分别指向三种不同压缩格式的导出路径;
  6. 通过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读取性能最优;
2. zlib压缩比最高;
3. lz4写性能最优。

3.三种压缩格式的应用场景

     通过上面的性能测试可以看出,ORC格式的三种压缩算法的各自应用场景:

  • 当我们需要压缩比更高时,推荐采用zlib压缩算法;
  • 当需要orc格式读取性能更高时,推荐采用snappy压缩算法,也是GaussDB DWSORC格式外表所默认推荐的压缩算法;
  • 当需要orc格式写性能更高时,则推荐采用lz4压缩算法。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。