hdfs文件格式比较

Hadoop中的文件格式大致上分为面向行和面向列两类:

面向行:将同一行的数据集中存储,即连续存储。序列文件、映射文件、Avro数据文件。这样,如果只需要访问一行的一小部分数据并将整行数据读入内存,延迟序列化可以在一定程度上缓解这一问题,但无法避免从磁盘读取整行数据的开销。面向行的存储适用于需要同时处理整行数据的情况。

[En]

Row-oriented: data in the same row is stored together, that is, continuous storage. SequenceFile,MapFile,Avro Datafile . In this way, if you only need to access a small portion of the data of a row and read the entire row into memory, delaying serialization can alleviate this problem to some extent, but the overhead of reading the entire row of data from disk cannot be avoided. Row-oriented storage is suitable for situations where entire rows of data need to be processed at the same time.

面向列:整个文件被分割成多列数据,每一列都存储在一起。实木地板、RCFile、或CFile。面向列的格式允许您在读取数据时跳过不需要的列,适用于仅位于行的一小部分字段中的情况。但是,以这种格式进行读写需要更多的内存空间,因为您需要在内存中缓存行(以便获得多行中的一列)。同时也不适合串流写入,因为如果写入失败,当前文件无法恢复,写入失败时面向行的数据可以重新同步到最后一个同步点,所以Flume采用面向行的存储格式。

[En]

Column oriented: the entire file is cut into columns of data, each of which is stored together. Parquet, RCFile,ORCFile . The column-oriented format allows you to skip unwanted columns when reading data, suitable for situations where you are only in a small portion of the fields of the row. But reading and writing in this format requires more memory space because you need to cache rows in memory (in order to get a column in multiple rows). At the same time, it is not suitable for streaming writing, because if the write fails, the current file cannot be recovered, and the row-oriented data can be resynchronized to the last synchronization point when the write fails, so Flume uses a line-oriented storage format.

以下是Hadoop系统中广泛使用的几种相关文件格式:

[En]

Here are several related file formats, which are widely used in the Hadoop system:

SequenceFile是Hadoop API 提供的一种二进制文件,它将数据以的形式序列化到文件中。这种二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。Hive 中的SequenceFile 继承自Hadoop API 的SequenceFile,不过它的key为空,使用value 存放实际的值, 这样是为了避免MR 在运行map 阶段的排序过程。如果你用Java API 编写SequenceFile,并让Hive 读取的话,请确保使用value字段存放数据,否则你需要自定义读取这种SequenceFile 的InputFormat class 和OutputFormat class。

SequenceFile的文件结构如下:

根据是否压缩以及使用记录压缩还是块压缩,存储格式会有所不同:

[En]

Depending on whether or not to compress, and whether to use record compression or block compression, the storage format varies:

请勿压缩:

[En]

Do not compress:

按记录长度、密钥长度、值度、密钥值、值值存储。长度是字节数。使用指定的序列化进行序列化。

[En]

It is stored according to record length, Key length, Value degree, key value and value value. Length is the number of bytes. Serializes with the specified Serialization.

Record压缩:

只压缩Value,压缩后的编解码器保存在Header中。

[En]

Only value is compressed, and the compressed codec is saved in Header.

Block压缩:

多个记录被压缩在一起,这可以利用记录之间的相似性来节省空间。同步标识符会在块之前和之后添加。Block的最小值由io.seqfile.compress.block大小属性设置。

[En]

Multiple records are compressed together, which can take advantage of the similarity between records to save space. Synchronization identifiers are added before and after the Block. The minimum value of Block is set by the io.seqfile.compress.blocksize property.

Avro是一种用于支持数据密集型的二进制文件格式。它的文件格式更为紧凑,若要读取大量数据时,Avro能够提供更好的序列化和反序列化性能。并 且Avro数据文件天生是带Schema定义的,所以它不需要开发者在API 级别实现自己的Writable对象。最近多个Hadoop 子项目都支持Avro 数据格式,如Pig 、Hive、Flume、Sqoop和Hcatalog。

RCFile是Hive推出的一种专门面向列的数据格式。 它遵循”先按列划分,再垂直划分”的设计理念。当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。需要说明的是,RCFile在map阶段从 远端拷贝仍然是拷贝整个数据块,并且拷贝到本地目录后RCFile并不是真正直接跳过不需要的列,并跳到需要读取的列, 而是通过扫描每一个row group的头部定义来实现的,但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。

