bash - Bash 中的并行 wget

标签 bash parallel-processing wget

<分区>

我从一个网站上获得了一堆相对较小的页面,我想知道我是否可以在 Bash 中以某种方式并行执行这些操作。目前我的代码看起来像这样,但需要一段时间才能执行(我认为让我变慢的是连接延迟)。

for i in {1..42}
do
    wget "https://www.example.com/page$i.html"
done

我听说过使用 xargs,但我对此一无所知,而且手册页非常困惑。有任何想法吗?甚至可以并行执行此操作吗?还有其他方法可以解决这个问题吗?

最佳答案

比使用 &-bwget 插入后台更可取,您可以使用 xargs 来效果一样,而且更好。

优点是 xargs正确同步,无需额外工作。这意味着您可以安全地访问下载的文件(假设没有发生错误)。一旦 xargs 退出,所有下载都将完成(或失败),并且您可以通过退出代码知道是否一切顺利。这比忙着等待 sleep 和手动测试完成要好得多。

假设 URL_LIST 是一个包含所有 URL 的变量(可以在 OP 的示例中使用循环构造,但也可以是手动生成的列表),运行此命令:

echo $URL_LIST | xargs -n 1 -P 8 wget -q

一次将一个参数(-n 1)传给wget,一次最多执行8个并行的wget进程(-P 8)。 xarg 在最后一个生成的进程完成后返回,这正是我们想知道的。不需要额外的技巧。

我选择的 8 个并行下载的“神奇数字”并不是一成不变的,但它可能是一个很好的折衷方案。 “最大化”一系列下载有两个因素:

一个是填充“电缆”,即利用可用带宽。假设“正常”条件(服务器的带宽大于客户端),一次或最多两次下载已经是这种情况。在这个问题上投入更多的连接只会导致数据包被丢弃和 TCP 拥塞控制开始,N 以渐进的 1/N 带宽下载每个,达到相同的净效果(减去丢弃的数据包,减去窗口大小恢复)。丢包在 IP 网络中是很正常的事情,这就是拥塞控制的工作原理(即使是单个连接),通常影响几乎为零。然而,拥有不合理的大量连接会放大这种影响,因此它会变得很明显。无论如何,它不会使任何事情变得更快。

第二个因素是连接建立和请求处理。在这里,在飞行中建立一些额外的联系真的很有帮助。一个人面临的问题是两次往返的延迟(在同一地理区域内通常为 20-40 毫秒,洲际之间为 200-300 毫秒)加上服务器实际需要处理请求和推送回复的奇数 1-2 毫秒到 socket 。这不是很多时间本身,但乘以几百/千个请求,它很快就会加起来。
从六个到十几个请求中的任何东西都隐藏了大部分或全部这种延迟(它仍然存在,但由于它重叠,所以它没有总结!)。同时,只有少数并发连接不会产生不利影响,例如导致过度拥塞或迫使服务器 fork 新进程。

关于bash - Bash 中的并行 wget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7577615/

相关文章:

bash - 使用 bash 脚本的输出作为 Terraform 中的变量

bash - 如何评估docker-compose.yml文件中的动态变量?

matlab - MATLAB 的 parfeval 函数是如何工作的?

r - 在 R parallel::mcparallel 中,是否有可能限制一次使用的内核数量?

c# - 并行 Entity Framework

jenkins - 尝试使用 wget 触发远程 Jenkins 作业时出现 405 错误

linux - 清理ubuntu服务器上的备份文件

bash - 使用 wget 优化网页抓取

wget - 如何使用wget下载带有mathjax的站点的本地副本?

python - 如何将 zip 文件拆分为多个有效的 zip 文件?