从互联网下载文件到S3存储桶

47
我希望能够直接从互联网上获取文件并将其放入S3存储桶中,然后将其复制到PIG集群中。由于文件的大小和我不太好的网络连接,先下载文件到我的电脑上,然后再上传到Amazon可能不是一个选择。
是否有任何方法可以通过抓取互联网上的文件并直接将其放入S3中?

下面的答案很好,但也可以参考这里获取更多的视角:https://dev59.com/cF4b5IYBdhLWcg3w-1-c?rq=1 - Kevin Glynn
4个回答

43

通过curl下载数据并将内容直接传输到S3。数据会直接流式传输到S3而不会在本地存储,避免任何内存问题。

curl "https://download-link-address/" | aws s3 cp - s3://aws-bucket/data-file

如上所建议,如果您的本地计算机下载速度过慢,请启动一个 EC2 实例,在其中运行ssh命令并执行上述命令。


如果文件是文本类型,使用以下命令:curl -s "url" |cat| aws s3 cp - "s3://..." - Uri Goren
1
如果您的文件大于50GB,请在末尾添加“--expected-size <size_in_bytes>”。从文档中可以看到:“如果在这些条件下不包括此参数,则可能由于上传部件过多而导致上传失败。” - Chrisjan
我们如何计算启动EC2实例并将文件发送+保存在S3上的估计成本?(以美元计算) - The Dan

21

对于像我这样的不太有经验的人,以下是通过EC2的更详细的过程描述:

  1. 在与目标S3存储桶相同的区域内启动Amazon EC2实例。最小可用(默认Amazon Linux)实例即可,但请确保为其提供足够的存储空间来保存您的文件。如果你需要超过~20MB/s的传输速度,则需要考虑选择具有更大管道的实例。

  2. 启动到新EC2实例的SSH连接,然后下载文件,例如使用wget。(例如,要通过FTP下载整个目录,可以使用wget -r ftp://name:passwd@ftp.com/somedir/。)

  3. 使用AWS CLI(请参阅Amazon文档),将文件上传到您的S3存储桶。例如,aws s3 cp myfolder s3://mybucket/myfolder --recursive (对于整个目录)。 (在此命令起作用之前,您需要向配置文件中添加您的S3安全凭据,如Amazon文档中所述。)

  4. 终止/销毁您的EC2实例。


你知道如何计算启动EC2实例并将文件发送+保存在S3上的估计成本吗?成本以美元计算。 - The Dan
@TheDan AWS计算器是一个很好的起点。我认为需要考虑的各个组件包括:EC2(按小时计费);如果需要,还有EBS(按小时计费);数据传输费用(下载/上传,按GB计费);S3上传/检索(按GB计费);S3存储(每月按GB计费)。其他一些解决方案(流式处理;Lambda)可能会降低您的成本。 - mpavey

15
[2017 edit] 我在2013年回答了原始问题。今天,我建议使用AWS Lambda来下载文件并将其放置在S3上。这是期望的效果-在没有服务器参与的情况下将对象放置在S3上。
[原始回答] 不能直接做到这一点。
为什么不使用EC2实例而不是本地PC?从同一地区的EC2到S3的上传速度非常快。
关于从/写入流到S3方面,我使用Python的smart_open

我想这是我必须要做的。我查看了文档,可能会选择Python和Boto。只需要弄清楚整个S3密钥的概念以及如何引用文件... - dreamwalker
1
这正是我所做的。结果使用boto和python上传文件非常容易。谢谢! - dreamwalker
你能否解释一下或者给出一个简短的代码示例,如何进行“流式传输”而不是真正地“下载”它。这是否类似于writeFileOutputBufferToS3()? - endertunc
不,我认为最后一句话是错误的。答案是它(直接下载到S3)不受支持。在这种情况下,EC2建议是好的,但您必须先下载然后上传文件(尽管您不一定需要创建本地文件)。 - Tom
我想要做这件事,但是我需要下载一个pip包来获取所需的文件,我该如何使用AWS Lambda来实现? - Acuervov

7

你可以使用Python将文件从互联网流式传输到AWS S3。

s3=boto3.resource('s3')
http=urllib3.PoolManager()

urllib.request.urlopen('<Internet_URL>')   #Provide URL
s3.meta.client.upload_fileobj(http.request('GET', 'Internet_URL>', preload_content=False), s3Bucket, key, 
    ExtraArgs={'ServerSideEncryption':'aws:kms','SSEKMSKeyId':'<alias_name>'})

这样做不会仍然将数据包下载到本地计算机,然后再上传吗?OP提到他的互联网连接不太好/快。 - Rajavanya Subramaniyan
将数据包下载到本地机器,然后上传到S3存储桶并不是一个好的选择。使用上述代码,数据将直接从互联网流式传输到S3存储桶。 - vinod_vh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接