数据的存储方式(Parquet、ORC)

这篇具有很好参考价值的文章主要介绍了数据的存储方式(Parquet、ORC)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据的存储方式

目前的数据存储方式分为行式和列式。

按行存储

  常见的关系型数据库,如Oracle、DB2、MySQL、SQL SERVER都是行式存储的, 在我们查询的条件需要得到大多数列的时候, 相对列式格式,查询效率更高。基础逻辑存储单元是行数据,在存储介质中是以连续存储的形式存在的。

Hive中的的TextFile文件存储格式中的数据就按行式存储的。

按列存储

大部分分布式分析型数据库,如Hbase、hive、Druid采用是列式存储,

  列式存储, 它存储的方式是采用数据按照行分块,每个块按照列存储。

数据表格
姓名 性别 年龄
张三 20
李四 30
王五 40
赵六 50
逻辑表
张三 李四 王五 赵六 20 30 40 50
按列存储
张三 20 李四 30 王五 40 赵六 50
按行存储

简单的对比

行式存储 列式存储
特点 1.每一行的所有字段都存在一起
2.查询时即使只涉及某几列,所有数据都会被读取
3.读取时硬盘寻址范围很大
4.适合事务性操作
5.主要用于在线交易处理(OLTP)场景的数据存储
1.每一列的所有数据存在一起,不同列之间支持分开存储
2.查询时只有涉及到的列会被读取
3.读取时硬盘寻道范围小
4.不适合事务性操作
5.主要用于在线分析处理(OLAP)场景的数据存储
优点 1.对数据进行插入和修改操作很方便
2.适合随机查询;在整行的读取上,要优于列式存储
1.采用每一列单独存储时,任何列都具有索引能力
2.同列数据具有相同类型,易于压缩,占用空间小
3.为每一列创建一个字典,存储的时候就仅存储数字编码,降低了存储空间需求
4.利用数据聚合操作
缺点 1.不适合扫描,这意味着要查询一个范围的数据
2.为加速查询会建索引,建立索引很耗时
3.不利于压缩,占用空间大
4.不适合聚合操作
1.插入和修改操作麻烦,不适合数据频繁变更的场景
2.查询完成时,被查询的列要重新进行组装
**文件格式 ** Text File、Sequence File、 Avro file RCFile、ORC File、Parquet、Arrow

数据通用压缩算法

  • Gzip
  • bzip2
  • LZO
  • LZ4
  • Snappy
  • zstd

Parquest

(一句话介绍)

Apache Parquet是一种列式存储格式,最初的目的是可供Hadoop生态系统中的任何项目使用,无论选择何种数据处理框架、数据模型或编程语言。

支持高校的压缩和编码方案。具有良好的向后兼容性。

文件布局

概念

block (hdfs块): 代表hdfs中的一个块,其含义对于Parquet这种文件格式来说是不变的。Parquet文件格式被设计为能在hdfs之上很好地工作。

File:一个hdfs文件,必须包括文件的元数据。它不需要实际包含数据。

Row group行组: 将数据横向分割成行的逻辑。对于行组来说,没有任何物理结构是可以保证的。一个行组由数据集中的每一列的列块组成。

Column chunk 列块: 一个特定列的数据块。这些数据生活在一个特定的行组中,并保证在文件中是连续的。

Page 页: 列块被划分为页。在概念上,一个页面是一个不可分割的单位(在压缩和编码方面)。在一个列块中可以有多个页面类型,它们交错排列。

在层次上,一个文件由一个或多个行组组成。一个行组中每一列正好包含一个列块。列块包含一个或多个页面。

并行处理的单元
处理框架 处理粒度
MapReduce File/Row group
IO Column chunk
编码/压缩 Page
文件逻辑结构图解

为了支持嵌套类型的数据,Parquet使用了definition层和repetition层的Dremel编码。

Definition 层指定了列的路径中有多少个可选字段被定义。