Hive的Record Columnar File,这种类型的文件先将数据按行划分成Row Group,在Row Group内部,再将数据按列划分存储。其结构如下:

与简单的面向行和面向列相比:

[En]

Compared to simply row-oriented and column-oriented:

ORCFile(Optimized Record Columnar File)提供了一种比RCFile更加高效的文件格式。其内部将数据划分为默认大小为250M的Stripe。每个Stripe包括索引、数据和Footer。索引存储每一列的最大最小值,以及列中每一行的位置。

在Hive中,如下命令用于使用ORCFile:

CREATE TABLE … STORED AS ORC

ALTER TABLE … SET FILEFORMAT ORC

SET hive.default.fileformat=ORC

一种基于Google的Dremel的面向列的通用存储格式。尤其擅长处理深度嵌套的数据。

[En]

A general column-oriented storage format based on Google’s Dremel. Especially good at dealing with deeply nested data.

对于嵌套结构,Parquet将它们转换为平面列存储,由重复级别和定义级别(R和D)表示。当读取数据以重建整个记录时,元数据用于重建记录的结构。以下是R和D的一个例子:

[En]

For nested structures, Parquet converts them into flat column storage, which is represented by Repeat Level and Definition Level (R and D). When reading data to reconstruct the whole record, metadata is used to reconstruct the structure of the record. Here is an example of R and D:

我们选择TPC-H标准测试来说明不同文件格式的存储开销。由于这一数据是公开的,对结果感兴趣的读者也可以针对以下实验亲自进行实验。订单文本格式的原始大小为1.62G。我们将其加载到Hadoop中,并使用配置单元将其转换为上述格式,并在相同的LZO压缩模式下测试结果文件的大小。

[En]

We chose a TPC-H standard test to illustrate the storage overhead of different file formats. Because this data is public, readers who are interested in the results can also do it themselves against the following experiments. The original size of the Orders text format is 1.62G. We load it into Hadoop and use Hive to convert it to the above formats, and test the size of the resulting file in the same LZO compression mode.

表1:不同格式文件大小对比

从上面的实验结果可以看出,SequenceFile在压缩和未压缩情况下都比原始的纯文本TextFile大,其中未压缩模式下的SequenceFile大11%,压缩模式下的SequenceFile大6.4%。这与SequenceFile的文件格式的定义有关:SequenceFile在头文件中定义它的元数据,元数据的大小根据压缩模式的不同而略有不同。通常,压缩是在块级别执行的,其中每个块包含键的长度和值的长度,并且每4K字节有一个同步标记标记。对于TextFile文件格式,不同列之间只需要一个行间隔符,因此TextFile文件格式比SequenceFile文件格式小。但TextFile文件格式没有定义列的长度,因此它必须逐个字符地确定每个字符是否是分隔符和行终止符。因此,TextFile的反序列化开销可能比其他二进制文件格式高几十倍。

[En]

As can be seen from the above experimental results, SequenceFile is larger than the original plain text TextFile in both compressed and uncompressed cases, including 11% in uncompressed mode and 6.4% in compressed mode. This has something to do with the definition of SequenceFile’s file format: SequenceFile defines its metadata in the header, and the size of the metadata varies slightly depending on the compression mode. In general, compression is performed at the block level, where each block contains the length of the key and the length of the value, and there is a sync-marker tag for every 4K byte. For TextFile file formats, only one line spacer is needed between different columns, so the TextFile file format is smaller than the SequenceFile file format. But the TextFile file format does not define the length of the column, so it must determine whether each character is a delimiter and line Terminator on a character-by-character basis. As a result, the deserialization overhead of TextFile can be dozens of times higher than other binary file formats.

RCFile文件格式同样也会保存每个列的每个字段的长度。但是它是连续储存在头部元数据块中,它储存实际数据值也是连续的。另外RCFile 会每隔一定块大小重写一次头部的元数据块(称为row group,由hive.io.rcfile.record.buffer.size控制,其默认大小为4M),这种做法对于新出现的列是必须的,但是如 果是重复的列则不需要。RCFile 本来应该会比SequenceFile 文件大,但是RCFile 在定义头部时对于字段长度使用了Run Length Encoding进行压缩,所以RCFile 比SequenceFile又小一些。Run length Encoding针对固定长度的数据格式有非常高的压缩效率,比如Integer、Double和Long等占固定长度的数据类型。在此提一个特例—— Hive 0.8引入的TimeStamp 时间类型,如果其格式不包括毫秒,可表示为”YYYY-MM-DD HH:MM:SS”,那么就是固定长度占8个字节。如果带毫秒,则表示为”YYYY-MM-DD HH:MM:SS.fffffffff”,后面毫秒的部分则是可变的。

