在加密卷上使用压缩文件系统会提高性能吗?

Pet*_*etr 7 filesystems encryption compression dm-crypt btrfs

加密/解密通常是访问加密卷时的主要瓶颈。使用具有快速透明压缩(例如 BTRFS + LZO)的文件系统会有帮助吗?这个想法是要加密的数据会更少,如果压缩比加密算法快得多,整体处理时间就会更少。

更新:正如 Mat 所指出的,这取决于实际数据的可压缩性。当然,我假设它是可压缩的,就像源代码或文件一样。当然,将它用于媒体文件没有任何意义(但我想它不会造成太大伤害,因为BTRFS 会尝试检测不可压缩的文件。)

由于测试这个想法是一个非常耗时的过程,我问是否有人已经有这方面的经验。我只测试了一个非常简单的设置,它似乎显示出不同:

$ touch BIG_EMPTY
$ chattr +c BIG_EMPTY
$ sync ; time ( dd if=/dev/zero of=BIG_EMPTY bs=$(( 1024*1024 )) count=1024 ; sync )
...
real    0m26.748s
user    0m0.008s
sys 0m2.632s

$ touch BIG_EMPTY-n
$ sync ; time ( dd if=/dev/zero of=BIG_EMPTY-n bs=$(( 1024*1024 )) count=1024 ; sync )
...
real    1m31.882s
user    0m0.004s
sys 0m2.916s
Run Code Online (Sandbox Code Playgroud)

fro*_*utz 9

我做了一个小的基准测试。不过,它只测试写入。

测试数据是Linux内核源码树(linux-3.8),已经解压到内存(/dev/shm/tmpfs)中,所以尽量不受数据源的影响。我在此测试中使用了可压缩数据,因为无论加密如何,使用不可压缩文件进行压缩都是无稽之谈。

在 4GiB LVM 卷、LUKS [aes、xts-plain、sha256]、RAID-5 上使用 btrfs 文件系统,超过 3 个磁盘,块大小为 64kb。CPU 是没有 AES-NI 的 Intel E8400 2x3Ghz。内核是 3.8.2 x86_64。

剧本:

#!/bin/bash

PARTITION="/dev/lvm/btrfs"
MOUNTPOINT="/mnt/btrfs"

umount "$MOUNTPOINT" >& /dev/null

for method in no lzo zlib
do
    for iter in {1..3}
    do
        echo Prepare compress="$method", iter "$iter"
        mkfs.btrfs "$PARTITION" >& /dev/null
        mount -o compress="$method",compress-force="$method" "$PARTITION" "$MOUNTPOINT"
        sync
        time (cp -a /dev/shm/linux-3.8 "$MOUNTPOINT"/linux-3.8 ; umount "$MOUNTPOINT")
        echo Done compress="$method", iter "$iter"
    done
done
Run Code Online (Sandbox Code Playgroud)

因此,在每次迭代中,它都会创建一个新的文件系统,并测量从内存和 umount 复制 linux 内核源代码所需的时间。所以这是一个纯粹的写测试,零读取。

结果:

Prepare compress=no, iter 1

real 0m12.790s
user 0m0.127s
sys 0m2.033s
Done compress=no, iter 1
Prepare compress=no, iter 2

real 0m15.314s
user 0m0.132s
sys 0m2.027s
Done compress=no, iter 2
Prepare compress=no, iter 3

real 0m14.764s
user 0m0.130s
sys 0m2.039s
Done compress=no, iter 3
Prepare compress=lzo, iter 1

real 0m11.611s
user 0m0.146s
sys 0m1.890s
Done compress=lzo, iter 1
Prepare compress=lzo, iter 2

real 0m11.764s
user 0m0.127s
sys 0m1.928s
Done compress=lzo, iter 2
Prepare compress=lzo, iter 3

real 0m12.065s
user 0m0.132s
sys 0m1.897s
Done compress=lzo, iter 3
Prepare compress=zlib, iter 1

real 0m16.492s
user 0m0.116s
sys 0m1.886s
Done compress=zlib, iter 1
Prepare compress=zlib, iter 2

real 0m16.937s
user 0m0.144s
sys 0m1.871s
Done compress=zlib, iter 2
Prepare compress=zlib, iter 3

real 0m15.954s
user 0m0.124s
sys 0m1.889s
Done compress=zlib, iter 3
Run Code Online (Sandbox Code Playgroud)

因为zlib它慢了很多,lzo快了一点,而且一般来说,不值得打扰(考虑到我在这个测试中使用了易于压缩的数据,差异对我来说太小了)。

我也会做一个读取测试,但它更复杂,因为你必须处理缓存。

  • 对于读取速度,我获得了 zlib(42-46s)的最佳结果,其次是 lzo(46-48s),其次是无压缩(58-59s)。我的读取测试是 `time (xargs cat < /dev/shm/files | md5sum)`(文件是 linux-3.8 内核树中的所有文件),在 `sync 之后;echo 3 > /proc/sys/vm/drop_caches` 和新安装的 fs,作为写入平台卸载。所以...... zlib 需要更长的时间来编写,但读取速度最快。只要您的文件都易于压缩。我个人仍然不会打扰它,但是 ymmv。 (2认同)