Repetition 层指定路径中的重复字段在什么地方有重复值。(Repetition 重复 重叠)

配置
Row Group Size 行组的大小

更大的行组允许更大的列块,从而可以执行更大的连续IO。较大的组也需要在写入路径上有更多的缓冲(或两次写入)。我们推荐行组大小为(512MB - 1GB)。由于整个行组可能需要被读取,我们希望它能完全容纳在一个HDFS块中。因此,HDFS块的大小也应该被设置得更大。一个优化的读取设置将是: 1GB的行组,1GB的HDFS块大小,每个HDFS文件有一个HDFS块。

❓HDFS的块的大小不是128MB或者512GB的吗?可以调整成1GB?或者是设置成128MB的倍数

Data Page Size 数据页的大小

数据页应该被认为是不可分割的(即最小的数据处理单元),所以较小的数据页允许更精细的读取(例如,单行查找)。较大的页面尺寸会产生较少的空间开销(较少的页眉)和解析开销(处理页眉)。注意:对于顺序扫描,预计不会一次读取一个页面;这不是IO块。建议页面大小为8KB

元数据

有三种类型的元数据:文件元数据(FileMetaData)、列(chunk)元数据和页眉元数据。所有的thrift结构都使用TCompactProtocol进行序列化。

数据页

对于数据页,这3个信息是在页眉之后连续编码的。我们有

  • 定义层的数据、
  • 重复层的数据、
  • 编码的值。页眉中指定的大小是所有3个部分的和。

数据页是必要存在的数据的。根据模式的定义,定义层和重复层是可选的。如果列不是嵌套的(即列的路径长度为1),我们不对重复层进行编码(它总是有1的值)。对于需要的数据,定义层被跳过(如果编码,它将总是有最大定义层的值)。

例如,在列非嵌套且是必需的情况下,页面中的数据只是编码后的值。

Hive下的Parquet实验

-- 创建专用数据库
create DATABASE if not EXISTS test_fileformat COMMENT '文件格式测试的库' WITH DBPROPERTIES ('createUser'='顾栋','date'='20230609');

-- 创建无非嵌套字段表
CREATE TABLE test_fileformat.parquet_test (
 id int,
 name string,
 d string
)
STORED AS PARQUET tblproperties ("orc.compress"="NONE");
-- 表创建完成之后 并非立即产生hdfs文件,只是创建了对于的hdfs路径

 INSERT INTO TABLE test_fileformat.parquet_test VALUES (1, '张三', '我是张三,呼叫李四'), (2, '李四', '我是李四,呼叫张三');
 INSERT INTO TABLE test_fileformat.parquet_test VALUES (3, '王五', '我是王五,呼叫赵六'),(4, '赵六', '');
 
 Drop table test_fileformat.parquet_test;
 
 -- 创建含嵌套字段表 tag是一个复杂类型 是一个struct的数组 struct里面有两个字段tagid,weight
