【问题标题】:HTTP requests in wget taking most of the timewget 中的 HTTP 请求占用大部分时间
【发布时间】:2017-02-15 18:12:18
【问题描述】:

我正在通过 wget 检索大量数据,使用以下命令:

wget --save-cookies ~/.urs_cookies --load-cookies ~/.urs_cookies --keep-session-cookies --content-disposition -i links.dat

我的问题是 links.dat 包含数千个链接。这些文件相对较小(100kb)。所以下载文件需要 0.2 秒,等待 HTTP 请求响应需要 5 秒。所以最终下载我的全部数据需要 14 小时,大部分时间都花在等待请求上。

URL transformed to HTTPS due to an HSTS policy
--2017-02-15 18:01:37--  https://goldsmr4.gesdisc.eosdis.nasa.gov/daac-bin/OTF/HTTP_services.cgi?FILENAME=%2Fdata%2FMERRA2%2FM2I1NXASM.5.12.4%2F1980%2F01%2FMERRA2_100.inst1_2d_asm_Nx.19800102.nc4&FORMAT=bmM0Lw&BBOX=43%2C1.5%2C45%2C3.5&LABEL=MERRA2_100.inst1_2d_asm_Nx.19800102.SUB.nc4&FLAGS=&SHORTNAME=M2I1NXASM&SERVICE=SUBSET_MERRA2&LAYERS=&VERSION=1.02&VARIABLES=t10m%2Ct2m%2Cu50m%2Cv50m
Connecting to goldsmr4.gesdisc.eosdis.nasa.gov (goldsmr4.gesdisc.eosdis.nasa.gov)|198.118.197.95|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 50223 (49K) [application/octet-stream]
Saving to: ‘MERRA2_100.inst1_2d_asm_Nx.19800102.SUB.nc4.1’

这可能是一个非常菜鸟的问题,但以这种方式工作似乎真的适得其反。我对幕后发生的事情知之甚少,但我只是想确保我没有做错任何事情,并且这个过程确实可以更快。

如果详细信息有帮助,我正在下载特定节点的 MERRA-2 数据。

谢谢!

【问题讨论】:

    标签: linux bash shell ubuntu wget


    【解决方案1】:

    Wget 将对同一服务器的多个请求重用现有连接,从而可能为您节省建立和拆除套接字所需的时间。

    您可以通过在命令行上提供多个 URL 来做到这一点。例如,每批下载 100 个:

    #!/usr/bin/env bash
    
    wget_opts=(
     --save-cookies ~/.urs_cookies
     --load-cookies ~/.urs_cookies
     --keep-session-cookies
     --content-disposition
    )
    
    manyurls=()
    while read url; do
      manyurls+=( "$url" )
      if [ ${#manyurls[@]} -eq 100 ]; then
        wget "${wget_opts[@]}" "${manyurls[@]}"
        manyurls=()
      fi
    done < links.dat
    
    if [ ${#manyurls[@]} -gt 0 ]; then
      wget "${wget_opts[@]}" "${manyurls[@]}"
    fi
    

    请注意,我没有对此进行测试。它可能会起作用。如果没有,请告诉我您的错误,我会尝试调试。

    所以...这就是“连接重用”或“keepalive”。可以加快下载速度的另一件事是HTTP Pipelining,它基本上允许在收到第一个响应之前发送第二个请求。 wget 不支持这个,curl 在它的库中支持它,但不支持命令行工具。

    我没有现成的工具来建议支持 HTTP 管道。 (除此之外,工具建议是题外话。)您可以在this SO answer 中了解流水线的工作原理。如果您想用您选择的支持 libcurl 的语言编写一些东西,我相信您遇到的任何困难都会导致另一个有趣的 StackOverflow 问题。

    【讨论】:

    • 非常感谢,我试试这个。基本上,您提供的是一种在命令末尾放置 100 个 url 的方法?喜欢运行“wget --options url1 url2 url100”?
    • 是的,就是这样。我认为 100 是一个合理的数字——你可能不能把它们都放在那里,因为命令行太长了。 wget 和 curl 都将回收服务器保持打开状态的连接。如果这似乎是一个问题,您将毫不费力地找到有关 keepalive 标头的其他文档。要考虑的另一件事是您可以同时运行多个wgets。但是弄清楚如何后台处理或管理后台 shell 函数池超出了这个问题的范围。
    • 我确实认为使用流水线可以获得更好的性能,但您需要编写自己的软件来处理它。结合流水线和后台 wgets 或 curls 池,您将获得一切好处!当然,直到 nasa.gov 阻止您的 IP 以过度攻击那里的服务器。
    • 您好,再次感谢您的帮助。不幸的是,通过快速测试(仅在命令行末尾手动放置 3 个 URL),观察到节省了时间:下载完成之间仍然需要 5 秒,其中 10% 的时间专门用于下载本身。
    • 好的,所以如果我们假设每个 GET 将包含 来自服务器的这 5 秒延迟,那么您唯一的控制是通过流水线或同时运行多个请求。如果您不打算编写利用流水线的东西,请查看this answer,它可能会帮助您控制后台wget 进程的集合。
    猜你喜欢
    • 2011-11-01
    • 2014-07-05
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多