bz2的解压可以并行吗?

问题描述 投票:0回答:2

我正在使用pythons bz2模块生成(并压缩)一个大的jsonl文件(bzip2压缩17GB)。

但是,当我后来尝试使用 pbzip2 解压它时,它似乎只使用 one CPU 核心来解压,这非常慢。

当我用 pbzip2 压缩它时,它可以利用多个核心进行解压缩。有没有办法在 python 中以 pbzip2 兼容格式进行压缩?

import bz2,sys
from Queue import Empty
#...
compressor = bz2.BZ2Compressor(9)
f = open(path, 'a')

    try:
        while 1:
            m = queue.get(True, 1*60)
            f.write(compressor.compress(m+"\n"))
    except Empty, e:
        pass
    except Exception as e:
        traceback.print_exc()
    finally:
        sys.stderr.write("flushing")
        f.write(compressor.flush())
        f.close()
python python-2.7 multiprocessing bzip2 bzip
2个回答
5
投票

一个

pbzip2
流只不过是多个
bzip2
流的串联。

使用 shell 的示例:

bzip2 < /usr/share/dict/words > words_x_1.bz2
cat words_x_1.bz2{,,,,,,,,,} > words_x_10.bz2
time bzip2 -d < words_x_10.bz2 > /dev/null
time pbzip2 -d < words_x_10.bz2 > /dev/null

我从未使用过 python 的

bz2
模块,但应该很容易在
'a'
pend 模式下关闭/重新打开流,每这么多字节,以获得相同的结果。请注意,如果
BZ2File
是从现有的类文件对象构造的,则关闭
BZ2File
将不会关闭底层流(这正是您想要的)。

我还没有测量多少字节最适合分块,但我猜测每 1-20 MB - 它肯定需要大于 bzip2 块大小 (900k)。

另请注意,如果记录每个块的压缩和未压缩偏移量,则可以进行相当有效的随机访问。这就是

dictzip
程序的工作方式,尽管它是基于
gzip


3
投票

如果您绝对必须在解压时使用

pbzip2
,这对您没有帮助,但替代方案
lbzip2
可以对“正常”
.bz2
文件执行多核解压,例如由 Python 的
BZ2File
或传统
 生成的文件bzip2
命令。这避免了您所描述的
pbzip2
的限制,即只有使用
pbzip2
压缩文件时才能实现并行解压缩。请参阅https://github.com/kjn/lbzip2/

作为奖励,基准测试表明

lbzip2
pbzip2
快得多,无论是解压(快 30%)还是压缩(快 40%),同时实现略优的压缩比。此外,其峰值 RAM 使用量还不到
pbzip2
使用的 RAM 的 50%。请参阅https://vbtechsupport.com/1614/

© www.soinside.com 2019 - 2024. All rights reserved.