Ubuntu 下解压 gz 文件,如何限制速度?
客户上传的是 gz 压缩包,解压后是单个 log 文件,压缩包大小1G左右,解压后10G左右。
使用 gunzip 或者 gzip -d 解压文件,会跑满服务器硬盘速度 200M/s ,导致服务器上其他服务卡顿。
有什么限制解压速度的方法吗?
限制进程的 io 占用
#1 有对应的工具或者命令吗?只看到可以限制 CPU 和内存占用,没看到可以限制 IO
unix.stackexchange.com/questions/48138/how-to-throttle-per-process-i-o-to-a-max-limit
gunzip -c log.gz | pv -L 102400 > log
在限速之前先建议尝试一下 ionice (
楼上已经提了解决办法,我再歪一嘴。我估摸你解压出来是要读这个 log 文件?大部分编程软件可以不解压到磁盘直接读取 gz 文件,就是程序内自动解压。
单独一个用户,然后限制这个用户的资源?或者如果只是单次操作的话,就解压运行只来后设置进程的优先级
如果是解压完处理好就删掉的,服务器内存又足够,还可以考虑搞个内存盘 ramdisk···mount -o size=16G -t tmpfs none /mnt/tmpfs··· unix.stackexchange.com/a/66331
好几楼都没人提 zless 这个老派命令,v2ex 也开始低龄化了。
#9 zless 用的确实少,用的更多是的 zgrep , 或者用 zcat + head/tail + less 来替代 zless.
上传解压的文件,换个机器执行。 不要在当前服务器上执行,可以解耦,并且后期如果要扩展,多加几个 work
默认你是较新版本的操作系统, 比如 22.04 的 ubuntu, 比如最新的 debian 而不是上古内核的 centos 直接拷贝以下命令到 bash 脚本执行即可--------------------------#!/bin/bashecho "+io" >/sys/fs/cgroup/cgroup.subtree_controlmkdir /sys/fs/cgroup/limitioecho $$ > /sys/fs/cgroup/limitio/cgroup.procsls -la /dev/block/ | grep -v '/loop' | grep -v '/sr' | awk '{print $1, $2, $3, $4, $5, $9}' | grep -oP '\d+:\d+' | while read linedo echo "$line wbps=52428800 rbps=52428800" > /sys/fs/cgroup/limitio/io.max 2>/dev/nulldone#this script's disk read and write are both set to 50MB/s, plz add your gzip -d command below#gzip -d a.gz----------------格式如果错乱, 去下面复制: gist.github.com/realpg/f36ae7bc655d7eab6903fad82ead65f8请用 root 执行, uncomment 代码最后一行的 gzip 指令换成你自己的本脚本后面的任何语句的本地磁盘 IO 会被限速到读写各 50MB/s
#4 大内存机器, 没特殊优化的, 你这样写还会炸硬盘吞吐量缓冲区大的, 都限速写 ram buffer 里了, 然后刷新脏页时候还不限速的, 会堆死掉硬盘如果硬盘的限速是因为后端是类似云盘的 IPSAN 虚拟化挂载到虚拟机, 速度限制是因为存储网络带宽瓶颈, 甚至会导致这个盘的 IO 整体被内核 hang 住, 系统盘直接死机, 不是系统盘的话, 必须硬断电重启可破, 本机 reboot 命令都没用, 永久 hang 住如果空闲内存小的机器, 问题不大, 不会读吞吐量OP 这个问题 基本就是我们的面试题之一 低成本嫖各大云厂商的 IOPS 和吞吐量您这个解答基本算是常见考虑不充分的错误答案
#6 公司买的成品闭源软件,只能读 log 文件,没办法。因为涉及配方那些机密,又只能在同一台机器上解压,不然另外一台服务器解压好 scp 过去就好了,
#8 内存严重不足
#9 我倒是知道 zless ,但是没看懂这个查看命令怎么能限制解压速度。直接 zless a.gz > a.log 也不合适
#13 嗯,确实是的,不过我认为即使在不修改内核参数的情况下,也并非无解。首先可以想到的是继续增加限速,直到保证脏页刷新之前不会写入过多数据其次可以使用 dd 来手动控制刷新的时机: | dd of=log bs=100M iflag=fullblock oflag=dsync
#12 这个是不是等效于 systemd-run -t -p "BlockIOWriteBandwidth=/dev/sda 50M" gzip -d a.gz(题外话:(我测了半天一直没效果,最后发现自己不知道啥时候切到 cgroup v1 去了,而 cgroup v1 只能限制 direct io 的速度
#12 测试无效,还是跑到了 200M+
#18 对 cgroups v2 能控制 buffered io 才有这个彻底的方法用 systemd 的 slice 也可以实现类似方法 我对 systemd 研究不透彻 #19 那可能是我的哪个脚本写的有毛病 我就随手脑测手打的 理解思路自己修改即可 绝对是可用的查一下 cgroups v2 的状态 查一下分组的内容因为因为我的生产业务每天都依赖这玩意 遇到的问题跟你是一样的 而且比你的麻烦在于我这边的吞吐量问题是不限速就会因为写入超过 6GB/s 把虚拟化后端的 25Gbps*2 IPSAN 打死 机器直接死掉
#19 额 仔细看了下 你这是 buffered io 肯定是很快的这也是我跟 4 楼讨论的问题你需要用 iostat 查硬盘真实写入速度 这也是我这个办法的最核心的东西
#17 这里走 dd 还是建议用 odirect...fsync 也会有奇怪问题 我记不住是啥问题了 得看知识库 懒我们整天跟 io 打交道 为了把成本降低到正常使用云的 5%
#15 另外可以试试 FIFO 管道?解压的时候不直接解压到目标文件,而是解压到 FIFO 管道,程序也是去读这个管道示例vivi@pc:~/tmp/fifo$ mkfifo gz-fifovivi@pc:~/tmp/fifo$ for i in {1..10000}; do echo $i >> file.txt; donevivi@pc:~/tmp/fifo$ gzip file.txt vivi@pc:~/tmp/fifo$ lsfile.txt.gz gz-fifovivi@pc:~/tmp/fifo$ gzip -d < file.txt.gz > gz-fifo此时 gzip 这个命令会 hang 住,因为 fifo 的 buffer 满了,然后开启另一个终端,直接 cat 这个 gz-fifo 文件,模拟程序读取,是可以读到完整数据的,这个过程应该不会写磁盘
为啥这个 markdown code 不起作用阿艹😂
#4 你这个命令可以
考虑到 gzip 是流式编码,用不解压直接读取的方式其实和解压是一样的,而且也会遇到一样的无法限速的问题
这个无法限速但是只会读硬盘了,就不会因为写硬盘导致卡死了
而且程序里也可以限速啊,你读 1kb 就只会解压这 1kb 或者再多一点点最后其实 op 上面说他们不能改程序这个办法不能用,但是还有个解决办法,其实有插件可以直接 mount zip 文件到文件系统上。啥玩意儿都能直接 mount 的。
现在 deployment 一般都是 docker 或者类似系统 在生产环境之外,都会有不同的测试环境,比如 staging,qa 等 假设 build 好的 image 都是…
前些天买了机械师 创物者 mini2 , 这颗 amd 7840h 带的 780m 核显,在 linux(fedora38, kernel 6.5.9)里跑不了几分钟就黑屏,可…
插入数据要求工号转 ID 这个步骤,让他调接口去查这个映射,实际上这个查询也不慢,100ms ,反正是一次性操作,这个数据迁移做了再就不做了,查库查表区别不大 相关的公司只有 …