将文件直接从S3移动到FTP



我有一个基于媒体的Web应用程序在AWS(EC2 Windows)上运行。而且,我正在尝试通过在自动扩展组上添加应用程序和Web服务器来实现可扩展性。

我的问题是我需要将媒体存储与S3分开,以便我可以与不同的应用服务器簇共享。但是我必须将这些媒体文件从S3移至不同的FTP服务器。为此,我必须将文件从S3下载到App Server,然后进行FTP上传,这需要太多的时间过程。请注意,我将ColdFusion用作应用程序服务器。

现在,我有2个解决此问题的选项

  1. 将S3实例安装到EC2实例(我知道这是不建议的,也不确定这是否有助于提高FTP上传的速度)。
  2. 使用LAMDA服务将文件直接从S3上传到FTP服务器

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

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

efs不是一个选项,因为我正在使用Windows Storage。

任何人都可以建议更好的解决方案吗?

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分钟。因此,在文件传输完成之前,可能会出现超时。我建议使用ECS Fargate代替Lambda。只要您需要,就可以保持运行过程。

如果S3文件不公开,请使用预先符号URL通过Urllib访问。

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

最新更新