内存高效地将大型文件从S3传输到Google云端存储

时间:2018-04-02 13:58:22

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

我在下面有一些工作代码将文件从S3传输到Google云端存储(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作为最终目标呢?

1 个答案:

答案 0 :(得分:3)

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

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

虽然gsutil rsync可以镜像整个存储桶。总是双倍和三倍检查它的参数及其顺序,因为在镜像空目录/桶时,这可能导致突然停电。建议首先尝试两个空桶,然后替换源和放大器。目的地。

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