文章目录
- 背景
- 基本概念
- 行式存储和列式存储总结
- Hive 存储格式有哪些?
- TEXTFILE 文本格式文件(行式存储)
- 适用场景
- SequenceFile(二进制序列化文件)
- 适用场景
- sequenceFile如何解决小文件问题
- RCFile(行列式文件)
- 存储方式
- ORC(优化的行列式文件)
- 存储方式
- 适用场景
- Parquet
- 适用场景
背景
hive 的数据存储其实是在HDFS文件系统中的。hive 提供了一种查询HDFS 中文件的一种方式。和传统的关系型数据库相比,hive 对所存储的数据在文件中的编码方式有很大的灵活性。Apache Hive支持Apache Hadoop中使用的几种熟悉的文件格式,如 TextFile(文本格式)
,RCFile(行列式文件)
,SequenceFile(二进制序列化文件)
,AVRO
,ORC(优化的行列式文件)
和Parquet
格式,而这其中我们目前使用最多的是TextFile
,SequenceFile
,ORC
和Parquet
。
基本概念
- 行式存储结构:传统的关系型数据库,如 Oracle、DB2、MySQL、SQL SERVER 等采用行式存储法(Row-based),在基于行式存储的数据库中, 数据是按照行数据为基础逻辑存储单元进行存储的, 一行中的数据在存储介质中以连续存储形式存在。
行式存储会将这三笔数据将按照行的顺序存储在磁盘中。如下图
行式存储有个特点就是写入数据非常的快,因为只需要将新增的数据在后面追加,存储在磁盘上最终是连续的空间。
行式存储结构读取数据
优势:读区单行或者是一组数据会非常高效。
缺点:在聚合的时候,尤其是需要聚合的字段比较少的时候,行式存储结构需要将多余的(列)加载到内存, 因此面向行的数据库可能需要访问的磁盘数量通常更大。
- **列式存储结构:**是相对于行式存储来说的,新兴的 Hbase、HP Vertica、EMC Greenplum 等分布式数据库均采用列式存储。在基于列式存储的数据库中, 数据是按照列为基础逻辑存储单元进行存储的,一列中的数据在存储介质中以连续存储形式存在。
同样的如上图的用户表在列式存储结构中如下存储
新增一笔数据如下
在聚合的场景下,比如说想要获取年龄的综合只需要将磁盘上连续的记录年龄的记录加载到内存中,不需要额外的数据加载。访问的磁盘数量将减少,并且必须保留在内存中的额外数据量最小化。 这大大提高了计算的整体速度。
行式存储和列式存储总结
- 同一行数据存储在一起即连续存储:SequenceFile、MapFile、Avro Datafile。 这样,如果只需要访问该行的少量数据,则需要将整行读入内存。 延迟序列化可以将问题减轻到一定程度,但无法收回从磁盘读取整行数据的开销。 面向行的存储适用于需要同时处理整行数据的情况。
- 整个文件切成几列数据,每一列数据存储在一起:Parquet、RCFile、ORCFile。 面向列的格式可以在读取数据时跳过不需要的列,适用于字段中只有一小部分行的情况。 但是这种读写格式需要更多的内存空间,因为缓存行需要在内存中(获取多行中的一列)。 同时不适合流式写入,因为一旦写入失败,当前文件无法恢复,而写入失败时,面向行的数据可以重新同步到最后一个同步点,所以Flume使用了 面向行的存储格式。
Hive 存储格式有哪些?
- TEXTFILE 文本格式文件(行式存储)
- SEQUENCEFILE 二进制序列化文件(行式存储)
- ORC(列式存储)
- PARQUET(列式存储)等。
TEXTFILE 文本格式文件(行式存储)
每一行都是一条记录,每行都以换行符(\ n)结尾。数据不做压缩,磁盘开销大,数据解析开销大。可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。
适用场景
TEXTFILE主要使用场景在数据源层 ODS层,针对需要使用脚本load加载数据到Hive数仓表中的情况。
SequenceFile(二进制序列化文件)
是Hadoop API提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。
支持三种压缩选择:NONE, RECORD, BLOCK。 Record压缩率低,一般建议使用BLOCK压缩。
压缩选择
- none Uncompressed
- RECORD
在每条记录添加到文件时对其进行压缩。
- BLOCK
- 等到数据达到要压缩的块大小。
- 块压缩比记录压缩提供更好的压缩率。
- 使用 SequenceFile 时,块压缩通常是首选选项。
- 这里的块与 HDFS 或文件系统块无关。
适用场景
HDFS文件系统是适合存储大文件的,很小的文件如果很多的话对于 Namenode 的压力会非常大,因为每个文件都会有一条元数据信息存储在 Namenode上, 当小文件非常多也就意味着在 Namenode上存储的元数据信息就非常多。
Hadoop是适合存储大数据的,所以我们可以通过 SequenceFile 将小文件合并起来,可以获得更高效率的存储和计算。
sequenceFile如何解决小文件问题
mapreduce 中的小文件问题
- Map 任务通常一次处理一个输入块(使用默认的 FileInputFormat)。
- 文件数量越多,需要的 Map 任务数量就越多,作业时间就会慢得多。
SequenceFile 的概念是将每个小文件放到一个更大的单个文件中。
例如,假设有 10,000 个 100KB 的文件,那么我们可以编写一个程序将它们放入一个单独的 SequenceFile 中,如下所示,您可以使用文件名作为键和内容作为值。
这样做的好处
- NameNode 上需要的内存数量较少。 继续以 10,000 个 100KB 文件为例
- 在使用 SequenceFile 之前,10,000 个对象在 NameNode 中占用大约 4.5MB 的 RAM。
- 使用 SequenceFile 后,1GB SequenceFile 和 8 个 HDFS 块,这些对象在 NameNode 中占用大约 3.6KB 的 RAM。
- SequenceFile 是可拆分的,因此适用于 MapReduce。
- SequenceFile 支持压缩。
RCFile(行列式文件)
存储方式
存储方式:数据按行分块,每块按列存储()
ORC(优化的行列式文件)
存储方式
存储方式:数据按行分块 每块按照列存储(不是真正意义上的列存储,可以理解为分段列存储)
可以看到ORC File被分成一个个的stripe,在file footer里面包含了该ORC File文件中stripes的元数据信息,比如每个stripe中有多少行,以及每列的数据类型。ORC File还包含了一些轻量级的索引,读取ORC数据时候就可以使用这些index来判断在一个file中哪些stripes需要被读取,并且可以将查询范围缩小到10000行的集合;实现原理是在ORC中,每个file/每个stripe/每10000行,都有索引来记录该数据范围内每列最大最小值等统计信息,所以可以很容易的根据查询条件判断是否需要读取相应的file/stripe/10000行数据,从而实现Predicate Pushdown
特点
- ORC是列式存储,有多种文件压缩方式,并且有着很高的压缩比。
- 文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储资源,查询任务的输入数据量减少,使用的MapTask也就减少了。
- 提供了多种索引,row group index、bloom filter index。
- ORC可以支持复杂的数据结构(比如Map等)
适用场景
orc 格式文件存储的出现是为了提升处理速度和减小文件占用磁盘大小。
Parquet
基于 Google 的 Dremel 的通用面向列的存储格式。 尤其擅长处理深度嵌套的数据。是一个面向列的二进制文件格式,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此Parquet格式文件是自解析的。Parquet对于大型查询的类型是高效的。对于扫描特定表格中的特定列的查询,Parquet特别有用。Parquet一般使用Snappy、Gzip压缩,默认是Snappy。
对于嵌套结构,Parquet 将其转换为扁平列存储,由Repeat Level 和Definition Level(R 和D)表示,并在读取数据时使用元数据重建记录以重建整个文件。 结构。 以下是 R 和 D 的示例:
AddressBook {
contacts: {
phoneNumber: "555 987 6543"
}
contacts: {
}
}
AddressBook {
}
适用场景
Parquet 主要使用场景在Impala和Hive共享数据和元数据的场景。
Parquet的核心思想是使用“record shredding and assembly algorithm”来表示复杂的嵌套数据类型,同时辅以按列的高效压缩和编码技术,实现降低存储空间,提高IO效率,降低上层应用延迟。Parquet是语言无关的,而且不与任何一种数据处理框架绑定在一起,适配多种语言和组件。