parquet

news/2024/10/30 0:28:34/

一、parquet结构

在这里插入图片描述

Row Group

​ --Column Chunk:一列对应一个Column Chunk

​ – Page:压缩和编码的单元,parquet的 min/max 索引是针对于page的,存在了文件的页脚。以前的版本是存储Column Chunk和Page的索引,导致在决定是否跳过的时候,都必须读取Page的头文件来决定。

对比orc索引,感觉更优秀

数据编码和orc很像,就不细说了

二、parquet对于嵌套数据类型的处理

2.1 数据模型(数据定义时候用的)

parquet处理嵌套数据的思路来源于Google的Dremel系统(Dremel是Google研发的一个即席查询系统,因为Google处理的数据一般都是网页数据,会有很多嵌套类型,下文把这种数据存储方式简称为Dremel)。

parquet不需要复杂类型,如Map、List或Set,因为它们可以映射到repeated fields 和 groups的组合。

Dremel支持的数据类型:group 和 原子数据类型 (int, float, boolean, string)

Dremel根据数据的出现次数把数据分成了三种类型:

  • required:出现且仅出现一次
  • optional:出现0次或1次
  • repeated:出现0次或多次

例:

在这里插入图片描述

2.2 存储(数据存储时候用的)

为了把数据可以组装到一起,定义两个存储级别:Repetition levels 和 Definition levels,如 Fig3

Repetition levels:表示值在字段路径中有几个重复。作用是为了解析非null字段。

如上述示例,Name.Language.Code路径中有两个重复字段,Name和Language,因此Code的重复级别范围是0~2(Name:1,Language:2),0表示新的记录开始。

如果从上往下扫描r1和r2的数据,'en-us’是一个新的Code,所以它的r level是0,'en’是在Language中重复,所以它的 r level是2,

'en-gb’是在Name中重复的,在这个Name中没有重复的Language,所以它的 r level是1。

Definition levels:表示有多少个字段可能未定义(因为它们是可选的或重复的)。作用是为了处理null。

如上述示例,DocId是required,所以它的d level是0;conntry的d level范围是1~3,如果有d level < 3,表示该country是null。

2.3 实现List和Map

2.3.1 List

//optional or required
<list-repetition> group <name> (LIST) {//必须是repeated,我认为是为了识别到下一个list,当很多行的list都存在了一列,怎么识别出来哪个元素是哪个列的repeated group list {//optional or required<element-repetition> <element-type> element;}
}

在这里插入图片描述

​ 如上图,只有根节点才会存储数据,通过r的级别就可以组装出list

2.3.2 Map

