大数据存储格式-parquet

大数据存储格式-parquet


为何须要列式存储

首先咱们从关系数据库入手,来看关系数据库的一些常见查询。对于关系数据库而言,咱们常见的查询通常有详情查询或者统计分组,可是若是是大数据量的状况下,关系数据库是不能很好的支持统计类的查询,因此通常关系数据库多有于对OLTP业务,那么常见的大数据的查询有个特色,因为数据量很大,获取具体的详情数据意义不大,因此基本都是统计类的查询,如:select count(1) cnt,ip from access_log group by ip,查询每一个ip的访问次数。固然也可能有查询详细作深度的数据分析。html

对于查询速度固然是越快越好,咱们能够从如下几个方面来提升这个系统的查询速度(固然缓存不在考虑的范畴内),1.查询系统框架的优化,这里可能包含了(执行计划啊,分布式计算等等等),2.底层文件存储格式的优化,尽可能减小IO.3.固然还有索引技术.sql

针对上面的sql:select count(1) cnt,ip from access_log group by ip数据库

咱们假设access_log的格式以下: <code> access_log{ string ip; string access_time; ............(其余N个属性)apache

} </code>缓存

若是是行存储:数据结构

咱们须要读取一行的全部数据,而后获取其中的ip字段,在作分组统计。增长的磁盘的IO,同时也增长了计算压力.框架

若是是列存储会如何: 分布式

对于上面的统计,咱们只须要读取IP就能够,读取不须要的列信息,这就是列存储对于大数据的统计类查询的优势所在,固然除此以外大数据自己的稀疏性,采用列式可能更好的去优化存储结构,减小存储空间.大数据

parquet介绍

parquet是twitter在2013年开源的数据结构,google的Dremel: [Interactive Analysis of Web-Scale Datasets http://research.google.com/pubs/pub36632.html](Interactive Analysis of Web-Scale Datasets http://research.google.com/pubs/pub36632.html "Interactive Analysis of Web-Scale Datasets http://research.google.com/pubs/pub36632.html").这个大数据查询利器的paper里面,其实主要也是在阐述底层文件存储格式。优化

Parquet支持复杂嵌套的数据结构组成,并使用重复级别/定义级别(repetition/definition level )的方法来对数据结构进行编码,嵌套的方式其实能够避免了大数据的join问题.

Parquet支持对某一列数据进行压缩,支持任意开发语言的读写操做.目前是apache的顶级项目.

parquet文件格式分析

首先来看一下如何定义一个parquet的文件格式,这里也是采用相似PB的格式定义 这里采用了班级信息来做为示例,有多个班级,每个班级有个master,有多个学生(能够无),每一个学生有名称和多个爱好,还有每一门可课程的成绩以及课程名称. schema定义: <code> message classroom{ required string master; repeated group students{ required string name; repeated string hobbys; repeated group coursescore{ required string name; optional string score; } } } </code> required 表示必填 repeated 表示能够有任意个 optional 0 or 1 对于数据能够关系能够分为Map以及List,若是为List能够采用repeated,Map采用group 关键字修饰.

这里咱们来定义一组数据:

<code> { master:"jack", student: name:"tom" student: name:"joy", hobbys:"basketball", hobbys:"football", coursescore: name:"math", coursescore: name:"chinese", score:100 } { master:"BoBo" } </code>

两个班级一个有学生一个没有,一个学生有爱好有课程,一个什么也没有. 咱们先来看看如何存储.

存储

依据上面定义的schema,能够先转化为一个tree表示结构

只有树的根节点是须要实际存储的数据节点,其他的只是关系的一种维系。 下图展现了其嵌套关系

实际存储也是这样,每一列存储了全部的数据信息。是否是存储很容易。

读取

既然全部的同一类的数据存储在一块儿,那么数据如何还原为原来的数据。这里引入了parquet的元数据信息,如何还原数据须要 Repetition Level以及Definition Level这两个元数据信息。

首先咱们须要知道哪些数据是一组的,其实还须要知道数据和数据之间的层级关系,OK。这两个元数据信息能够帮咱们搞的.(固然也是存储的时候写入的元数据信息)

Repetition Level是记录该列的值是在哪个级别上重复的。

用刚才的两个classroom信息来举例: 对于两个classroom的master来讲,因为都是独立的没有直接关系,因此他们的Repetition level是0

Jack 0

BoBO 0

对于jack的学生tom,joy来讲,tom是第一个学生,因此level是0,而joy平级,因此是1.

<table> <tr><td>master</td><td>Repetition Level</td><tr> <tr><td>Jack</td><td>0</td><tr> <tr><td>BoBo</td><td>0</td><tr> </table>

<table> <tr><td>student.name</td><td>Repetition Level</td><tr> <tr><td>tom</td><td>0</td><tr> <tr><td>joy</td><td>1</td><tr> <tr><td>null</td><td>2</td><tr> </table>

<table> <tr><td>student.coursescore.score</td><td>Repetition Level</td><tr> <tr><td>null</td><td>0</td><tr> <tr><td>null</td><td>2</td><tr> <tr><td>100</td><td>1</td><tr> </table>

基于Repetition level是能够把原有的数据分好类,可是咱们如今咱们还不知道一条记录到什么位置STOP,以及数据以前的关系,这个时候在引入Definition Level。

这个时候在引入Definition Level 是定义的深度,用来记录该列是不是虚拟出来的。因此对于非NULL的记录,是没有意义的,其值必然为相同。一样举个例子。 好比对于master来讲深度就是0,由于是required。

<table> <tr><td>master</td><td>Definition Level</td><tr> <tr><td>Jack</td><td>0</td><tr> <tr><td>BoBo</td><td>0</td><tr> </table>

<table> <tr><td>student.name</td><td>Definition Level</td><tr> <tr><td>tom</td><td>1</td><tr> <tr><td>joy</td><td>2</td><tr> <tr><td>null</td><td>1</td><tr> <table> 经过Definition Level能够还原数据的嵌套关系。

其余

parquet已经有hive,pig,spark,impala等数据处理框架的支持,同时也是spark建议parquet做为其存储格式。经过以上能够看出,若是数据schema是扁平结构,那么其实,repetition level 和 definition level 就彻底不须要。后续会继续写一些数据处理引擎的文档。

相关文章
相关标签/搜索