create table test_fileformat.parquet_nested_test (uid string ,tag array<struct<tagid:string,weight:string>>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ' '
MAP KEYS TERMINATED BY ':'
STORED AS PARQUET tblproperties ("orc.compress"="NONE");

 INSERT INTO TABLE test_fileformat.parquet_nested_test select '221190xxx9',array(named_struct('tagid',cast(0.30 as string),'weight',cast(0.31 as string)),named_struct('tagid',cast(0.21 as string),'weight',cast(0.11 as string))) as tag;
 
 INSERT INTO TABLE test_fileformat.parquet_nested_test select '221190xxx9',array(named_struct('tagid',cast(0.30 as string),'weight',cast(0.31 as string)),named_struct('tagid',cast(0.21 as string),'weight',cast(0.11 as string))) as tag;
 
 Drop table test_fileformat.parquet_nested_test;
 
 DROP DATABASE test_fileformat;

文件系统

# hadoop dfs -ls -r /user/bigdata/hive/warehouse/test_fileformat.db/parque_test
-rwxr-xr-x   2 bigdata supergroup        595 2023-06-09 11:16 /user/bigdata/hive/warehouse/test_fileformat.db/parquet_test/000000_0

# hadoop dfs -ls -r /user/bigdata/hive/warehouse/test_fileformat.db/parquet_nested_test
 -rwxr-xr-x   2 bigdata supergroup        588 2023-06-09 14:46 /user/bigdata/hive/warehouse/test_fileformat.db/parquet_nested_test/000000_0_copy_1
-rwxr-xr-x   2 bigdata supergroup        588 2023-06-09 14:46 /user/bigdata/hive/warehouse/test_fileformat.db/parquet_nested_test/000000_0

Parquet简单工具的使用

根据Parquet文件的定义,每一个Parquet文件都可以单独进行读写和分析。可以使用parquet-cli工具进行简单操作。

java -cp parquet-cli-1.13.1.jar;dependency/* org.apache.parquet.cli.Main meta 000000_0
java -cp parquet-cli-1.13.1.jar;dependency/* org.apache.parquet.cli.Main schema 000000_0
java -cp parquet-cli-1.13.1.jar;dependency/* org.apache.parquet.cli.Main footer 000000_0

数据的存储方式(Parquet、ORC)

bag:袋子;一套,通过repetition:REPEATED表达字段的嵌套
数据的存储方式(Parquet、ORC)

支持的组件

  • Apache Hive
  • Apache HDFS
  • Apache Doris
  • Apache iceberg
  • Apace hudi

Apache ORC

(一句话介绍)

Apache Orc也是一种列式存储格式,最初主要是为了极大加速Apache Hive和提高存储在Apache Hadoop中的数据的存储效率,目的是支持高速处理和减小文件大小。

目前有Orc V0(伴随Hive 0.11发布)和ORC V1(伴随Hive 0.12发布)两个版本。

文件布局

文件由1个或1个以上的Stripe,一个文件页脚,一个后记组成。

文件逻辑结构图解

Orc文件的读取是反向读取,先读取文件尾部,解析出必要信息,再去读取具体数据。

文件尾部由三部分组成;

  • 文件元数据:包含stripe粒度的列统计。这些统计信息基于每个stripe评估的谓词下推启用输入拆分消除。在谓词下推的是时候会根据这些统计信息进行对stripe进行评估,来筛选数据。
  • 文件页脚:页脚部分包含文件正文的布局、类型模式信息、行数和每列的统计信息。
  • 后记(Postscript):提供解析文件其余部分的必要信息,包括文件的页脚和元数据部分的长度、文件的版本以及使用的一般压缩类型(例如 none、zlib 或 snappy)。
Stripe

文件的主体被分成stripes。 每个stripe都是独立的,可以仅使stripe被本身的字节与文件的页脚和后记相结合来读取(每个stripe可以被独立的读取)。大小一般为200+MB。

stripe包含三个部分:

  • 索引流:未加密的数据在前,加密的数据在后,行组索引由每个原始列的 ROW_INDEX 流组成,每个原始列都有一个行组条目。 行组由编写器控制,默认为 10,000 行。 每个 RowIndexEntry 给出列的每个流的位置和该行组的统计信息。因为在默认的流式传输情况下不需要读取索引。 它们仅在使用谓词下推或读取器查找特定行时加载使用。
  • 数据流:未加密的数据在前,加密的数据在后
  • stripe的页脚:包含每一列的编码和流的目录,包括它们的位置

encryptStripeId 和 encryptedLocalKeys 支持列加密。 它们设置在每个带有列加密的 ORC 文件的第一个stripe上,之后不设置。

Hive下的Parquet实验

-- 创建专用数据库
create DATABASE if not EXISTS test_fileformat COMMENT '文件格式测试的库' WITH DBPROPERTIES ('createUser'='顾栋','date'='20230609');

-- 创建无非嵌套字段表
create table test_fileformat.orc_test (
 id int,
 name string,
 d string
) stored as orc tblproperties ("orc.compress"="NONE");

 INSERT INTO TABLE test_fileformat.orc_test VALUES (1, '张三', '我是张三,呼叫李四'),(2, '李四', '我是李四,呼叫张三');
 INSERT INTO TABLE test_fileformat.orc_test VALUES (3, '王五', '我是王五,呼叫赵六'),(4, '赵六', '');
 
 Drop table test_fileformat.orc_test;
 
 -- 创建含嵌套字段表 tag是一个复杂类型 是一个struct的数组 struct里面有两个字段tagid,weight
create table test_fileformat.orc_nested_test (uid string ,tag array<struct<tagid:string,weight:string>>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ' '
MAP KEYS TERMINATED BY ':'
STORED AS orc tblproperties ("orc.compress"="NONE");

 INSERT INTO TABLE test_fileformat.orc_nested_test select '221190xxx9',array(named_struct('tagid',cast(0.30 as string),'weight',cast(0.31 as string)),named_struct('tagid',cast(0.21 as string),'weight',cast(0.11 as string))) as tag;
 
 INSERT INTO TABLE test_fileformat.orc_nested_test select '221190xxx9',array(named_struct('tagid',cast(0.30 as string),'weight',cast(0.31 as string)),named_struct('tagid',cast(0.21 as string),'weight',cast(0.11 as string))) as tag;
 
 Drop table test_fileformat.orc_nested_test;
 
 DROP DATABASE test_fileformat;

文件系统

 # hadoop dfs -ls -r /user/bigdata/hive/warehouse/test_fileformat.db/orc_test

-rwxr-xr-x   2 bigdata supergroup        502 2023-06-09 17:16 /user/bigdata/hive/warehouse/test_fileformat.db/orc_test/000000_0_copy_1
-rwxr-xr-x   2 bigdata supergroup        611 2023-06-09 17:15 /user/bigdata/hive/warehouse/test_fileformat.db/orc_test/000000_0

# hadoop dfs -ls -r /user/bigdata/hive/warehouse/test_fileformat.db/orc_nested_test

-rwxr-xr-x   2 bigdata supergroup        590 2023-06-09 17:19 /user/bigdata/hive/warehouse/test_fileformat.db/orc_nested_test/000000_0_copy_1
-rwxr-xr-x   2 bigdata supergroup        590 2023-06-09 17:19 /user/bigdata/hive/warehouse/test_fileformat.db/orc_nested_test/000000_0

ORC简单工具的使用

# 查看orc的元数据信息
java -jar orc-tools-1.8.3-uber.jar meta -p 000000_0

# 查看orc文件中的记录数
java -jar orc-tools-1.8.3-uber.jar data -n 2 000000_0

数据的存储方式(Parquet、ORC)
数据的存储方式(Parquet、ORC)

支持的组件

  • Apache Hive
  • Apache HDFS
  • Apache Doris
  • Apache iceberg
  • Apace hudi

数据存储中的编码

字典编码

位打包

增量编码

游程编码

二进制编码方式

Thrift

avro

arrow文章来源地址https://www.toymoban.com/news/detail-486303.html

到了这里,关于数据的存储方式(Parquet、ORC)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python导出数据为parquet格式

    import duckdb import pandas as pd from sqlalchemy import create_engine # 定义连接到您的 MySQL 或 PostgreSQL 数据库的参数 db_type = \\\'mysql\\\'  # 或 \\\'postgresql\\\' user = \\\'your_username\\\' password = \\\'your_password\\\' host = \\\'your_host\\\' port = \\\'your_port\\\' database = \\\'your_database\\\' table_name = \\\'your_table\\\' # 创建 SQLAlchemy 引擎 if db_type == \\\'mys

    2024年01月25日
    浏览(48)
  • HIVE表数据快速构造(分区表、orc、text)

    引言 当需要在hive数仓中去创建测试表并构造测试数据时,通常需要在安装了hive客户端的服务器环境下,通过执行命令的方式建表。通过在HDFS上上传和加载数据文件的方式来加载数据到hive表中。其中操作算不得多复杂,但比较依赖对环境和命令的熟悉,并且操作不够可视化

    2024年02月16日
    浏览(47)
  • 大数据_Hadoop_Parquet数据格式详解

    之前有面试官问到了parquet的数据格式,下面对这种格式做一个详细的解读。 参考链接 : 列存储格式Parquet浅析 - 简书 Parquet 文件结构与优势_parquet文件_KK架构的博客-CSDN博客 Parquet文件格式解析_parquet.block.size_david\\\'fantasy的博客-CSDN博客 行组(Row Group)  按照行将数据物理上划分为

    2024年02月14日
    浏览(42)
  • 大数据存储方式有哪些?

    本文隶属于专栏《大数据从 0 到 1》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和文献引用请见《大数据从 0 到 1》 数据常用的存储介质为磁盘和磁带。 数据存储组织方式因存储介质不同而异。 在磁带上数据仅按顺

    2024年02月07日
    浏览(39)
  • Python 数据存储 ---->方式

    我的个人博客主页:如果’\\\'真能转义1️⃣说1️⃣的博客主页 关于Python基本语法学习----可以参考我的这篇博客:《我在VScode学Python》 缕清一个关系–文本和文件的关系 1 最简单的就是文本文件,扩展名 .txt 对于大多数的平台或者系统都兼容的很好。 二进制文件是指以二进制

    2024年02月01日
    浏览(36)
  • JavaScript数据存储方式

    内置对象 js内部提供的对象,包含各种属性和方法给开发者调用 document.write() console.log() Math Math对象是js提供的一个 “数学”对象,提供了一系列做 数学运算 的方法 max 找最大值 Math.max(3,8,5,4) 返回8 min 找最小值 Math.min(3,8,5,4) 返回4 abs 绝对值 Math.abs(-1) 返回1 ceil 向上取整 Mat

    2024年02月12日
    浏览(40)
  • 数据加密存储常见的加密方式

    下面详细说下数据加密存储常见的加密方式 数据加密存储方式一、MD5加密(加密不可逆) MD5的全称是Message-Digest Algorithm 5(信息摘要算法)。128位长度。目前MD5是不可逆算法。具有很高的安全性。对应任意字符串,可以加密成唯一的固定长度代码。 那为什么MD5加密算法是不

    2023年04月08日
    浏览(49)
  • Flink之FileSink将数据写入parquet文件

    在使用FileSink将数据写入列式存储文件中时必须使用 forBulkFormat ,列式存储文件如 ORCFile 、 ParquetFile ,这里就以 ParquetFile 为例结合代码进行说明. 在Flink 1.15.3 中是通过构造 ParquetWriterFactory 然后调用 forBulkFormat 方法将构造好的 ParquetWriterFactory 传入,这里先讲一下构造 ParquetWriterF

    2024年02月03日
    浏览(45)
  • 记csv、parquet数据预览一个bug的解决

    工作中遇到通过sparksession解析csv、parquet文件并预览top100的需求。 为了便于测试,下面在单元测试中使用模拟数据( 模拟Dataset.toJSON()返回值 )来说明 目前看来似乎一切正常。 实际测试过程中发现,hive数据仓库中的字段由于各种原因并不一定都有值,从而导致保存的结果文

    2024年01月19日
    浏览(35)
  • Unity——数据存储的几种方式

    PlayerPrefs适合用于 存储简单的键值对数据 存储的数据会在游戏关闭后依然保持,并且可以在不同场景之间共享,适合用于需要在游戏不同场景之间传递和保持的数据。 它利用key-value的方式将数据保存到本地,跟字典类似。然后通过代码进行保存、读取、更新操作。值得注意

    2024年02月03日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包