【问题标题】:Memory efficient transfer of large file from S3 to Google Cloud Storage大文件从 S3 到 Google Cloud Storage 的内存高效传输
【发布时间】:2018-04-02 13:58:22
【问题描述】:

我在下面有一些工作代码可以将文件从 S3 传输到 Google Cloud Storage (GCS)。据我了解,这会将文件下载到内存中,然后再上传到 GCS。我想找到一种更有效的方法(在代码中)。我知道 Google 有传输服务和 CLI 选项,但这些选项不适合我的工作。

在我的应用程序中,下面的代码位于小方法中,但我以长程序形式发布了它,以便更轻松地一次性查看此处的步骤。

# AWS S3: Connect and get object
s3 = Aws::S3::Client.new(region: 'us-east-1', access_key_id: 'my_access_key', secret_access_key: 'my_secret')
response = s3.get_object(bucket:'my_s3_bucket', key:'my_object_key')

# Google Cloud Storage: Connect, Authorize and upload S3 object
client = Google::APIClient.new( :application_name => APP_NAME, :application_version => APP_VERSION )
key = Google::APIClient::KeyUtils.load_from_pkcs12(P12_KEY, 'notasecret')

client.authorization = Signet::OAuth2::Client.new(
  :token_credential_uri => 'token_credential_uri',
  :audience => 'audience',
  :scope => 'scope',
  :issuer => 'issuer',
  :signing_key => key)
client.authorization.fetch_access_token!

storage = client.discovered_api('storage', 'v1')

media = Google::APIClient::UploadIO.new(response['response'], 'text/csv', 'my_filename.txt')

resumable_result = client.execute(
  api_method: storage.objects.insert,
  media: media,
  parameters: {
    uploadType: 'resumable',
    bucket: 'my_gcs_bucket',
    name: filename.to_s
  },
  body_object: {contentType: 'text/csv'},
  connection: conn
)

我已经看到了将对象直接流式传输到磁盘上的文件的方法,从而避免将整个对象加载到内存中,但是我将如何使用 GCS 作为最终目标来做同样的事情呢?

【问题讨论】:

  • 啊,抱歉应该更清楚,我的意思是内存效率更高。例如,如果我有一个 3GB 的文件和有限的可用内存。
  • 你是如何解决这个问题的?
  • 嗨@Cemo,我不能 100% 记得,但我想我可能已经使用/编写了 Google Cloud Function (GCF) 从 S3 中提取文件,而不是通过中介红宝石应用程序。自从写了这个问题后,我一直在使用 Python 和 GCF 来解决我工作中的大部分问题;移动文件和数据。

标签: ruby-on-rails ruby amazon-s3 google-cloud-platform google-cloud-storage


【解决方案1】:

您可以使用gsutil(支持rsyncREST API 上创建转移(以防您坚持在同一句话中使用Ruby 和高效)。下载和重新上传可能需要很长时间,我认为直接传输是有效的。

猜测 Ruby 中的等价物是 APIClient/Request - 以便创建请求,否则该 Ruby API 客户端不明确支持这些请求。

gsutil rsync 可以镜像整个存储桶。总是双重和三重检查它的参数和它们的顺序,因为当镜像一个空目录/桶时,这可能会导致突然停电。建议首先尝试使用两个空桶,然后替换源和目标。

gsutil rsync -d -r s3://my-s3-bucket gs://my-gs-bucket

【讨论】:

  • 直接传输是我本质上所追求的
  • Rest API 文档要求提供 S3 密钥,因此我假设存储桶可以是私有的并且它仍然可以工作。
  • @Anthony 在已经为请求提供密钥时,这使 API 能够在服务器端进行身份验证;那不是问题(删除无用的评论)。
猜你喜欢
  • 1970-01-01
  • 2014-09-18
  • 2016-10-19
  • 2021-04-25
  • 1970-01-01
  • 2017-11-29
  • 2018-04-04
  • 2019-09-14
  • 2019-06-11
相关资源
最近更新 更多