索引:
1.背景
2.存储方式
3.存储效率
4.读写方式
5.结论
6.其他格式

背景
     最近在做一个大数据分析平台的项目,项目开发过程中使用spark来计算工作流工程中的每一个计算步骤,多个spark submit计算提交,构成了一个工作流程的计算。其中使用csv来作为多个计算步骤之间的中间结果存储文件,但是csv作为毫无压缩的文本存储方式显然有些性能不够,所以想要寻找一个存储文件效率更高或者执行效率更高的文件格式作为替代品。

存储方式
    csv
            csv数据文件属于文本存储方式,spark默认支持,按照行以文本的方式写到文件中,每行一条记录.一般来说文本存储方式无压缩,性能相对较差。

parquet           
              Apache Parquet是Hadoop生态圈中一种新型列式存储格式,它可以兼容Hadoop生态圈中大多数计算框架(Mapreduce、Spark等),被多种查询引擎支持(Hive、Impala、Drill等),并且它是语言和平台无关的。Parquet最初是由Twitter和Cloudera合作开发完成并开源,2015年5月从Apache的孵化器里毕业成为Apache顶级项目。

Parquet最初的灵感来自Google于2010年发表的Dremel论文,文中介绍了一种支持嵌套结构的存储格式,并且使用了列式存储的方式提升查询性能,在Dremel论文中还介绍了Google如何使用这种存储格式实现并行查询的,如果对此感兴趣可以参考论文和开源实现Drill。

Parquet文件是以二进制方式存储的,是不可以直接读取和修改的,Parquet文件是自解析的,文件中包括该文件的数据和元数据。在HDFS文件系统和Parquet文件中存在如下几个概念:

HDFS块(Block):它是HDFS上的最小的副本单位,HDFS会把一个Block存储在本地的一个文件并且维护分散在不同的机器上的多个副本,通常情况下一个Block的大小为256M、512M等。
HDFS文件(File):一个HDFS的文件,包括数据和元数据,数据分散存储在多个Block中。
行组(Row Group):按照行将数据物理上划分为多个单元,每一个行组包含一定的行数,在一个HDFS文件中至少存储一个行组,Parquet读写的时候会将整个行组缓存在内存中,所以如果每一个行组的大小是由内存大的小决定的。
列块(Column Chunk):在一个行组中每一列保存在一个列块中,行组中的所有列连续的存储在这个行组文件中。不同的列块可能使用不同的算法进行压缩。
页(Page):每一个列块划分为多个页,一个页是最小的编码的单位,在同一个列块的不同页可能使用不同的编码方式。
              通常情况下,在存储Parquet数据的时候会按照HDFS的Block大小设置行组的大小,由于一般情况下每一个Mapper任务处理数据的最小单位是一个Block,这样可以把每一个行组由一个Mapper任务处理,增大任务执行并行度。Parquet文件的格式如下图所示。


             可以看出,存储格式中元数据索引信息是被存储在最后的,所以当读取某一行的数据的时候,就需要去定位最后的索引信息,最后才能去读取对应的行数据。   
    orc
             ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度。和Parquet类似,它并不是一个单纯的列式存储格式,仍然是首先根据行组分割整个表,在每一个行组内进行按列存储。ORC文件是自描述的,它的元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗,目前也被Spark SQL、Presto等查询引擎支持,但是Impala对于ORC目前没有支持,仍然使用Parquet作为主要的列式存储格式。2015年ORC项目被Apache项目基金会提升为Apache顶级项目。
              和Parquet类似,ORC文件也是以二进制方式存储的,所以是不可以直接读取,ORC文件也是自解析的,它包含许多的元数据,这些元数据都是同构ProtoBuffer进行序列化的。ORC的文件结构入图6,其中涉及到如下的概念:

