我需要在资源有限且对延迟非常敏感的环境中尽快下载并解压缩文件(具有 1 个 cpu、2 个内核、128MB RAM 的虚拟机)
当然,我尝试将下载过程通过管道传输到解压缩过程,并假设我可以在下载的同时解压缩。我知道管道被最慢的进程阻塞。为了克服这个问题,我在下载和解压缩过程之间使用了一个缓冲区。
我的 shell 脚本看起来像这样:
curl -s $CACHE_URL | buffer -S 100M | lz4 -d > /tmp/myfile
如果我首先下载压缩文件,然后在不使用管道的情况下解压缩,则下载大约需要 250 毫秒,如果按顺序执行,解压缩大约需要 250 毫秒。
因此,我的假设是管道方法将花费大约 250-275 毫秒,因为中间没有额外的磁盘读取,并且下载不像解压缩那样受 CPU 限制,因此不会影响那么多。
但事实并非如此。正如我的日志所示,它的速度稍快一些:
Start download
35211K, 81131K/s
Download & decompressed done in 447ms
Starting individual download & decompress
Download done in 234ms
Decompressed : 61 MiB
/tmp/myfile : decoded 75691880 bytes
Decompress done in 230ms
我这里是不是想错了?还有其他方法可以加快这个速度吗?
答案1
长话短说: 我已经测试了你的命令,它似乎可以在我的机器上运行。最短下载+解压缩时间约为 800ms+,脚本使用缓冲区的最短时间为 700ms。
我建议在另一个硬件上测试您的脚本,看看您的虚拟机的 CPU 是否是瓶颈,就像评论中已经建议的那样。现在,我不确定这个“答案”会对您有多大帮助,但无论如何它就是这样。
首先,我测试了 Stéphane 使用 16K 块和 32M mem 块的建议,报告的结果要好得多(大约快 60%):
$ cat compressed.lz4 | buffer -S 100M | lz4 -d > /tmp/myfile
11858K, 104017K/s
$ cat compressed.lz4 | buffer -s 16K -m 32M -S 100M | lz4 -d > /tmp/myfile
11858K, 162438K/s
但是,在测试您的命令后:
curl -s http://192.168.24.105/compressed2.lz4 | buffer -S 100M | lz4 -d > /tmp/myfile
结果更好没有更改任何缓冲区参数。
我还注意到使用 lz4 保存文件(不将其输出到 /dev/null)会增加大约 100 毫秒的时间。
就我而言:
file: 70MB
download time: ~700ms (minimum of 650ms)
decompress and save to /dev/null: ~160ms - 220ms
decompress and save to /tmp/file: ~310ms
decompress and save to a tempfs: ~300ms (slightly better??)
test.bash: ~700ms - 1000ms
test2.bash: ~1100ms, minimum recorded of 800ms
使用的脚本: 下载.bash
start=`date +%s%3N`
curl -s http://192.168.24.105/compressed2.lz4 >/dev/null
end=`date +%s%3N`
echo Execution time was `expr $end - $start` milliseconds.
解压缩.bash
start=`date +%s%3N`
lz4 -d /home/pi/compressed2.lz4 > /dev/null
end=`date +%s%3N`
echo Execution time was `expr $end - $start` milliseconds.
测试.bash
start=`date +%s%3N`
curl -s http://192.168.24.105/compressed2.lz4 | buffer -S 100M | lz4 -d > /tmp/myfile
end=`date +%s%3N`
echo Execution time was `expr $end - $start` milliseconds.
测试2.bash
start=`date +%s%3N`
curl -s http://192.168.24.105/compressed2.lz4 | buffer -s 128K -m 32M | lz4 -d > /tmp/myfile
end=`date +%s%3N`
echo Execution time was `expr $end - $start` milliseconds.