关于提高 dd 的性能, blocksize 和压缩算法讨论

63 天前
 liyafe1997

我经常用 dd 备份数据,大概是从 SSD 上 dd 整个硬盘或者分区的 block device 到机械硬盘(读入端的性能为写出端的 10+倍),并且经过 pigz 压缩 (dd if=/sda bs=xx | pigz >xxxx.img.gz类似这样)

bs 我经常喜欢设置成较大的值,比如 512M ,1024M ,因为以前似乎印象中设置一个太小的 bs 比如 KB 级的或者 1M 性能会比较差,但是似乎发现一个现象:硬盘不会连续读写,假如设置成 1024M ,是不是 dd 先从源盘读满 1G 的数据,然后再往 pipe 那边扔,等待 pipe 写完之后,再读下一个 1G ?如果是这样的话,就影响吞吐量了,等于有某个时间段管道的某一端是空闲状态。

还有一个现象似乎可以佐证这一点,pigz 能把我的 CPU 跑满,但是看 CPU 占用率的曲线,每隔几秒(大概 10 秒左右?)会有一个 1~2s 的凹槽( CPU 使用率下降,降到 0%),这似乎是在等待读盘/写盘。

我想的是,既然入比出的性能高很多,那如何让 buffer 始终处于满的状态,让输出端( pigz 和写出设备)一直有东西吃,而不是等它们吃完再读入下一个 block ,然后这过程中它们没东西可吃。

总之,如何优化能提高整个 dd 的性能,或者有什么更好的方案吗?

另外我刚在 stackoverflow 看到另一种压缩方案,用 squashfs 流式压缩:

sudo mksquashfs empty-dir squash.img -p 'sda_backup.img f 444 root root dd if=/dev/sda1 status=progress bs=512M'

这样好处是以后 dd 出来的镜像方便挂载(如果直接对 block device 做 gzip 以后确实不太方便使用),目前还没测这个方案性能如何,不知道各位有什么高见?以及现在 squashfs 有多种压缩算法可以选,在这种场景下哪种效能最好呢?

1256 次点击
所在节点    Linux
9 条回复
billlee
63 天前
bs 一般设置成 MB 级就不影响性能了。
备份文件用 tar 也好,用 squashfs 也好,都好过用 dd, 因为 sdd 不理解文件系统,会把无意义的空白空间也复制一份。
压缩算法用 zstd 就好了,调压缩级别就可以适合各种不同场景。
liyafe1997
63 天前
@billlee 不是备份文件,我的目的就是要备份整个 block device
GrayXu
63 天前
你的发现是对的,dd 同时只操作一个 blocksize ,pipe 本身并没有这么大的 buffer ,dd 等 pipe 拿完所有源数据后再去读新的源数据。但你这个场景下是写入盘 io bound ,提升 dd 的性能(比如说持有两个或者环形 buffer )对整体性能影响不会很大。

但其实平衡 pipe 两端吞吐倒是一个很多讨论过的话题,比如包括 pigz 在内的压缩软件可以动态压缩率来匹配 pipe 的速率
514146235
63 天前
一般备份这种 block 设备,我会用 qemu-img 转成 qcow2 。
qcow2 支持压缩,也支持 mount 操作。
liyafe1997
63 天前
@GrayXu 感谢!
我感觉 io bound 不完全在写入盘,主要在 pigz (因为 CPU 所有核能跑 100%?),以及等待读盘的时候浪费的时间。因为从 iotop 和写入盘的硬盘灯闪烁情况来看,写入盘并不是一直跑满的。
liyafe1997
63 天前
@514146235 感谢!好主意!回头试试性能如何。
deorth
62 天前
换 btrfs/zfs ,用文件系统的 send 功能
liyafe1997
62 天前
@deorth 虽然但是请审题,我说的是备份 block device ,没说备份文件系统
deorth
62 天前
@liyafe1997 XY 问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1021194

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX