V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
zhongjun96
V2EX  ›  Linux

Ubuntu 下解压 gz 文件,如何限制速度?

  •  
  •   zhongjun96 · 14 天前 · 2156 次点击

    客户上传的是 gz 压缩包,解压后是单个 log 文件,压缩包大小1G左右,解压后10G左右。
    使用 gunzip 或者 gzip -d 解压文件,会跑满服务器硬盘速度 200M/s ,导致服务器上其他服务卡顿。
    有什么限制解压速度的方法吗?

    27 条回复    2024-05-15 21:26:09 +08:00
    nevadax
        1
    nevadax  
       14 天前 via iPhone
    限制进程的 io 占用
    zhongjun96
        2
    zhongjun96  
    OP
       14 天前
    @nevadax #1 有对应的工具或者命令吗?只看到可以限制 CPU 和内存占用,没看到可以限制 IO
    aloxaf
        4
    aloxaf  
       14 天前   ❤️ 9
    gunzip -c log.gz | pv -L 102400 > log
    dant
        5
    dant  
       14 天前
    在限速之前先建议尝试一下 ionice (
    phrack
        6
    phrack  
       14 天前 via iPhone
    楼上已经提了解决办法,我再歪一嘴。

    我估摸你解压出来是要读这个 log 文件?大部分编程软件可以不解压到磁盘直接读取 gz 文件,就是程序内自动解压。
    izoabr
        7
    izoabr  
       14 天前
    单独一个用户,然后限制这个用户的资源?或者如果只是单次操作的话,就解压运行只来后设置进程的优先级
    vivisidea
        8
    vivisidea  
       14 天前   ❤️ 2
    如果是解压完处理好就删掉的,服务器内存又足够,还可以考虑搞个内存盘 ramdisk

    ···
    mount -o size=16G -t tmpfs none /mnt/tmpfs
    ···


    https://unix.stackexchange.com/a/66331
    ldbC5uTBj11yaeh5
        9
    ldbC5uTBj11yaeh5  
       14 天前
    好几楼都没人提 zless 这个老派命令,v2ex 也开始低龄化了。
    mingwiki
        10
    mingwiki  
       14 天前
    @jigloo #9 zless 用的确实少,用的更多是的 zgrep , 或者用 zcat + head/tail + less 来替代 zless.
    22too
        11
    22too  
       14 天前
    上传解压的文件,换个机器执行。 不要在当前服务器上执行,可以解耦,并且后期如果要扩展,多加几个 work
    realpg
        12
    realpg  
       14 天前   ❤️ 1
    默认你是较新版本的操作系统, 比如 22.04 的 ubuntu, 比如最新的 debian 而不是上古内核的 centos 直接拷贝以下命令到 bash 脚本执行即可

    --------------------------

    #!/bin/bash

    echo "+io" >/sys/fs/cgroup/cgroup.subtree_control
    mkdir /sys/fs/cgroup/limitio


    echo $$ > /sys/fs/cgroup/limitio/cgroup.procs

    ls -la /dev/block/ | grep -v '/loop' | grep -v '/sr' | awk '{print $1, $2, $3, $4, $5, $9}' | grep -oP '\d+:\d+' | while read line
    do
    echo "$line wbps=52428800 rbps=52428800" > /sys/fs/cgroup/limitio/io.max 2>/dev/null
    done

    #this script's disk read and write are both set to 50MB/s, plz add your gzip -d command below


    #gzip -d a.gz


    ----------------

    格式如果错乱, 去下面复制:

    https://gist.github.com/realpg/f36ae7bc655d7eab6903fad82ead65f8

    请用 root 执行, uncomment 代码最后一行的 gzip 指令换成你自己的

    本脚本后面的任何语句的本地磁盘 IO 会被限速到读写各 50MB/s
    realpg
        13
    realpg  
       14 天前
    @aloxaf #4

    大内存机器, 没特殊优化的, 你这样写还会炸硬盘吞吐量

    缓冲区大的, 都限速写 ram buffer 里了, 然后刷新脏页时候还不限速的, 会堆死掉硬盘

    如果硬盘的限速是因为后端是类似云盘的 IPSAN 虚拟化挂载到虚拟机, 速度限制是因为存储网络带宽瓶颈, 甚至会导致这个盘的 IO 整体被内核 hang 住, 系统盘直接死机, 不是系统盘的话, 必须硬断电重启可破, 本机 reboot 命令都没用, 永久 hang 住

    如果空闲内存小的机器, 问题不大, 不会读吞吐量

    OP 这个问题 基本就是我们的面试题之一
    低成本嫖各大云厂商的 IOPS 和吞吐量

    您这个解答基本算是常见考虑不充分的错误答案
    zhongjun96
        14
    zhongjun96  
    OP
       13 天前
    @phrack #6 公司买的成品闭源软件,只能读 log 文件,没办法。
    因为涉及配方那些机密,又只能在同一台机器上解压,不然另外一台服务器解压好 scp 过去就好了,
    zhongjun96
        15
    zhongjun96  
    OP
       13 天前
    @vivisidea #8 内存严重不足
    zhongjun96
        16
    zhongjun96  
    OP
       13 天前
    @jigloo #9 我倒是知道 zless ,但是没看懂这个查看命令怎么能限制解压速度。
    直接 zless a.gz > a.log 也不合适
    aloxaf
        17
    aloxaf  
       13 天前
    @realpg #13 嗯,确实是的,不过我认为即使在不修改内核参数的情况下,也并非无解。
    首先可以想到的是继续增加限速,直到保证脏页刷新之前不会写入过多数据
    其次可以使用 dd 来手动控制刷新的时机: | dd of=log bs=100M iflag=fullblock oflag=dsync
    aloxaf
        18
    aloxaf  
       13 天前
    @realpg #12 这个是不是等效于 systemd-run -t -p "BlockIOWriteBandwidth=/dev/sda 50M" gzip -d a.gz

    (题外话:
    (我测了半天一直没效果,最后发现自己不知道啥时候切到 cgroup v1 去了,而 cgroup v1 只能限制 direct io 的速度
    zhongjun96
        19
    zhongjun96  
    OP
       13 天前
    @realpg #12 测试无效,还是跑到了 200M+
    realpg
        20
    realpg  
       13 天前   ❤️ 1
    @aloxaf #18
    对 cgroups v2 能控制 buffered io 才有这个彻底的方法
    用 systemd 的 slice 也可以实现类似方法 我对 systemd 研究不透彻

    @zhongjun96 #19
    那可能是我的哪个脚本写的有毛病 我就随手脑测手打的 理解思路自己修改即可 绝对是可用的
    查一下 cgroups v2 的状态 查一下分组的内容
    因为因为我的生产业务每天都依赖这玩意 遇到的问题跟你是一样的 而且比你的麻烦在于我这边的吞吐量问题是不限速就会因为写入超过 6GB/s 把虚拟化后端的 25Gbps*2 IPSAN 打死 机器直接死掉
    realpg
        21
    realpg  
       13 天前   ❤️ 1
    @zhongjun96 #19
    额 仔细看了下 你这是 buffered io 肯定是很快的
    这也是我跟 4 楼讨论的问题

    你需要用 iostat 查硬盘真实写入速度 这也是我这个办法的最核心的东西
    realpg
        22
    realpg  
       13 天前
    @aloxaf #17

    这里走 dd 还是建议用 odirect...
    fsync 也会有奇怪问题 我记不住是啥问题了 得看知识库 懒
    我们整天跟 io 打交道 为了把成本降低到正常使用云的 5%
    vivisidea
        23
    vivisidea  
       13 天前
    @zhongjun96 #15

    另外可以试试 FIFO 管道?解压的时候不直接解压到目标文件,而是解压到 FIFO 管道,程序也是去读这个管道

    示例
    ```
    vivi@pc:~/tmp/fifo$ mkfifo gz-fifo
    vivi@pc:~/tmp/fifo$ for i in {1..10000}; do echo $i >> file.txt; done
    vivi@pc:~/tmp/fifo$ gzip file.txt
    vivi@pc:~/tmp/fifo$ ls
    file.txt.gz gz-fifo
    vivi@pc:~/tmp/fifo$ gzip -d < file.txt.gz > gz-fifo

    此时 gzip 这个命令会 hang 住,因为 fifo 的 buffer 满了,然后开启另一个终端,直接 cat 这个 gz-fifo 文件,模拟程序读取,是可以读到完整数据的,这个过程应该不会写磁盘

    ```

    为啥这个 markdown code 不起作用阿艹😂
    zhongjun96
        24
    zhongjun96  
    OP
       13 天前
    @aloxaf #4 你这个命令可以
    julyclyde
        25
    julyclyde  
       13 天前
    @phrack 考虑到 gzip 是流式编码,用不解压直接读取的方式其实和解压是一样的,而且也会遇到一样的无法限速的问题
    phrack
        26
    phrack  
       13 天前 via iPhone
    @julyclyde 这个无法限速但是只会读硬盘了,就不会因为写硬盘导致卡死了
    phrack
        27
    phrack  
       13 天前 via iPhone
    @phrack 而且程序里也可以限速啊,你读 1kb 就只会解压这 1kb 或者再多一点点

    最后其实 op 上面说他们不能改程序这个办法不能用,但是还有个解决办法,其实有插件可以直接 mount zip 文件到文件系统上。

    啥玩意儿都能直接 mount 的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1075 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:11 · PVG 03:11 · LAX 12:11 · JFK 15:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.