//optional or required
<map-repetition> group <name> (MAP) {repeated group key_value {//只要map里有值,key就不能是nullrequired <key-type> key;//optional or required<value-repetition> <value-type> value;}
}

在这里插入图片描述

三、parquet VS orc

3.1 嵌套数据

parquet在存储嵌套数据上更有优势,orc适用于存储扁平化的数据。我理解orc存储的struct或者map都是一条记录只出现一次的,如果想是上述案例中的一条记录可能有多个Code,这种orc不太适合。

3.2 2013年的对比(参考自Orc作者的演讲PPT)

在这里插入图片描述

上图中,Parquet里写 “N” 的地方,在新版本都有实现了!

​ 目前,Orc比Parquet多的一个特性是acid。

3.3 2016年的对比(分数据集对比)

3.3.1 NYC Taxi Data

**数据特点:**18列,22.7million行,类型有double,integer,dicimal,string,没有null

存储对比:

在这里插入图片描述

第一次存储对比结论:

  1. 不能用json!

  2. parquet要比orc优秀。

    orc作者不服,所以又按照列的类型进行了对比

按照存储类型对比:

在这里插入图片描述

按存储类型对比结论:

  1. 在double上parquet远优于orc,在timestamp上orc远优于parquet,因为parquet没有支持timestamp类型,而是用Logical type支持的。在其他字段的存储上都一样。

扫描全表对比:

在这里插入图片描述

扫描全表结论

  1. 有时候压缩也不一定会导致变慢

3.3.2 Github Logs

**数据特点:**704列,10.5 million 行,有大量的 structure 和 null

存储对比:

在这里插入图片描述

存储对比结论:

  1. zlib最优秀
  2. Avro最优秀,因为行string被压缩了

扫描全表对比:

在这里插入图片描述

扫描全表对比结论:

  1. Parquet表现的很差,有一部分原因是用在了垃圾回收上

在这里插入图片描述

3.3.3 对于只取少数列

在这里插入图片描述

3.4 spark sql的对比

数据集介绍:

case class PageImpression(userId: Long,date: Timestamp,refererUrl: String
)
21.2 G  avro
15.1 G  orc
30.2 G  parquet

在这里插入图片描述

注意date是timestamp类型的

case class Order(userId: Long,orderNo: String,date: Timestamp,productId: Int,productCode: String,productTitle: String,productPrice: Float,boughtPrice: Float,discountPercentageApplied: Byte
)
124.2 G  avro
93.4 G   orc
103.3 G  parquet

在这里插入图片描述

3.4 结论

  1. 存储格式的对比还是要真正的在实践中检测,在使用的时候,不仅要考虑到它本身设计的优越性,还要考虑到垃圾回收、真实数据在存储格式上的性能这些意想不到的事情。
  2. hive适合orc,spark适合parquet,这个结论现在看来不一定所有情况都适用,还需要具体实验。从网上看到说这个原因是因为spark在parquet上只吃了Vectorization机制,hive在orc上支持了Vectorization机制,要讲一下这个。
  3. 在2016年,orc要优于parquet,orc作者建议除了在少数情况下用Avro结合snappy,其余情况用orc结合zlib就行了!
  4. 以上的结论都是orc作者在2016年发表演讲中提到的,现在是什么情况还不能确定,因为每个格式都在发展!

参考文献

Performance of Avro, Parquet, ORC with Spark Sql:https://www.linkedin.com/pulse/performance-avro-parquet-orc-spark-sql-konstantine-kougios

dremel-made-simple-with-parquet:https://blog.twitter.com/engineering/en_us/a/2013/dremel-made-simple-with-parquet

Difference Between ORC and Parquet:http://www.differencebetween.net/technology/difference-between-orc-and-parquet/

why parquet is best for spark, and hive best for hive:https://stackoverflow.com/questions/32373460/parquet-vs-orc-vs-orc-with-snappy

File Format Benchmark - Avro, JSON, ORC & Parquet:https://www.slideshare.net/HadoopSummit/file-format-benchmark-avro-json-orc-parquet


http://www.ppmy.cn/news/12220.html

相关文章

LeetCode622.设计循环队列

设计循环队列1.题目描述2.思路3.代码实现以及分析3.1 创建结构体3.2创建一个具体的循环队列3.3判断是否为空 和 判断是否为满4. 进队列 和 出队列5.取队首和队尾元素6.释放空间7.总结1.题目描述 设计循环队列 2.思路 环形队列的抽象图 我们这里使用数组模拟实现循环队列&…

TCP/IP网络编程(4)——基于 TCP 的服务端/客户端(1)

文章目录第 4 章 基于 TCP 的服务端/客户端&#xff08;1&#xff09;4.1 理解 TCP 和 UDP4.1.1 TCP/IP 协议栈4.1.2 链路层4.1.3 IP 层4.1.4 TCP/UDP 层4.1.5 应用层4.1.6 生活小例子4.2 实现基于 TCP 的服务器/客户端4.2.1 TCP 服务端的默认函数的调用程序4.2.2 进入等待连接…

57 mac 中 SIGINFO 信号, jdk8 支持, 但是 jdk9 不支持?

前言 问题来自于文章 shell脚本 后台启动 程序1 “tail -f log“, ctrl c 导致程序1中断 中的测试用例 Test07Signal2ParentProcess, 可以看到 我当时标记了一个 "todo, not work in hostpostVM9" 然后 问题是这样的, 我同一台机器, 然后 jdk8 带上 SIGINFO 去执行…

时间序列模型SCINet(代码解析)

前言 SCINet模型&#xff0c;精度仅次于NLinear的时间序列模型&#xff0c;在ETTh2数据集上单变量预测结果甚至比NLinear模型还要好。在这里还是建议大家去读一读论文&#xff0c;论文写的很规范&#xff0c;很值得学习&#xff0c;论文地址SCINet模型Github项目地址&#xff…

智能售货机系统帝可得

智能售货机 概述项目使用springcloudalibaba中提供的短信服务图形验证码生成多端登录/网关统一鉴权对象存储服务代码的自动填充微服务集成emq&#xff0c;发送emq工单业务流 接收工单 拒绝工单 运维工单补货工单使用xxl-job进行任务调度lkd集成xxl-job自动创建维修工单自动…

线程池(关于变量捕获、线程数、针对ThreadPoolExecutor的构造方法参数的解释、自实现线程池)

目录&#xff1a;一、前言二、关于变量捕获三、针对ThreadPoolExecutor的构造方法参数的解释四、自实现线程池一、前言相比较于进程&#xff0c;创建线程 / 销毁线程 的开销是相对较小的&#xff0c;但是太过频繁的创建线程 / 销毁线程&#xff0c;其开销也很大。这时候我们就需…

JVM-【面试题】-垃圾收集算法+垃圾收集器,以后就不用担心对象那些事了

一、垃圾收集算法在jvm里对可回收的对象在不同的垃圾收集器里&#xff0c;有不同的回收算法&#xff0c;具体的可以分为这四种&#xff1a;分代收集算法、复制算法、标记清除算法、标记整理算法1.1 分代收集算法当前虚拟机的垃圾收集都采用分代收集算法&#xff0c;这种算法没有…

每日一问-ChapGPT-20230114-关于小年

文章目录每日一问-ChapGPT系列起因每日一问-ChapGPT-20230114-关于小年腊月每天都做些什么的歌谣为什么现在的年味淡了很多&#xff0c;感觉不到过年为什么春节放假要调休&#xff0c;不能多放几天吗说说现在世界上极端气候&#xff0c;以及多少年后&#xff0c;地球存在不适宜…