【问题标题】:Automatically retrieving large files via public HTTP into Google Cloud Storage通过公共 HTTP 将大文件自动检索到 Google Cloud Storage
【发布时间】:2017-07-12 15:08:36
【问题描述】:

出于天气处理的目的,我希望在 Google Cloud Storage 中自动检索每日天气预报数据。

这些文件在公共 HTTP URL (http://dcpc-nwp.meteo.fr/openwis-user-portal/srv/en/main.home) 上可用,但它们非常大(在 30 到 300 兆字节之间)。文件大小是主要问题。

看了之前的stackoverflow话题,我尝试了两种不成功的方法:

1/ 在 Google App Engine 中通过 urlfetch 首次尝试

从 google.appengine.api 导入 urlfetch url = "http://dcpc-nwp.meteo.fr/service..." 结果 = urlfetch.fetch(url) [...] # 保存在 Google Cloud Storage 存储桶中的代码

但我在 urlfetch 行收到以下错误消息:

DeadlineExceededError: 等待来自 URL 的 HTTP 响应时超过了最后期限

2/ 通过 Cloud Storage Transfert 服务进行第二次尝试

根据文档,可以通过 Cloud Storage Transfert Service 直接将 HTTP 数据检索到 Cloud Storage 中: https://cloud.google.com/storage/transfer/reference/rest/v1/TransferSpec#httpdata

但它需要下载前文件的大小和 md5。此选项不适用于我的情况,因为该网站不提供这些信息。

3/ 有什么想法吗?

您是否看到任何解决方案可以通过 HTTP 将大文件自动检索到我的 Cloud Storage 存储桶中?

【问题讨论】:

    标签: python google-app-engine google-cloud-storage google-cloud-data-transfer


    【解决方案1】:

    3/ 使用 Compute Engine 实例的解决方法

    由于无法使用 App Engine 或直接使用 Cloud Storage 从外部 HTTP 检索大文件,因此我使用了始终运行的 Compute Engine 实例的解决方法。

    此实例会定期检查是否有新的天气文件可用,下载它们并将它们上传到 Cloud Storage 存储桶。

    出于可扩展性、维护和成本原因,我宁愿只使用无服务器服务,但希望:

    • 它在新的 f1-micro Compute Engine 实例上运行良好(无需额外的软件包,如果 24/7 运行,每月只需 4 美元)
    • 如果实例和存储桶位于同一区域,则从 Compute Engine 到 Google Cloud Storage 的网络流量是免费的(0 美元/月)

    【讨论】:

    • 我遇到了和 Matthieu 一样的问题。截至 2020 年 3 月,还有一个额外的无服务器解决方法:Google Cloud Functions (GCF)。 GCF 有 2GB 内存 - cloud.google.com/functions/quotas
    【解决方案2】:

    可以使用 curl -I 命令轻松快速地检索文件的 md5 和大小,如此链接 https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests 中所述。
    然后可以将 Storage Transfer Service 配置为使用该信息。

    另一种选择是使用无服务器云功能。它在 Python 中可能看起来像下面的东西。

    import requests
    
    def download_url_file(url):
        try:
            print('[ INFO ] Downloading {}'.format(url))
            req = requests.get(url)
            if req.status_code==200:
                # Download and save to /tmp
                output_filepath = '/tmp/{}'.format(url.split('/')[-1])
                output_filename = '{}'.format(url.split('/')[-1])
                open(output_filepath, 'wb').write(req.content)
                print('[ INFO ] Successfully downloaded to output_filepath: {} & output_filename: {}'.format(output_filepath, output_filename))
                return output_filename
            else:
                print('[ ERROR ] Status Code: {}'.format(req.status_code))
        except Exception as e:
            print('[ ERROR ] {}'.format(e))
        return output_filename
    

    【讨论】:

      【解决方案3】:

      目前谷歌的Transfer Service需要MD5和size;我们知道,在像您这样的情况下,这可能很难处理,但不幸的是,我们今天没有很好的解决方案。

      除非您能够通过自己(临时)下载文件来获得大小和 MD5,否则我认为这是您能做的最好的事情。

      【讨论】:

      • 感谢您提供的信息,这些信息促使我找到了 Compute Engine 实例的解决方法。
      猜你喜欢
      • 2015-08-28
      • 2015-09-09
      • 1970-01-01
      • 2014-11-14
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      • 2018-06-20
      • 2018-04-22
      相关资源
      最近更新 更多