ORC文件:保存在文件系统上的普通二进制文件,一个ORC文件中可以包含多个stripe,每一个stripe包含多条记录,这些记录按照列进行独立存储,对应到Parquet中的row group的概念。
文件级元数据:包括文件的描述信息PostScript、文件meta信息(包括整个文件的统计信息)、所有stripe的信息和文件schema信息。
stripe:一组行形成一个stripe,每次读取文件是以行组为单位的,一般为HDFS的块大小,保存了每一列的索引和数据。
stripe元数据:保存stripe的位置、每一个列的在该stripe的统计信息以及所有的stream类型和位置。
row group:索引的最小单位,一个stripe中包含多个row group,默认为10000个值组成。
stream:一个stream表示文件中一段有效的数据,包括索引和数据两类。索引stream保存每一个row group的位置和统计信息,数据stream包括多种类型的数据,具体需要哪几种是由该列类型和编码方式决定。

和parquet不同的是,每一个row data的开始,都会有index data索引信息,相对于parquet把索引信息放在最后而言,理论上行读取的速度要更快一点。

存储大小(存储效率)
原始数据:

size:64G/format:csv/location:hdfs

集群运行环境:

5台/内存:24G/核心:16核

数据相同,从csv转换成了如下不同格式,读写效率如下:

格式        大小    读写时间    count操作一次时间
csv    36G    3.6min    59s
parquet    6G    1.1min    5s
orc    5.9G    1.2min    5s
avro    13G    1.3min    25s
    size:可以看出,相对于csv而言,parque和orc直接缩小了6倍的大小,理论上说可以达到6-10倍的压缩效率,本次使用的parquet默认的gzip压缩方式。

time:更值得注意的一点是,针对count这种列操作的方法,parquet、orc和avro都获得了相当好的效果,猜测可能是因为不需要这个数据集来计算,而仅仅使用某一些列就能计算,减小了计算的规模。

读写代码
  1.csv太普遍了这里就省略了

2.parquet:

val df  = sc.read.parquet("path")
df.write.format("parquet").save("hdfs path")
 3.orc:

val df = sc.read.orc("path")
df.write.format("orc").save("hdfs path")
 4.avro:

var data = sc.read.format("com.databricks.spark.avro")
    .option("header", "true")
    .option("mode", "DROPMALFORMED")
    .option("delimiter", ",")
    .load("hdfs://192.168.10.10:9000/data/test/Solderc_to_c.csv")
 
df.write.format("com.databricks.spark.avro").save("hdfs path")
 avro可是使用databricks进行读取,当然比忘了添加databricks的maven依赖

结论
       csv使用较为广泛,多数系统的输入都是csv格式,此外csv文件直接打开是可以理解和读懂的,而且csv文件也是支持末尾添加数据的,但是csv文件因为没有压缩,所以体积较大,某些操作上也不如列式存储。

parquet使用也较为广泛,默认使用gzip压缩,体积较,运算效率高,但是parquet打开是不能被理解和读懂的,因为其采用二进制存储方式,当系统中无特殊要求,也去需要打开数据文件的时候,为了追求效率可以考虑。

orc也是列示存储的二进制文件,打开无法被直接理解和读懂,但是因为在文件格式中,每一个row block的开始都有一个轻型索引,所以相较于parquet,orc在检索行的时候,速度要相对较快一点,

其他格式
还有其他的一些格式:indexR/ya100

引用文章如下:

http://blog.csdn.net/yu616568/article/details/51868447

https://www.cnblogs.com/piaolingzxh/p/5469964.html

csv、parquet、orc读写性能和方式相关推荐

  1. SQL与NoSQL区别-读写性能

    关系型数据库十分强调数据的一致性,并为此降低读写性能付出了巨大的代价,虽然关系型数据库存储数据和处理数据的可靠性很不错,但一旦面对海量数据的处理的时候效率就会变得很差,特别是遇到高并发读写的时候性能就 ...

  2. 使用SQL Server分区表功能提高数据库的读写性能

    首先祝大家新年快乐,身体健康,万事如意. 一般来说一个系统最先出现瓶颈的点很可能是数据库.比如我们的生产系统并发量很高在跑一段时间后,数据库中某些表的数据量会越来越大.海量的数据会严重影响数据库的读写 ...

  3. 入门云数据库Redis,满足你的高读写性能场景需求

    什么是云数据库Redis版 更新时间:2020-01-16 10:30:56 编辑 我的收藏 新浪微博 微信 钉钉 我的收藏 SDK中心 API中心 新手学堂 学习路径 本页目录 为什么选择云数据库R ...

  4. mysql myisam写入性能_(转)innodb 与 myisam 读写性能分析

    前提: mysql在5.0之前,读写性能相差很大,读性能:myisam 很强 mysql在5.0之后,差距不是很大 http://www.taobaodba.com/ 由于近期有个项目对系统性能要求很 ...

  5. c 语言编写脚本优化,两周自制脚本语言-第11天 优化变量读写性能

    第11天 优化变量读写性能 以变量值的读写为例,向读者介绍基于这种理念的语言处理器性能优化方式. 11.1 通过简单数组来实现环境 假如函数包含局部变量x与y,程序可以事先将x设为数组的第0个元素,将 ...

  6. HBase读写性能调优(一)

    目录 1.HBase关键参数配置 1.1 写参数调整 1.1.1客户端调优 1.1.2 使用PutList方式提交请求 1.2 Memstore相关 1.2.1 根据 memstore 大小flush ...

  7. 解决:测试HDFS读写性能时出现错误

    解决:测试HDFS读写性能时出现错误 今天测试HDFS的读写性能出现以下错误 java.lang.IllegalArgumentException:Unsupported ByteMultiple M ...

  8. 你的硬盘有多快?,教你提升硬盘/NAS读写性能

    速度是每个极客的追求,为了提升充电速度,我研究了各种充电头,写了篇「关于PD快充和快充充电器选购指南,看这一篇就够了」,还被张大妈首页推荐了.今天我们就来聊一聊机械硬盘 / 固态硬盘 / U盘 / N ...

  9. nfs服务器随机读写性能,linux nfs 读写性能

    linux nfs 读写性能 内容精选 换一换 fio是一个开源的I/O压力测试工具,可以使用fio工具对SFS进行吞吐量和IOPS的性能测试.已在云服务器上安装fio工具.fio可从官网或GitHu ...

最新文章

  1. Tomcat工程部署常见问题
  2. Spark的RDD行动算子
  3. swift_029(Swift 的泛型)
  4. 原来R语言还有这些不为人知的用处!
  5. Yarn 和 Npm 命令行切换 摘录
  6. circlegan_【源码解读】cycleGAN(二) :训练
  7. c语言pta判断字符或数字的昵称,c/c++开发分享『ACM C++』PTA浙大 | 基础题 – 打印沙漏...
  8. php pdo 错误信息,PHP的PDO错误与错误处理
  9. 高评分防火墙GlassWire:帮你监控、追踪和提升电脑安全
  10. c语言do while语句用法6,c语言do while的用法
  11. 你看,那个人好像一条狗哎
  12. 数据库设计说明书的编写
  13. 字典攻击ssh弱口令
  14. 苹果手机长截屏_发现一个手机必备软件
  15. Java短信平台实战第一天
  16. 单片机 舵机 SG90 舵机 控制原理 MSP432 单片机
  17. 文件夹提示文件或目录损坏且无法读取怎么修复
  18. Revit SDK 介绍:CompoundStructure 复合结构
  19. 2055041-21-7,Acid-PEG4-S-PEG4-acid在EDC和HATU等活化剂存在下,羧酸基团可与伯胺反应
  20. 【容斥原理】幸运数字

热门文章

  1. SSH远程连接原理及操作详解
  2. elementui table expand 修改数据
  3. uni-app下拉刷新触底加载更多
  4. 八爪鱼采集器 - 最好用的网页数据采集器
  5. 一:BT、BLE版本说明及对比
  6. Git不提交指定文件的方法
  7. SAR图像的干涉相位 matlab_时空双缝干涉
  8. 随机生成及检测8位密码:必须由大写字母、小写字母、数字和特殊符号共同组成
  9. 计算机组成原理期末考试:三种地址映射方式
  10. c++ getpid函数_C Linux中的getpid()和getppid()函数