`

针对GZIP文件类型的并行读取

阅读更多
原文链接:http://click.aliyun.com/m/26743/
摘要: 一,前言 GZIP是最常见的压缩文件格式,目前DataX是支持对该压缩文件直接的读取,但每个GZIP仅仅只能启动一个线程来读取,当GZIP比较大,或者说针对GZIP中的数据有着较复杂的操作的情况下,执行效率往往比较低下。

一,前言
GZIP是最常见的压缩文件格式,目前DataX是支持对该压缩文件直接的读取,但每个GZIP仅仅只能启动一个线程来读取,当GZIP比较大,或者说针对GZIP中的数据有着较复杂的操作的情况下,执行效率往往比较低下。下面就讨论下如何对针对GZIP文件类型的并行读取,大幅度提高执行效率。

二,简单测试
首先对一个GZIP文件进行解压缩的测试:

$ll -h event_custom_json_201705161100.0.log.gz
-rw-r--r-- 1 weiguang.sunwg users 18M May 26 21:44 event_custom_json_201705161100.0.log.gz
该压缩文件大小为18MB,测试解压缩的时间:

$time gzip -d event_custom_json_201705161100.0.log.gz

real    0m1.879s
user    0m1.550s
sys     0m0.314s
仅仅不到2秒就完成了对该文件的解压操作,看下解压后的文件情况:

$ll -h event_custom_json_201705161100.0.log
-rw-r--r-- 1 weiguang.sunwg users 301M May 27 13:34 event_custom_json_201705161100.0.log
解压后文件大小为301MB,这个压缩率还是相当可观的。一般来说,对于结构化的数据,压缩率都比较高。这么看来,解压的效率还是很高的,不会成为性能的瓶颈,这也是我们接下来通过对GZIP文件并行读取提高整体数据同步效率的前提。试想下,如果解压缩的操作非常耗时,那么并行读取意义就不大了。

$wc -l event_custom_json_201705161100.0.log
628410 event_custom_json_201705161100.0.log
该文件中共有将近63万条记录。

三,并行读取
1,拆分规则

并行读取的前提是读取任务可以拆分,对于类似上面这样结构化的文件通过记录数来拆分是最自然的想法。例如,上面的文件存在628410行记录,启动10个并行的话,那么每个线程读取62841行记录即可。但实际操作上却非常困难,针对一个大文件,想要准确定位到某一行绝对是件效率不高的操作。
记录数不行,那就通过数据量(偏移量)吧,上面的文件解压缩后有301MB,如果启动10个并行的话,每个线程读取30MB左右的数据(不能通过压缩后的18MB来做拆分,这并不是实际数据的大小)。通过JAVA可以很容易的实现对压缩文件的流式读取,边读边解压。这时候就要求我们在读之间最好就可以知道该文件压缩前的大小。看下GZIP的压缩格式,在文件的结尾部分是保存了该信息的:

ISIZE(4 byte):这是原始数据的长度以2的32次方为模的值。GZIP中字节排列顺序是LSB方式,即Little-Endian,与ZLIB中的相反。
比较悲催的一点是,ISIZE存储的是以2的32次方为模的值,也就是说当原始文件大于4GB的时候,该值就不能准确的反应原始文件的大小了。GZIP的规范应该很久很久以前制定的,当时估计还不支持这么大的文件吧。这点先忽略吧,目前的项目中文件都是相对较小的。
我们来验证下,看看如何通过读取GZIP的文件尾,来计算原始文件大小。

[weiguang.sunwg@buffer010101169107.et2sqa /home/weiguang.sunwg/sunwg/test]
$echo a > 1.txt

[weiguang.sunwg@buffer010101169107.et2sqa /home/weiguang.sunwg/sunwg/test]
$cat 1.txt
a

[weiguang.sunwg@buffer010101169107.et2sqa /home/weiguang.sunwg/sunwg/test]
$ll 1.txt
-rw-r--r-- 1 weiguang.sunwg users 2 May 27 13:57 1.txt
对1.txt进行压缩,并查看压缩后的文件信息:
···
[weiguang.sunwg@buffer010101169107.et2sqa /home/weiguang.sunwg/sunwg/test]
$gzip 1.txt

[weiguang.sunwg@buffer010101169107.et2sqa /home/weiguang.sunwg/sunwg/test]
$xxd 1.txt.gz
0000000: 1f8b 0808 5b15 2959 0003 312e 7478 7400 ....[.)Y..1.txt.
0000010: 4be4 0200 07a1 eadd 0200 0000 K...........
···
最后4个字节为0200 0000,高低位转换后为0000 0002,意思该压缩文件对应的原始文件为2个字节。

在看下前面那个压缩后为18MB的文件,文件尾如下:

1145930: 4a21 c510 92a8 5177 0c9e b3da 7858 2867  J!....Qw....xX(g
1145940: 56f3 370f 28ff 3fa8 692e bc92 7dc0 12    V.7.(.?.i...}..
最后4个字节为927d c012,高低位转换后为12c0 7d92,转换为10进制为314604946,即为解压后文件大小。

$ll event_custom_json_201705161100.0.log
-rw-r--r-- 1 weiguang.sunwg users 314604946 May 27 13:34 event_custom_json_201705161100.0.log
通过解析GZIP文件尾,可以很方便的得到该原始文件大小,根据原始文件大小可以比较方便的进行并行的拆分,并且基本保证每个并行处理的数据量差不多,避免长尾。

2,记录对齐

按数据量拆分,不能保证每个拆分点都是一行记录的结尾,所以每个并行需要进行记录对齐,保证读取的是完整的一行。对齐的规则也相当简单,开头少读半行,结尾多读半行。示意图如下:
A012.jpg
该并行读取数据头和尾分别为A0和B0,根据上面的对齐规则调整为A1和B1,保证记录对齐。其实针对其他结构化的文件都可以如此操作,只要有明确的行分隔符。

四,结束
实现了对GZIP文件的并行读取,就可以很容易的通过设置更高的并行度来提高同步的效率,更好的满足用户的需求。
原文链接:http://click.aliyun.com/m/26743/
分享到:
评论

相关推荐

    segy文件的读取

    - 并行处理:对于大型数据集,可以利用多核CPU并行读取和转换多个SEGY文件,显著提升效率。 - 数据流处理:在内存有限的情况下,可以使用流式处理技术,避免一次性加载整个文件到内存。 总结,处理SEGY文件需要...

    Gzip压缩算法源码

    - **读取和写入Gzip文件**:源码中会包含读取Gzip文件头、解析压缩数据、计算和验证CRC校验和,以及写入新Gzip文件的函数。 - **DEFLATE算法的实现**:理解LZ77滑动窗口的维护、查找匹配、生成霍夫曼编码的过程。 - ...

    pgzip:进行并行gzip(de)压缩

    您不必匹配压缩器/解压缩器即可获得上述加速器,并且gzip文件与其他gzip读取器/写入器完全兼容。 这个的golang变体是 ,它具有相同的功能,并且可以在生成的文件中查找。 唯一的缺点是与此版本和纯gzip相比,开销稍...

    Pascal-gzip.zip

    5. **压缩和解压缩过程**:Pascal实现GZIP需要处理的步骤包括读取文件头,应用DEFLATE算法进行压缩或解压缩,以及验证CRC校验码以确保数据的完整性。 6. **错误处理和异常处理**:在实现过程中,要考虑到可能出现的...

    matlab开发-读写速度文件

    本主题将深入探讨如何使用MATLAB来优化读写速度,特别是针对特定的`.spe`文件格式。`.spe`文件通常用于科学实验数据存储,例如声学或光谱分析等领域。 首先,我们来看两个核心脚本——`SpeWriter.m`和`SpeReader.m`...

    gzip源代码gzip源代码

    2. **解压缩过程**:解压缩时,gzip读取已压缩文件的头部信息,解析出霍夫曼编码表,然后使用反向的LZ77和霍夫曼解码算法将数据还原。在源代码中,解压功能由`uncompress()`函数处理。 3. **文件格式**:gzip压缩后...

    gzip内存解压压缩(libz.so库)

    Gzip是一种广泛使用的文件压缩工具,它基于DEFLATE算法。本文将深入探讨如何利用Gzip在内存中实现解压和压缩,以及涉及到的libz.so库。 **一、Gzip简介** Gzip是一种数据格式,主要用于减少文件大小,提高存储和...

    完整版读取DBF数据.rar

    7. **错误处理**:在读取过程中,可能会遇到诸如文件损坏、编码错误、字段类型不匹配等问题。良好的错误处理机制是必不可少的,它能帮助捕获和报告这些问题,确保程序的健壮性。 8. **性能优化**:如果你需要处理...

    JAVA文件压缩与解压缩实践(源代码+论文)

    这可能包括读取文件,创建压缩流,写入数据到压缩流,以及从压缩流中读取和写入文件等步骤。 5. **文件操作**:在Java中,文件操作涉及`java.io`包,如`File`类用于文件的创建、删除和基本信息获取,而`...

    JAVA文件压缩与解压缩实践-project

    1. **Java内置库`java.util.zip`**:这个库包含了用于压缩和解压缩的类,如`ZipOutputStream`用于创建ZIP文件,`ZipInputStream`用于读取和解压ZIP文件,以及`GZIPOutputStream`和`GZIPInputStream`用于GZIP格式的...

    read-wirte--binary.rar_文件 分段

    针对这种情况,通常会采用文件分段的策略进行读写,以提高处理速度和系统资源利用率。本文将详细探讨“文件分段”这一技术及其在二进制文件中的应用。 文件分段是指将一个大文件分割成多个小段,然后分别进行读写...

    文件上传代码

    4. 文件预览:在上传前,可以通过FileReader API读取文件内容并显示预览。 二、文件解压 1. ZIP格式:常见的压缩格式有ZIP,它支持多文件和目录的打包。在服务器端,可以使用如Node.js的`adm-zip`库或者Python的`...

    数据文件分解

    1. **数据文件类型**: - .dat 文件是一种通用的文件格式,可以用于存储各种类型的数据,如文本、图像、音频或二进制数据。具体到 a.dat、b.dat 和 c.dat,它们可能是结构化的数据库记录,也可能是非结构化的日志...

    python文件传输demo

    为了减小文件传输的大小,可以使用Python的`zlib`, `gzip`, `bz2`或`lzma`库进行文件的压缩和解压缩,也可以使用`shutil`库的`compress`和`decompress`方法。 以上就是“python文件传输demo”中涉及的主要知识点,...

    C++ zip文件解压VS例子

    - 提取文件:对每个文件,调用`unzOpenCurrentFile`打开当前文件,然后使用`unzReadCurrentFile`读取文件内容并写入目标位置。 - 关闭ZIP文件:最后,使用`unzCloseCurrentFile`关闭当前文件,`unzClose`关闭整个...

    MySQL、NetCDF、N1、HDF5、HDF4读写操作类

    使用`h5py`库,我们能创建、打开HDF5文件,创建数据组和数据集,设置和读取数据,以及管理文件的链接和属性。 在实际应用中,这些读写操作类通常包含以下部分: 1. 连接与断开:建立与数据库(如MySQL)或文件(如...

    JAVA文件压缩与解压缩实践(源代码+文档).zip

    `GZIPOutputStream`用于创建gzip压缩的文件,而`GZIPInputStream`用于读取gzip压缩的文件。 4. **Deflater与Inflater**: `Deflater`类用于提供数据的压缩功能,而`Inflater`用于解压缩。它们可以直接与字节数组或...

    文件备份C#源程序

    1. **比较文件差别**:要比较两个文件的差异,可以读取它们的内容并进行逐字节对比,或者计算文件的哈希值(如MD5或SHA1)进行快速比较。如果哈希值不同,说明文件内容有改动。此外,还可以使用第三方库,如DiffPlex...

    文件压缩的库引用实现

    4. 多线程处理:对于大文件或大量文件,考虑使用多线程并行压缩以提高性能。 综上所述,实现文件压缩的库引用涉及对不同压缩算法的理解、选择合适的库以及正确使用库提供的API。在实际开发中,应根据项目需求和目标...

    [计算机项目]基于java的文件压缩与解压缩系统设计与实现(源代码+项目报告).zip

    在解压缩过程中,需要读取ZIP或GZIP文件的内容,这涉及到File类的使用,如`new File(String path)`创建文件对象,以及FileInputStream和FileOutputStream的使用来读写文件。 7. **数据块处理**: 为了提高效率,...

Global site tag (gtag.js) - Google Analytics