文件压缩格式和容器文件格式

File compression formats and container file formats

一般来说,任何像 Gzip 这样的压缩格式,当与像 avro 和序列(文件格式)这样的容器文件格式一起使用时,将使压缩格式可拆分。

这是否意味着容器格式中的块根据首选压缩(如 gzip)或其他方式进行压缩。有人可以解释一下吗?谢谢!

嗯,我认为这个问题需要更新。

更新:

我们是否有直接的方法将不可拆分文件压缩格式(如 Gzip)的大文件转换为可拆分文件(使用 Avro、Sequence 或 Parquet 等容器文件格式)以供处理MapReduce?

注意:我并不是要寻求解决方法,例如解压缩文件,然后使用可拆分压缩格式再次压缩数据。

对于序列文件,如果您指定 BLOCK 压缩,每个块将使用指定的压缩编解码器进行压缩。块允许 Hadoop 在块级别拆分数据,同时使用压缩(压缩本身不可拆分)并跳过整个块而无需解压缩它们。

Hadoop wiki 上描述了其中的大部分内容:https://wiki.apache.org/hadoop/SequenceFile

Block compressed key/value records - both keys and values are collected in 'blocks' separately and compressed. The size of the 'block' is configurable.

对于 Avro,这也非常相似:https://avro.apache.org/docs/1.7.7/spec.html#Object+Container+Files

Objects are stored in blocks that may be compressed. Syncronization markers are used between blocks to permit efficient splitting of files for MapReduce processing.

Thus, each block's binary data can be efficiently extracted or skipped without deserializing the contents.

将数据从一种格式转换为另一种格式的最简单(通常也是最快)的方法是让 MapReduce 为您完成这项工作。例如:

GZip Text -> SequenceFile

您将拥有一个使用 TextInputFormat 作为输入和输出 SequenceFileFormat 的纯地图作业。通过这种方式,您可以对文件数量进行一对一转换(如果需要更改,请添加减少步骤),如果要转换的文件很多,则可以并行进行转换。

不知道你在说什么...但是任何文件都可以随时拆分。

为什么我这么说...希望您使用的是 Linux 或类似的东西。

在 Linux 上,创建真正存储在某些文件串联上的块设备(不是太)容易。

我的意思是:

  • 您可以根据需要将文件分成任意多的块,每个块大小不同,不需要好甚至大小,512 字节的倍数等,无论您想要什么大小,数学表达splitted_file_size=(desired_size mod 1).
  • 您定义了一个以正确顺序连接所有文件的块设备
  • 你为这样的设备定义一个符号link

这样你就可以将一个大文件(超过 16GiB,超过 4GiB)存储在一个 FAT32 分区(每个文件有 4GiB-1 字节的限制)......并在 -飞翔和透明......只在阅读时思考。

对于read/write...有一个技巧(复杂的部分)有效:

  • 拆分文件(这次是 N*512 字节的块)
  • 定义一个参数化的设备驱动程序(因此它知道如何通过创建更多文件来分配更多块)

在 Linux 我过去曾使用过一些工具(命令行)来完成所有工作,它们可以让你创建一个可以动态调整大小的虚拟容器,它将使用精确大小的文件(包括最后一个)并将其公开为常规块设备(您可以在其中执行 dd if=... of=... 来填充它)和与之关联的虚拟文件。

这样你就有了:

  • 一些大小相同的不太大的文件
  • 它们将保存在流的真实数据中
  • 根据需要创建/删除它们(增长/收缩或截断)
  • 它们在某些时候作为常规文件公开
  • 访问此类文件将如同串联

也许这会让您对您遇到的问题的其他方法有所了解:

  • 而不是调整压缩系统,只需放置一个层(比简单的循环设备稍微复杂一点),它可以动态地透明地 split/join

有这样的工具,我不记得名字了,抱歉!但我记得那个是只读的(dvd_double_layer.* 在 FAT32 上):

# cd /mnt/FAT32
# ls -lh dvd_double_layer.*
total #
-r--r--r-- 1 root root 3.5G 2017-04-20 13:10 dvd_double_layer.000
-r--r--r-- 1 root root 3.5G 2017-04-20 13:11 dvd_double_layer.001
-r--r--r-- 1 root root 0.2G 2017-04-20 13:12 dvd_double_layer.002
# affuse dvd_double_layer.000 /mnt/transparent_concatenated_on_the_fly
# cd /mnt/transparent_concatenated_on_the_fly
# ln -s dvd_double_layer.000.raw dvd_double_layer.iso
# ls -lh dvd_double_layer.*
total #
-r--r--r-- 1 root root 7.2G 2017-04-20 13:13 dvd_double_layer.000.raw
-r--r--r-- 1 root root 7.2G 2017-04-20 13:14 dvd_double_layer.iso

希望这个想法能帮到你。