首页 > 解决方案 > 如何在 bash/shell 中节流管道

问题描述

背景

我正在恢复数据库的 tar 快照。

在恢复它时,由于磁盘 I/O 饱和,我的计算机几乎无法使用。

不幸的是,我的操作系统(Ubuntu 18.04)使用了最后期限 I/O 调度程序,它忽略了任何 I/O 优先级的概念。

问题

相反,我正在尝试创建一个限制读取源 tar 的 shell 管道。

something db.tar.gz | tar xzf -

因此,我可以控制我的写入速度并假装我的操作系统缺少真正的 I/O 调度程序。

我怎样才能做到这一点?

试图

到目前为止,我已经尝试过pv,但它似乎不适合这项任务。

pv -L 5M db.tar.gz | tar xzf -

进度表会定期显示速度比限制高出数倍,发生这种情况时我的电脑会锁定。

标签: linuxbashshellio

解决方案


系统阻塞磁盘 IO 并要求限制吞吐量是不正常的,但是您在 StackOverflow 上询问而不是在 ServerFault 上询问,所以...

pv命令如宣传的那样工作。你看到速度峰值的原因是它tar暂时太慢了,所以pv让它读得更快,以赶上平均 5 MiB/s。

任何给定的 5MB 压缩数据块都可以对应于从 5MB 到 100MB+ 的任何未压缩数据,因此为了使处理更加统一,您可以在解压缩应用它:

gzip -d < db.tar.gz | pv -L 5M | tar x

如果做不到这一点,您可以编写一个 bash 循环,该循环将以稳定的速度编写并且不允许追赶:

cat db.tar.gz |
    while sleep 1 && [[ $(LC_ALL=C dd bs=5M count=1 2>&1 >&3) != "0+0 records"* ]] 3>&1; do true; done |
    pv |
    tar xz

推荐阅读