我一直在寻找一种工具来帮助我将S3存储桶的内容复制到第二个存储桶中,而无需先将内容先下载到本地系统。
我尝试过AWS S3控制台复制选项,但导致一些嵌套文件丢失。
我曾尝试使用传输应用(恐慌),但复制命令首先将文件复制到本地系统,然后再复制到第二个存储桶
答案 0 :(得分:159)
AWS(刚刚最近)发布了一个用于在存储桶之间进行复制的命令行界面。
$ aws s3 sync s3://mybucket-src s3://mybucket-target --exclude *.tmp
..
此将从一个目标存储桶复制到另一个存储桶。
请参阅此处的文档:S3 CLI Documentation
答案 1 :(得分:40)
使用aws-sdk gem的简化示例:
AWS.config(:access_key_id => '...', :secret_access_key => '...')
s3 = AWS::S3.new
s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key')
如果要在不同存储桶之间执行复制,请指定目标存储桶名称:
s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key', :bucket_name => 'target-bucket')
答案 2 :(得分:37)
您现在可以从S3管理界面执行此操作。只需进入一个存储桶,选择所有文件夹actions->copy
即可。然后进入新的存储桶actions->paste
。
答案 3 :(得分:7)
有可能使用最近的 aws-sdk gem,请参阅代码示例:
require 'aws-sdk'
AWS.config(
:access_key_id => '***',
:secret_access_key => '***',
:max_retries => 10
)
file = 'test_file.rb'
bucket_0 = {:name => 'bucket_from', :endpoint => 's3-eu-west-1.amazonaws.com'}
bucket_1 = {:name => 'bucket_to', :endpoint => 's3.amazonaws.com'}
s3_interface_from = AWS::S3.new(:s3_endpoint => bucket_0[:endpoint])
bucket_from = s3_interface_from.buckets[bucket_0[:name]]
bucket_from.objects[file].write(open(file))
s3_interface_to = AWS::S3.new(:s3_endpoint => bucket_1[:endpoint])
bucket_to = s3_interface_to.buckets[bucket_1[:name]]
bucket_to.objects[file].copy_from(file, {:bucket => bucket_from})
答案 4 :(得分:7)
$ aws s3 cp s3://src_bucket/file s3://dst_bucket/file --source-region eu-west-1 --region ap-northeast-1
上述命令将文件从欧洲(eu-west-1)的一个桶复制到日本(ap-northeast-1)。您可以使用以下命令获取存储桶区域的代码名称:
$ aws s3api get-bucket-location --bucket my_bucket
顺便说一句,在S3 Web控制台中使用复制和粘贴很容易,但它似乎从源存储桶下载到浏览器中,然后上传到目标存储桶。使用" aws s3"对我来说要快得多。
答案 5 :(得分:6)
我创建了一个Docker executable s3s3mirror工具。 用于从AWS S3存储桶复制和镜像到另一个存储库的实用程序。
它是线程允许并行COPY和非常高效的内存,它在s3cmd完全失败的情况下成功。
用法:
docker run -e AWS_ACCESS_KEY_ID=FOO -e AWS_SECRET_ACCESS_KEY=BAR pmoust/s3s3mirror [OPTIONS] source_bucket[/prefix] dest_bucket[/prefix]
有关选项的完整列表,请尝试:
docker run pmoust/s3s3mirror
答案 6 :(得分:5)
我想你现在可能已经找到了一个很好的解决方案,但对于遇到这个问题的其他人(就像我刚才那样),我专门为了镜像一个S3存储桶而制作了一个简单的实用工具。另一个以高度并发,但CPU和内存有效的方式。
这是在Apache许可下的github上:https://github.com/cobbzilla/s3s3mirror
如果你有一个非常大的水桶并且正在寻找最佳性能,那么可能值得尝试。
如果您决定尝试一下,请告诉我您是否有任何反馈。
答案 7 :(得分:5)
查看以下文档。我想这就是你要找的东西。 http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectCOPY.html
RightAws gem的S3Interface具有复制功能,可以完成上述操作。
http://rubydoc.info/gems/right_aws/3.0.0/RightAws/S3Interface#copy-instance_method
答案 8 :(得分:4)
如果您在shell中并且想要复制多个文件但不是所有文件: s3cmd cp --recursive s3:// BUCKET1 / OBJECT1 s3:// BUCKET2 [/ OBJECT2]
答案 9 :(得分:3)
我编写了一个备份S3存储桶的脚本:https://github.com/roseperrone/aws-backup-rake-task
#!/usr/bin/env python
from boto.s3.connection import S3Connection
import re
import datetime
import sys
import time
def main():
s3_ID = sys.argv[1]
s3_key = sys.argv[2]
src_bucket_name = sys.argv[3]
num_backup_buckets = sys.argv[4]
connection = S3Connection(s3_ID, s3_key)
delete_oldest_backup_buckets(connection, num_backup_buckets)
backup(connection, src_bucket_name)
def delete_oldest_backup_buckets(connection, num_backup_buckets):
"""Deletes the oldest backup buckets such that only the newest NUM_BACKUP_BUCKETS - 1 buckets remain."""
buckets = connection.get_all_buckets() # returns a list of bucket objects
num_buckets = len(buckets)
backup_bucket_names = []
for bucket in buckets:
if (re.search('backup-' + r'\d{4}-\d{2}-\d{2}' , bucket.name)):
backup_bucket_names.append(bucket.name)
backup_bucket_names.sort(key=lambda x: datetime.datetime.strptime(x[len('backup-'):17], '%Y-%m-%d').date())
# The buckets are sorted latest to earliest, so we want to keep the last NUM_BACKUP_BUCKETS - 1
delete = len(backup_bucket_names) - (int(num_backup_buckets) - 1)
if delete <= 0:
return
for i in range(0, delete):
print 'Deleting the backup bucket, ' + backup_bucket_names[i]
connection.delete_bucket(backup_bucket_names[i])
def backup(connection, src_bucket_name):
now = datetime.datetime.now()
# the month and day must be zero-filled
new_backup_bucket_name = 'backup-' + str('%02d' % now.year) + '-' + str('%02d' % now.month) + '-' + str(now.day);
print "Creating new bucket " + new_backup_bucket_name
new_backup_bucket = connection.create_bucket(new_backup_bucket_name)
copy_bucket(src_bucket_name, new_backup_bucket_name, connection)
def copy_bucket(src_bucket_name, dst_bucket_name, connection, maximum_keys = 100):
src_bucket = connection.get_bucket(src_bucket_name);
dst_bucket = connection.get_bucket(dst_bucket_name);
result_marker = ''
while True:
keys = src_bucket.get_all_keys(max_keys = maximum_keys, marker = result_marker)
for k in keys:
print 'Copying ' + k.key + ' from ' + src_bucket_name + ' to ' + dst_bucket_name
t0 = time.clock()
dst_bucket.copy_key(k.key, src_bucket_name, k.key)
print time.clock() - t0, ' seconds'
if len(keys) < maximum_keys:
print 'Done backing up.'
break
result_marker = keys[maximum_keys - 1].key
if __name__ =='__main__':main()
我在rake任务中使用它(对于Rails应用程序):
desc "Back up a file onto S3"
task :backup do
S3ID = "AKIAJM3NRWC7STXWUWVQ"
S3KEY = "0A5kuzV+E1dkaPjZxHQAezz1GlSddJd0iS5sNpry"
SRCBUCKET = "primary-mzgd"
NUM_BACKUP_BUCKETS = 2
Dir.chdir("#{Rails.root}/lib/tasks")
system "./do_backup.py #{S3ID} #{S3KEY} #{SRCBUCKET} #{NUM_BACKUP_BUCKETS}"
end
答案 10 :(得分:1)
我被告知您也可以在EMR集群上使用s3distcp执行此操作。对于包含大文件的数据,它应该更快。它在小型数据集上运行良好 - 但我会更喜欢另一种解决方案,因为它为这么少的数据设置了学习曲线(我之前从未使用过EMR)。
以下是AWS文档的链接:http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html
更新:对于相同的数据集,s3s3mirror比s3distcp或AWS cli快得多。设置起来也容易得多。
答案 11 :(得分:1)
您可以从AWS cli https://aws.amazon.com/cli/中进行
LOCATE(var1,search) and LOCATE(var2,search) return 1 ?
-这将列出所有S3存储桶
SELECT var1=var2 return 1 ?
-这会将文件从一个存储桶复制到另一个存储桶
注意*在创建跨区域复制存储桶时非常有用,通过执行上述操作,将跟踪所有文件,并且对源区域文件的更新将传播到复制的存储桶。除了文件删除以外的所有内容都已同步。
对于CRR,请确保在存储桶上启用了版本控制。
答案 12 :(得分:1)
如果您使用的是javascript:p
,我会听到有一个节点模块来自 knox-copy 文档:
knoxCopy = require 'knox-copy'
client = knoxCopy.createClient
key: '<api-key-here>'
secret: '<secret-here>'
bucket: 'backups'
client.copyBucket
fromBucket: 'uploads'
fromPrefix: '/nom-nom'
toPrefix: "/upload_backups/#{new Date().toISOString()}"
(err, count) ->
console.log "Copied #{count} files"
答案 13 :(得分:0)
要从一个S3存储桶复制到相同或另一个S3存储桶而不下载到本地,它非常简单。使用以下shell命令。
hdfs dfs -cp -f "s3://AccessKey:SecurityKey@ExternalBucket/SourceFoldername/*.*" "s3://AccessKey:SecurityKey@ExternalBucket/TargetFoldername"
这会将源存储区SourceFoldername
文件夹中的所有文件复制到目标存储区的TargetFoldername
文件夹中。在上面的代码中,请将AccessKey
,SecurityKey
和ExternalBucket
替换为相应的值。
答案 14 :(得分:0)
aws s3 sync
cli命令如何。
aws s3同步s3:// bucket1 / s3:// bucket2 /
答案 15 :(得分:0)
正如Neel Bhaat在此blog中所解释的,有许多不同的工具可用于此目的。 AWS提供了一些工具,其中大多数是第三方工具。所有这些工具都要求您在工具本身中保存您的AWS账户密钥和机密。使用第三方工具时要格外小心,因为保存的凭据可能会导致您的财产,全部资产损失甚至死亡。
因此,我始终建议为此目的使用AWS CLI。您只需从this link安装即可。接下来,运行以下命令,并将密钥和秘密值保存在AWS CLI中。
aws configure
并使用以下命令将您的AWS S3存储桶同步到本地计算机。 (本地计算机应已安装AWS CLI)
aws s3 sync <source> <destination>
示例:
1)从AWS S3到本地存储
aws s3 sync <S3Uri> <LocalPath>
2)从本地存储到AWS S3
aws s3 sync <LocalPath> <S3Uri>
3)从AWS s3存储桶到另一个存储桶
aws s3 sync <S3Uri> <S3Uri>
答案 16 :(得分:0)
复制S3存储桶的最佳方法是使用 AWS CLI 。
涉及以下三个步骤:
**https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html**
如果要在两个AWS账户之间复制存储桶,则需要在每个存储桶中附加正确的策略。
此后,使用此命令从一个存储桶复制到另一个存储桶。
aws s3 sync s3://sourcebucket s3://destinationbucket
第2步和第3步的详细信息在此链接中给出:
https://aws.amazon.com/premiumsupport/knowledge-center/account-transfer-s3/
答案 17 :(得分:0)
您可以编写一个Java应用程序-甚至是使用AWS Java API复制对象的GUI SWING应用程序,请参见-
答案 18 :(得分:0)
添加Copying objects across AWS accounts using S3 Batch Operations,因为此处尚未提及。这是我目前正在尝试的方法,因为我有大约100万个对象需要转移到新帐户,并且由于某些令牌到期,cp和sync对我不起作用,并且我没有弄清楚它是什么令牌的方法,因为我的通用访问令牌工作正常。
答案 19 :(得分:0)
从2020年开始,如果您使用 s3cmd ,则可以使用以下命令将文件夹从bucket1复制到bucket2
s3cmd cp --recursive s3://bucket1/folder_name/ s3://bucket2/folder_name/
--recursive
是递归复制文件夹中所有内容的必要条件,还请注意,您必须在文件夹名称后指定“ /”,否则将失败。