一篇文章彻底理解大数据的列式存储

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 一篇文章彻底理解大数据的列式存储

大家好,我是明哥!

本片文章,跟大家一起探讨下,列式存储与数据质量的相关话题。

1. 什么是列式存储

  • 所谓行式存储,指存储结构化数据时,在底层的存储介质上,数据是以行的方式来组织的,即存储完一条记录的所有字段,再存储下一条数据的所以字段,以此类推;
  • 所谓列式存储,指存储结构化数据时,在底层的存储介质上,数据时以列的方式来组织的,即存储完若干条记录的首个字段后,再存储这些记录的第二个字段,然后是这些记录的第三个字段,以此类推,当这些记录的所有字段存储完毕后,再按照这种方式,组织存储下一批若干条记录的所有字段;

比如需要存储以下记录:

姓名 年龄 工资

则行存储格式,底层是这样组织的:(示意图)

image.png


而列存储格式,底层是这样组织的:(示意图)

image.png


说明:

  • 以上只是示意图,实际存储时,往往还会存储一些元数据,比如校验信息,统计信息等等;(列式存储往往会存储更多的元数据信息,以便于检索/查询/统计等)
  • 行存储与列存储,存储的都是结构化数据;(非结构化数据,就无所谓行和列了)
  • 行存储和列存储,描述的是底层存储介质上,数据的组织形式,而存储介质可以是磁盘,也可以是内存;存储介质的上次建筑,可以是文件系统,也可以是对象存储;
  • 很多数据库,在底层即支持行存储,也支持列存储,这两者有时是同时混合使用的;(比如 oracle12c,就引入了对 In-Memory Column Store 的支持;再比如 TiDB, 底层同时支持行存储引擎 TiKV 和 列存储引擎 TiFlash);

2. 深入了解列式存储 - 以 Parquet 为例

说到当下最流行的开源列式存储引擎,就非 apache parquet 莫属了。

  • 绝大多数计算引擎,比如 apache spark/presto/impala/flink, 都将 parquet 作为首选的列示存储引擎;
  • orc 是 apache hive 社区推出的,另一款开源列示存储引擎;
  • apache hive 在早期只支持 orc 列示存储的基础上,有扩展了对 parquet 的支持;

有鉴于此,我们有必要以 parquet 为例,来深入了解下列示存储。

以下是 parquet 底层,数据的组织格式:

image.png

相关述语解释如下:

  • Block (hdfs block): 指 hdfs 文件系统的 block,parquet 是在 hdfs 文件之上的数据组织格式;(当然现在很多对象存储系统,比如 S3,也支持 parquet 存储格式);
  • File: 指 hdfs 文件,使用 parquet 格式时,每个 hdfs 文件底层必须包括 parquet 元数据 - 事实上该文件底层可以不包含数据,但必须包含元数据;(当然现在很多对象存储系统,比如 S3,也支持 parquet 存储格式);
  • Row group: 文件底层的所有数据,在逻辑上被水平切割,每个 row group 存储的都是一份这些被水平切割后的数据。(row group 是对数据的水平切,分比如上图中,就显示了 row group 0 和 row group1 两个 row group);
  • Column chunk: 每个 row group 底层都包含一系列 column chunk,每个colum 都有一个对应的 column chunk;(数据有多少列,水平切割的每个 row group底层,就有多少个 column chunk);
  • Page: Column chunks 被进一步切分为若干个 page 页,page 是压缩和编码的最小单位;(比如上如,row group0 的 Column a,就显示了两个 page: page a 和 page b);

概括如下:

  • 每个文件由一个或多个 row group 构成,每个 row group 包含了多个 column chunk (column chunk 和 column 是 一一对应的),Column chunks 包含了一个或多个 page;
  • MR 等计算作业,其并行操作的单位是 File/Row Group;
  • IO 的单位是 Column chunk;
  • 编码和压缩的单位是 Page;

3. 行式存储与列式存储的优劣势都有哪些

通过上述对底层数据组织格式的对比,不难发现,行存储有以下特点:

  • 行存储将每条数据的所有列连续存储在一起,一条记录接着一条记录;
  • 行存储中数据写入的成本较低,适合数据有频繁更新的场景;
  • 通过使用索引,能大幅提高行存储的数据查询速度;
  • 行存储是传统的数据组织形式,更适合传统的 OLTP 系统;(OLTP 数据库表的设计强调范式,底层一般有多张有关联关系的窄表)

而列存储有以下特点:

  • 列存储将多行记录的列连续存储在一起,一列接着一列;
  • 由于连续存储在一起的列的数据类型都一样,所以数据压缩率更高,更省存储空间;
  • 列存储中数据查询的成本较低,特别适合分析时只查询部分列的场景,因为不需要扫描/读取不需要查询的列;
  • 列存储由于数据更新成本较高,一般适合读多写少的场景;(但是不代表不能更新!)
  • 列存储是新型数据组织形式,更适合 OLAP 分析型系统;(OLAP数据库表的设计强调反范式,底层一般是星型模式的若干张事实表和维度表,倾向使用大宽表)

4. 列式存储与数据质量

各厂各司在其数据仓库或数据湖泊的数据规范部分,大都强调要尽可能地使用列式存储格式,而尽可能不要使用行式存储格式。

究其原因,一方面是列式存储相比行式存储,其压缩率更高读写效率更快;另一方面是因为,相比行式存储,列式存储的数据质量更高!

之所以说列示存储能提高数据质量,更准确地说,是有些行式存储会降低数据质量,比如 csv/tsv 等 TextFile。

比如,以我们熟悉的 HIVE 为例,一个常见的 DDL 语句如下:

CREATE TABLE student_text_test(                       
   id double,                                     
   name string,                                   
   sex double,                                    
   age double,                                    
   class double,                                  
   address string)    
   ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
 STORED AS TEXTFILE;
  • 大家可以看到,TextFile 的 DDL 语句中,需要通过 xx terminated by xx 来指定列分隔符和行分隔符(列分隔符默认是'\001',行分隔符默认是'\n');
  • 而上游rdbms表中某些字段,可能会包含特殊字符比如换行符,此时就可能会跟上述textfile 表的 DDL 语句中指定的列分隔符或分隔符冲突;
  • 后续通过数据同步工具比如 sqoop/datax/spark sql 等同步上游数据到 hive中 textfile 格式的表时,同步作业可以执行成功;
  • 但是后续再查询该同步的 textfile 格式的表时,因为大数据schema on read 的特性,在读数据时按就会按照 DDL 中指定的行和列分隔符来切割数据,此时就可能会因为行分隔符造成数据切割混乱,从而查出大量 NULL 字段的错乱数据;
  • 不幸的是,上游 RDBMS 中的数据往往不受大数据部门管控,会出现各种各样的奇怪数据;
  • 更不幸的是,目前hive的textfile只支持\n作为行分隔符(验证了cdh6.3,也就是hive2.1)

所以,正式出于数据质量的原因,各厂各司在其数据仓库或数据湖泊的数据规范部分,大都强调:

  • 要尽可能地使用列式存储格式比如orc/parquet,而尽可能不要使用行式存储格式textfile;
  • 数仓中各层,包括 ods/dwd/dws/ads ,以及业务临时表与技术临时表,都尽量不要使用textfile;
  • 除非是选用的数据同步工具不支持orc/parquet(比如sqoop),且此时也仅仅只能在 ods层的落地表中使用textfile, 后面 dws等各层需要切换使用列示存储 orc/parquet;
  • 必要时,对数据同步工具重新进行技术选型,比如抛弃不支持列示存储的 sqoop, 而选用支持列示存储的 spark sql/datax 等。
相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
相关文章
|
4月前
|
存储 算法 数据挖掘
【2023年中国高校大数据挑战赛 】赛题 B DNA 存储中的序列聚类与比对 Python实现
本文介绍了2023年中国高校大数据挑战赛赛题B的Python实现方法,该赛题涉及DNA存储技术中的序列聚类与比对问题,包括错误率分析、序列聚类、拷贝数分布图的绘制以及比对模型的开发。
98 2
【2023年中国高校大数据挑战赛 】赛题 B DNA 存储中的序列聚类与比对 Python实现
|
1月前
|
存储 算法 固态存储
大数据分区优化存储成本
大数据分区优化存储成本
32 4
|
2月前
|
存储 消息中间件 大数据
大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
49 4
|
2月前
|
消息中间件 存储 缓存
大数据-71 Kafka 高级特性 物理存储 磁盘存储特性 如零拷贝、页缓存、mmp、sendfile
大数据-71 Kafka 高级特性 物理存储 磁盘存储特性 如零拷贝、页缓存、mmp、sendfile
76 3
|
2月前
|
存储 消息中间件 大数据
大数据-70 Kafka 高级特性 物理存储 日志存储 日志清理: 日志删除与日志压缩
大数据-70 Kafka 高级特性 物理存储 日志存储 日志清理: 日志删除与日志压缩
51 1
|
2月前
|
存储 消息中间件 大数据
大数据-68 Kafka 高级特性 物理存储 日志存储概述
大数据-68 Kafka 高级特性 物理存储 日志存储概述
33 1
|
2月前
|
存储 算法 NoSQL
大数据-138 - ClickHouse 集群 表引擎详解3 - MergeTree 存储结构 数据标记 分区 索引 标记 压缩协同
大数据-138 - ClickHouse 集群 表引擎详解3 - MergeTree 存储结构 数据标记 分区 索引 标记 压缩协同
41 0
|
2月前
|
存储 消息中间件 分布式计算
大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引
大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引
43 0
|
2月前
|
存储 SQL 分布式计算
大数据-127 - Flink State 04篇 状态原理和原理剖析:状态存储 Part2
大数据-127 - Flink State 04篇 状态原理和原理剖析:状态存储 Part2
21 0
|
2月前
|
存储 消息中间件 大数据
大数据-126 - Flink State 03篇 状态原理和原理剖析:状态存储 Part1
大数据-126 - Flink State 03篇 状态原理和原理剖析:状态存储 Part1
72 0