【数仓】数据存储格式的选择:Parquet与ORC

大家好,我终于又出现了!

这次要讲讲数据存储格式Parquet和ORC之间的选择!

平时呢,我也会加一些有的没有的交流群,主要还是日常潜水看看里面有没有大佬!

然后就遇到了一个问题:hadoop上存储的数据,要进行查询,用什么格式存储更好?

我下意识的反应是ORC,因为ORC的压缩比更高(文件能压缩的更小),但是转念一想,ORC和Parquet都是列式存储的格式,两者之间有什么区别呢?或者说在最开始选择数据存储格式的时候,我们需要关注哪些点呢?

这另我陷入了沉思,开始在网上收集相关信息!

一、orc和parquet的区别

首先关于这两个格式的区别,我搜索到了不少东西!

国内的各大it博客平台流传这这么一份博客,具体出处是哪里,我考究不了了,随便贴个链接出来大家看看就好:https://developer.aliyun.com/article/226990

stackoverflow有类似的问题:https://stackoverflow.com/questions/53648218/when-to-use-parquet-over-orc-or-orc-over-parquet

甚至找到YouTube上的视频:https://www.youtube.com/watch?v=NZLrJmjoXw8

【数仓】数据存储格式的选择:Parquet与ORC_第1张图片

【数仓】数据存储格式的选择:Parquet与ORC_第2张图片

二、有没有谁实际测试过

这方面的材料不多,有的好像也已经过时,文章打不开

Parquet与ORC性能测试报告(教练_我要踢球):https://blog.csdn.net/yu616568/article/details/51188479

Parquet与ORC:高性能列式存储格式(教练_我要踢球):https://blog.csdn.net/yu616568/article/details/51868447

spark 1.6 下parquet vs orc(作者:cjuexuan):http://www.voidcn.com/article/p-fmauhwpe-bau.html

得到的结论是:hive的orc性能更好,但是低版本spark的parquet性能更好

 

三、总结:选型时候该注意

1、存储空间

orc的压缩比parquet更好,相同大小的文件,orc格式往往占用的空间更小!

但是其实现在硬盘的价格相对于内存和cpu,gpu来说,应该是很便宜的了,所以在这点上你说orc有多大优势,并不见得

存储在hadoop上会有三副本,可以考虑调低副本数(但是就降低了可用性),或者hadoop3.x好像有什么纠删码策略,可以减少副本数(具体没了解过)

2、查询框架

查询往往都是使用不同的框架查询同一份数据,问题在于这些不同的框架对于这个格式的支持度如何?

比如spark默认的数据格式是parquet,也从侧面印证spark对于parquet数据的查询优于orc

比如impala低版本是不支持orc格式的!

比如hive查询orc格式的数据速度更快性能更好!

presto对读取orc格式的优化:https://cloud.tencent.com/developer/article/1427176

所以关键点在于你们公司选用的查询框架是否对该格式有良好的支持度!

3、查询性能的优化点

在列式存储的查询上,有如下的优化手段

(1)、对于嵌套格式的存储会导致查询时的快慢(这个跟这两种格式存储嵌套数据的策略有关,看下来是parquet更优)

Parquet的那些事(三)嵌套数据模型:https://zhuanlan.zhihu.com/p/129371435

不过讲实话,一般数据我更喜欢扁平化的操作,一个字段,存一个值,比较少一个字段,存多个值,所以一些奇怪的数据结构我也用的少,比如hive中有什么array,map,struct,用过,但用的少

(2)、谓词下推,可以在源头过滤更多不需要计算的数据

这个也得看查询框架对于这个数据是否支持,不过一般都是支持的,不然这个框架查数据肯定比别的框架慢,那他就火不起来

(3)、向量查询,可以实现批量扫描数据,减少cpu指令的调用,增加每次cpu指令执行是处理的数据条数(具体这个我也不太懂,大家可以百度到在spark2.3左右的版本才支持orc的向量查询,用的还是hive的类做的,所以我们就知道spark更倾向于parquet,而hive倾向于orc

(4)、预先存值

我记得orc会在各自的块中存放一些预先计算的值,比如max,min,count等,这样我们在查询的时候,比如全表count,实际上并没有扫描所有数据来计算count值,只是读取了预先计算好的count值而已(parquet有没有,我估计应该是有类似的实现,但是我暂时搜索不到这部分信息,就不瞎说了)

具体可以尝试hive的orcfiledump来获得orc文件块中的json信息!

例如:./hive –orcfiledump -j -p /hivedata/warehouse2/lxw1234_orc1/000000_0,你就可以看到这个orc块中某些字段的min和max

parquet嵌套数据结构(作者:浪尖):https://blog.csdn.net/rlnLo2pNEfx9c/article/details/82880519

更高的压缩比,更好的性能–使用ORC文件格式优化Hive(作者:lxw):http://lxw1234.com/archives/2016/04/630.htm

 

3、支持的特殊功能

我所说的支持的特殊功能,不能单从数据结构来判断,应该通过使用的框架+数据结构来做支持功能的判断,比如我下面要说的两点,在不同框架中有不同的结果!

(1)、ACID

Hive 0.13之前,Hive支持分区级别上原子性、一致性、持久性,隔离性可以通过hive提供的锁机制来实现(通过zookeeper锁或者内存锁来锁住一个分区的数据)。从Hive 0.13开始,Hive可以支持行级别上面的ACID语义了。因此我们可以在有其他程序读取一个分区数据时往这个分区插入新的数据。

具体大家可以百度看看,要使用这个功能也是有所限制的,比如:仅支持ORC格式!(所以parquet就是不支持ACID)

Hive ACID和事务表支持详解(作者:疯狂的哈丘):https://www.jianshu.com/p/b4a8011b2b5d

但是讲实话,在数仓,或者大数据层面,ACID使用场景并不多,一般ACID是面向一些作为查询服务的数据,然而数仓中的数据更多是作为计算和分层流转

(2)、update

从数据结构层面上来说parquet和orc应该都不支持update,但是有些框架会支持使得这个数据结构也能有ACID或者update的功能。

比如和orc格式更加亲密的hive,就支持orc的ACID和update,不支持parquet格式

然后hudi却又可以支持parquet的update操作

具体做法我没有深究,但是估计就是update的时候生成新的数据块,后续合并数据块的时候,自动/手动把过时的数据清楚掉(hbase或者es都是类似这样的方式来处理update)

拓展内容:

1、如果想了解hbase或者es的相关策略,可以搜索下LSM树和es的增删改查策略

2、大家有兴趣也可以研究下LSM树和B+树的优缺点,为什么大数据框架都用LSM,但是B+树却又不过时(其实LSM只增加了写方面的性能,但削弱了读方面的性能,所以在不同场景下有优劣之说)

 

菜鸡一只,如果有任何要补充的,或者我哪里说错的,还请大家留言补充或者批评指正!

最近真的是(个人私事:买房)很忙,这篇文章也是从上个礼拜就开始撰写到今天才弄完,不过自己的私事也算是得到了皆大欢喜的结果,接下来还需要更加努力打工赚钱提升自己!!加油冲冲冲~

上面那段结语是本周一写的(今天),下面这段是上周五预先写好的结语,我也留着,当成一种心路历程的记录吧

好久没写文章了,最近主要个人私事比较多,年纪到了,该考虑人生大事了,结果烦心事接踵而至,虽然也是一步步在慢慢处理,但是也搞得心力憔悴焦头烂额,不过我相信黎明前最黑暗,风雨后见彩虹!

你可能感兴趣的:(数据仓库)