Avro文件格式也按group进行划分。但是它会在头部定义整个数据的模式(Schema), 而不像RCFile那样每隔一个row group就定义列的类型,并且重复多次。另外,Avro在使用部分类型的时候会使用更小的数据类型,比如Short或者Byte类型,所以Avro的数 据块比RCFile 的文件格式块更小。

我们可以使用Java的配置文件工具来查看Hadoop运行时任务的CPU和内存开销。以下是配置单元命令行上的设置:

[En]

We can use Java’s profile tool to view the CPU and memory overhead of Hadoop runtime tasks. The following are the settings on the Hive command line:

hive>set mapred.task.profile=true;

hive>set mapred.task.profile.params =-agentlib:hprof=cpu=samples,heap=sites, depth=6,force=n,thread=y,verbose=n,file=%s

当map task 运行结束后,它产生的日志会写在$logs/userlogs/job- 文件夹下。当然,你也可以直接在JobTracker的Web界面的logs或jobtracker.jsp 页面找到日志。

让我们运行一条简单的SQL语句来观察RCFile格式的序列化和反序列化开销:

[En]

Let’s run a simple SQL statement to observe the serialization and deserialization overhead of the RCFile format:

hive> select O_CUSTKEY,O_ORDERSTATUS from orders_rc2 where O_ORDERSTATUS=’P’;

其中的O_CUSTKEY列为integer类型,O_ORDERSTATUS为String类型。在日志输出的最后会包含内存和CPU 的消耗。

下表显示了CPU的成本:

[En]

The following table shows the cost of an CPU:

表2:一次CPU的开销

第五列可以根据上面的跟踪信息检查调用了哪些函数。例如,在CPU消耗排名第20位的函数对应于Track:

[En]

The fifth column can check which functions are called against the Track information above. For example, the function ranked 20 in CPU consumption corresponds to Track:

TRACE 315554: (thread=200001) org.apache.hadoop.hive.ql.io.RCFile$Reader.getCurrentRow(RCFile.java:1434) org.apache.hadoop.hive.ql.io.RCFileRecordReader.next(RCFileRecordReader.java:88) org.apache.hadoop.hive.ql.io.RCFileRecordReader.next(RCFileRecordReader.java:39)org.apache.hadoop.hive.ql.io.CombineHiveRecordReader.doNext(CombineHiveRecordReader.java:98)org.apache.hadoop.hive.ql.io.CombineHiveRecordReader.doNext(CombineHiveRecordReader.java:42) org.apache.hadoop.hive.ql.io.HiveContextAwareRecordReader.next(HiveContextAwareRecordReader.java:67)

其中,更明显的是RCFile,它为了构造行而消耗了不必要的数组移动开销。这主要是因为RCFile需要构造RowContainer来恢复行,顺序读取一行来构造RowContainer,然后给相应的列赋值。因为RCFile与SequenceFile兼容,所以它可以合并两个块,并且因为RCFile不知道列结束于哪个行组,所以它必须保持数组的当前位置,类似于以下格式定义:

[En]

Among them, the more obvious is RCFile, which consumes unnecessary array movement overhead in order to construct rows. This is mainly because RCFile needs to construct RowContainer in order to restore rows, read one row sequentially to construct RowContainer, and then assign values to the corresponding columns. Because RCFile is compatible with SequenceFile, it can merge two block, and because RCFile does not know which row group the column ends in, it must maintain the current position of the array, similar to the following format definition:

Array>

此数据格式可以更改为面向列的序列化和反序列化。例如:

[En]

This data format can be changed to column-oriented serialization and deserialization. Such as:

Map,array,array….>

当然,这种方式的反序列化避免了不必要的数组移动,只要我们知道列从哪个行组开始,哪个行组结束。这种方法提高了整个反序列化过程的效率。

[En]

Deserialization in this way avoids unnecessary array movement, of course, as long as we know which row group the column starts and which row group ends. This approach improves the efficiency of the overall deserialization process.

Original: https://www.cnblogs.com/wqbin/p/14635480.html
Author: wqbin
Title: hdfs文件格式比较

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/6901/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

发表回复

登录后才能评论
免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部