使用pigz加速gzip压缩和解压

pigz是一个用于加速gzip压缩和解压的工具,它可以利用多核心来并行处理数据。它与标准的gzip命令完全兼容,只是更快。以下是如何使用pigz来加速.tar.gz文件的解压过程的步骤:

  1. 安装pigz: 如果还没有安装pigz,可以使用包管理器来安装。例如在Ubuntu上:
1
2
sudo apt-get update
sudo apt-get install pigz
  1. 多线程压缩:使用tar命令结合pigz开压缩文件,-p保持所有者权限
1
tar --use-compress-program=pigz -cvpf youfile.tar.gz yourfile
  1. 多线程解压: 使用tar命令结合pigz来解压.tar.gz文件。为了解压rk_android13.0_sdk.tar.gz,可以使用以下命令:
1
tar xf rk_android13.0_sdk.tar.gz --use-compress-program=pigz
  1. 这个命令会使用所有可用的CPU核心来解压文件。如果想限制使用的核心数,可以使用-p选项。例如,使用24个核心:
1
tar xf rk_android13.0_sdk.tar.gz --use-compress-program="pigz -p 24"

这样就可以利用多线程来快速解压大的.tar.gz文件了。

我们可以通过 tar + xz + 管道 的方式绕开这一限制。
tar -cvf - <压缩目标> | xz -T 0 -c > <压缩包名>.tar.xz
比如
tar -cvf - my_folder/ | xz -T 0 -c > my_folder.tar.xz

-T 后面跟上的参数是要使用的线程数量,0 代表尽可能多的使用 CPU 线程。

1
tar cf - paths-to-archive | pigz -9 -p 32 > archive.tar.gz

监控档案创建速度的选项:

1
tar --use-compress-program="pigz --best --recursive | pv" -cf archive.tar.gz YourData

使用rsync加速删除大量文件

可能需要先删除一个包含大量文件的目录。如果使用传统的rm -rf命令,可能会变得相对较慢,因为它会逐一删除每个文件。在这种情况下可以尝试使用rsync来加速删除过程。以下是如何使用rsync来删除一个目录的步骤:

  1. 创建一个空目录: 需要一个空目录作为源目录,用于同步到目标目录。例如可以创建一个名为empty_dir的空目录:
1
mkdir empty_dir
  1. 使用rsync同步并删除: 使用rsync -a --delete empty_dir/ rk_android13.0_sdk/命令来同步空目录到想要删除的目录,并删除所有文件。例如,如果想要删除名为`rk_android13.0_sdk的目录中的所有内容,可以使用以下命令:
1
rsync -a --delete empty_dir/ rk_android13.0_sdk/
  1. 这里:
  • -a:归档模式,表示递归复制并保留文件属性。
  • --delete:删除目标目录中的文件,使其与源目录同步。

可以利用rsync来快速删除一个包含大量文件的目录了。

使用pv查看进度

在上面的方法中,使用了一些命令来加速解压缩或删除过程。但是这些命令通常不会显示进度信息,这可能会让我们感到不确定或不耐烦。可以使用pv来实现。pv是一个终端工具,可以用来查看通过管道传输的数据的进度。以下是如何使用pv来查看解压缩或删除过程的进度的步骤:

  1. 安装pv: 如果还没有安装pv,可以使用包管理器来安装。例如Ubuntu上:

    1
    2
    sudo apt-get update
    sudo apt-get install pv
  2. 使用pv查看压缩进度

    1
    tar -cf - rices/ | pv -s "$(du -sb rices/ 2>/dev/null | awk '{print $1}' || echo 1000000000)" | pigz -9 -p 32 > rices.tar.gz

    1. 打包阶段:tar -cf - rices

    • tar: 经典的归档工具。
    • -c: 创建新的归档文件。
    • -f -: -f 选项指定归档文件的名称。这里的 - 是一个特殊参数,代表标准输出。所以 -f - 的意思不是创建文件,而是将打包好的数据流打印到标准输出。
    • rices: 要打包的目录名。
    • 作用: 将 rices/ 目录下的所有文件和子目录打包成一个未压缩的 tar 数据流,并通过标准输出传递给下一个命令(管道 |)。这是整个流程的起点。

    2. 进度显示阶段:pv -s $(...)

    • pv: Pipe Viewer 的缩写,是一个用于监控管道中数据流动进度的工具。它可以显示已传输的数据量、进度条、传输速率、预计剩余时间等。

    • -s SIZE: 指定整个数据流的预期总大小(以字节为单位)。这是显示准确进度条的关键。pv 需要知道总大小才能计算百分比。

    • $(...): 这是命令替换,Shell 会先执行括号内的命令,并将其输出结果作为 -s 参数的值。

      让我们深入分析这个计算总大小的子命令:$(du -sb rices/ 2>/dev/null | awk '{print \$1}' || echo 1000000000)

      • du -sb rices/:
        • du: 查看文件或目录的磁盘使用空间。
        • -s: 仅显示总计,不显示每个子目录的明细。
        • -b: 以字节为单位显示大小。
        • 这个命令会输出 rices/ 目录的总字节数,例如:123456789 rices/。
      • 2>/dev/null: 将 du 命令的错误输出重定向到“黑洞”(/dev/null)。如果 rices/ 目录不存在或没有读取权限,du 会报错,这个操作可以防止错误信息干扰主流程。
      • | awk '{print $1}': 将 du 的结果通过管道传递给 awk。awk '{print $1}' 会提取输出行的第一列,也就是纯数字的字节数(上面的 123456789)。
      • || echo 1000000000: 这是逻辑或操作。如果前面的 du ... | awk 命令执行失败(例如目录不存在),则执行 echo 1000000000,即输出一个很大的数字(1,000,000,000 字节 ≈ 1GB)。
        • 为什么这么做? 这是一种优雅的降级策略。如果无法获取目录真实大小,pv 仍然可以运行并显示进度,只是进度百分比会不准确(它会以为总大小是 1GB)。这比直接让 pv 因缺少 -s 参数而报错要好得多。

      小结: 这个子命令的目的是尽最大努力获取 rices/ 目录的准确大小,如果获取失败,就提供一个默认的估算值,确保 pv 能正常工作。

    3. 压缩阶段:pigz -p 32

    • pigz: 代表 parallel gzip。是 GNU gzip 的多线程实现,可以显著加快压缩速度,尤其是在多核 CPU 上。

    • -p 32: 指定使用 32 个线程进行压缩。这个数字通常设置为机器的 CPU 核心数或逻辑处理器数(你可以用 nproc 命令查看)。32 是一个很高的值,说明运行这条命令的机器性能很强。

    • 作用: 接收从 pv 传来的 tar 数据流,使用 32 个线程并行地对其进行 gzip 格式的压缩,然后将压缩后的数据流传递给下一个管道。

    • 想要极限压缩,可以使用 pigz 的最高压缩级别。pigz 的压缩级别范围是 1-9,其中:

      • -1 最快压缩(最低压缩率)

      • -9 最慢压缩(最高压缩率)

      • 默认是 -6

        想要更极致的压缩:

        使用 zstd(通常比 gzip 压缩率更好):

        1
        2
        3
        4
        5
        # 安装 zstd(如果尚未安装)
        # Ubuntu/Debian: sudo apt install zstd
        # CentOS/RHEL: sudo yum install zstd

        tar -cf - rices/ | pv -s $(du -sb rices/ 2>/dev/null | awk '{print \$1}' || echo 1000000000) | zstd -T32 -19 > rices.tar.zst

        使用 xz(最高压缩率但最慢):

        1
        tar -cf - rices/ | pv -s $(du -sb rices/ 2>/dev/null | awk '{print \$1}' || echo 1000000000) | xz -T32 -9 > rices.tar.xz

    4. 输出阶段:> rices.tar.gz

    • >: 输出重定向符号。
    • rices.tar.gz: 最终生成的压缩文件名。
    • 作用: 将 pigz 压缩后的数据流从标准输出重定向到当前目录下的 rices.tar.gz 文件中,完成文件的创建。
  3. 使用pv查看压缩进度: 可以将pv与tar和pigz结合使用来查看解压缩进度。使用pv来监视文件的读取进度,然后通过管道将数据传递给tar和pigz。

    1
    pv rk_android13.0_sdk.tar.gz | tar xf - --use-compress-program=pigz

    这里我们需要指定文件的总大小,以便pv能够正确显示百分比和剩余时间。可以使用以下命令来获取文件的总大小(以字节为单位):

    1
    du -b rk_android13.0_sdk.tar.gz | cut -f 1

    然后我们可以将这个值作为参数传递给pv -s选项:

    1
    pv -s $(du -b rk_android13.0_sdk.tar.gz | cut -f 1) rk_android13.tar.gz | tar xf - --use-compress-program=pigz

    当解压缩文件时,pv会显示一个进度条,表示已经读取的数据量、总数据量、百分比、已用时间、剩余时间和当前速度。

    使用pv查看删除进度: 可以将pv与rsync结合使用来查看删除进度。首先,使用du -s --block-size=1 your_large_dir/ | cut -f 1 命令来获取想要删除的目录的总大小(以字节为单位)。然后,使用以下命令来同步空目录并删除所有文件:

1
rsync -a --delete --progress empty_dir/ rk_android13.0_sdk/ | pv -l -s $(du -s --block-size=1 rk_android13.0_sdk/ | cut -f 1) > /dev/null
  1. 这里:
  • -l:表示按行计数。
  • -s $(du -s --block-size=1 rk_android13.0_sdk/ | cut -f 1):表示设置进度条的总大小为目标目录的大小。

当删除目录时,pv会显示一个进度条,表示已经删除的文件数、总文件数、百分比、已用时间、剩余时间和当前速度。