将文件直接从S3移到FTP

时间:2019-02-13 07:07:42

标签: amazon-web-services amazon-s3 amazon-ec2 coldfusion scalability

我有一个基于媒体的Web应用程序在AWS(EC2窗口)上运行。我正在尝试通过在自动缩放组中添加应用程序和Web服务器来实现可伸缩性。

我的问题是我需要将媒体存储区分离到S3,以便可以与不同的应用程序服务器群集共享。但是我必须将这些媒体文件从S3移到其他FTP服务器。为此,我必须将文件从S3下载到应用服务器,然后进行FTP上传,这会花费很多时间。请注意,我正在使用ColdFusion作为应用程序服务器。

现在我有2个解决方案

  1. 将S3实例安装到EC2实例(我不建议这样做,也不确定是否会帮助提高FTP上传速度)。
  2. 使用Lamda service将文件直接从S3上传到FTP服务器

我不能对每个EC2实例使用单独的EBS卷,因为

  1. 存储量巨大,将导致高成本
  2. 我需要在附加到EC2实例的不同EBS卷上同步媒体存储

由于我正在使用Windows存储,因此不能选择EFS。

有人可以提出更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

使用python很简单

from ftplib import FTP
from socket import _GLOBAL_DEFAULT_TIMEOUT
import urllib.request

class FtpCopier(FTP):

    source_address = None
    timeout = _GLOBAL_DEFAULT_TIMEOUT

    # host → ftp host name / ip
    # user → ftp login user
    # password → ftp password
    # port → ftp port
    # encoding → ftp servver encoding
    def __init__(self, host, user, password, port = 21, encoding = 'utf-8'):

        self.host = host
        self.user = user
        self.password = password
        self.port = port
        self.connect(self.host, self.port)
        self.login(self.user, self.password, '')
        self.encoding = encoding

    # url → any web URL (for example S3)
    # to_path → ftp server full path (check if ftp destination folders exists)
    # chunk_size_mb → data read chunck size
    def transfer(self, url, to_path, chunk_size_mb = 10):

        chunk_size_mb = chunk_size_mb * 1048576 # 1024*1024
        file_handle = urllib.request.urlopen(url)
        self.storbinary("STOR %s" % to_path, file_handle, chunk_size_mb)

使用示例:

ftp = FtpCopier("some_host.com", "user", "p@ssw0rd")
ftp.transfer("https://bucket.s3.ap-northeast-2.amazonaws.com/path/file.jpg", "/path/new_file.jpg")

但是请记住,lambda处理时间仅限于15 minutes。因此,超时可能在文件传输完成之前出现。我建议使用ECS Fargate而不是lambda。这样可以根据需要保留运行过程。

如果S3文件不是公共文件,请使用presigned URLs通过urllib访问它。

aws s3 presign s3://bucket/path/file.jpg --expires-in 604800