客户上传的是 gz 压缩包,解压后是单个 log 文件,压缩包大小1G左右,解压后10G左右。
使用 gunzip
或者 gzip -d
解压文件,会跑满服务器硬盘速度 200M/s ,导致服务器上其他服务卡顿。
有什么限制解压速度的方法吗?
1
7lQM1uTy635LOmbu 222 天前 via iPhone
限制进程的 io 占用
|
2
zhongjun96 OP @nevadax #1 有对应的工具或者命令吗?只看到可以限制 CPU 和内存占用,没看到可以限制 IO
|
3
7lQM1uTy635LOmbu 222 天前 via iPhone 1
|
4
aloxaf 222 天前 9
gunzip -c log.gz | pv -L 102400 > log
|
5
dant 221 天前
在限速之前先建议尝试一下 ionice (
|
6
phrack 221 天前 via iPhone
楼上已经提了解决办法,我再歪一嘴。
我估摸你解压出来是要读这个 log 文件?大部分编程软件可以不解压到磁盘直接读取 gz 文件,就是程序内自动解压。 |
7
izoabr 221 天前
单独一个用户,然后限制这个用户的资源?或者如果只是单次操作的话,就解压运行只来后设置进程的优先级
|
8
vivisidea 221 天前 2
如果是解压完处理好就删掉的,服务器内存又足够,还可以考虑搞个内存盘 ramdisk
··· mount -o size=16G -t tmpfs none /mnt/tmpfs ··· https://unix.stackexchange.com/a/66331 |
9
ldbC5uTBj11yaeh5 221 天前
好几楼都没人提 zless 这个老派命令,v2ex 也开始低龄化了。
|
11
22too 221 天前
上传解压的文件,换个机器执行。 不要在当前服务器上执行,可以解耦,并且后期如果要扩展,多加几个 work
|
12
realpg 221 天前 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 |
13
realpg 221 天前
@aloxaf #4
大内存机器, 没特殊优化的, 你这样写还会炸硬盘吞吐量 缓冲区大的, 都限速写 ram buffer 里了, 然后刷新脏页时候还不限速的, 会堆死掉硬盘 如果硬盘的限速是因为后端是类似云盘的 IPSAN 虚拟化挂载到虚拟机, 速度限制是因为存储网络带宽瓶颈, 甚至会导致这个盘的 IO 整体被内核 hang 住, 系统盘直接死机, 不是系统盘的话, 必须硬断电重启可破, 本机 reboot 命令都没用, 永久 hang 住 如果空闲内存小的机器, 问题不大, 不会读吞吐量 OP 这个问题 基本就是我们的面试题之一 低成本嫖各大云厂商的 IOPS 和吞吐量 您这个解答基本算是常见考虑不充分的错误答案 |
14
zhongjun96 OP |
15
zhongjun96 OP @vivisidea #8 内存严重不足
|
16
zhongjun96 OP @jigloo #9 我倒是知道 zless ,但是没看懂这个查看命令怎么能限制解压速度。
直接 zless a.gz > a.log 也不合适 |
17
aloxaf 221 天前
@realpg #13 嗯,确实是的,不过我认为即使在不修改内核参数的情况下,也并非无解。
首先可以想到的是继续增加限速,直到保证脏页刷新之前不会写入过多数据 其次可以使用 dd 来手动控制刷新的时机: | dd of=log bs=100M iflag=fullblock oflag=dsync |
18
aloxaf 221 天前
@realpg #12 这个是不是等效于 systemd-run -t -p "BlockIOWriteBandwidth=/dev/sda 50M" gzip -d a.gz
(题外话: (我测了半天一直没效果,最后发现自己不知道啥时候切到 cgroup v1 去了,而 cgroup v1 只能限制 direct io 的速度 |
19
zhongjun96 OP |
20
realpg 221 天前 1
@aloxaf #18
对 cgroups v2 能控制 buffered io 才有这个彻底的方法 用 systemd 的 slice 也可以实现类似方法 我对 systemd 研究不透彻 @zhongjun96 #19 那可能是我的哪个脚本写的有毛病 我就随手脑测手打的 理解思路自己修改即可 绝对是可用的 查一下 cgroups v2 的状态 查一下分组的内容 因为因为我的生产业务每天都依赖这玩意 遇到的问题跟你是一样的 而且比你的麻烦在于我这边的吞吐量问题是不限速就会因为写入超过 6GB/s 把虚拟化后端的 25Gbps*2 IPSAN 打死 机器直接死掉 |
21
realpg 221 天前 1
|
22
realpg 221 天前
|
23
vivisidea 221 天前
@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 不起作用阿艹😂 |
24
zhongjun96 OP |