我必须每周执行两次任务。任务包括从公共ftp服务器获取1.4GB的csv文件。然后我必须处理它(应用一些过滤器,丢弃一些行,进行一些计算),然后将它同步到AWS RDS上托管的Postgres数据库。对于每一行,我必须检索数据库上的SKU条目,并确定它是否需要更新。
我的问题是EC2是否可以作为我的解决方案。我主要担心的是内存..我已经搜索了一些解决方案https://github.com/goodby/csv,它通过逐行取出而不是将它全部拉到内存来处理这个问题,但是如果我尝试直接读取.csv它们就不起作用来自FTP。
任何人都可以提供一些见解吗? AWS EC2是解决此问题的好平台吗?你会如何处理csv大小和内存限制的问题?
答案 0 :(得分:2)
您无法直接从FTP流式传输文件,而是要复制整个文件并将其存储在本地。使用curl或ftp命令可能是最有效的方法。
一旦你这样做,你将需要编写某种程序,如果你可以并行化工作,它将一次读取一行或几行。有ETL工具可以使这很容易。使用PHP可以工作,但它不是这类工作的非常有效的选择,并且你的并行化选项是有限的。
答案 1 :(得分:2)
当然,您可以在EC2实例上执行此操作(您可以执行几乎任何可以在EC2中提供代码的操作),但如果您只需要每周运行两次任务,则EC2实例将处于空闲状态,在剩下的时间里吃钱,除非你为每次任务运行手动停止并启动它。
此处scheduled AWS Lambda function可能更具成本效益且更合适。您的代码选项略受限制,但您可以为Lambda函数提供与访问RDS相同的IAM权限,并且只有在计划或调用时才会运行。
答案 2 :(得分:1)
FTP协议没有"流媒体"。您无法通过块读取Ftp块中的文件。
老实说,下载文件并触发运行更大的实例并不是什么大问题,如果你每周只运行两次,你只需选择r3.large(它的成本低于0.20 /小时),尽快执行并停止它。内部SSD磁盘空间应该为您提供与EBS最佳的I / O比较。
只需确保您的操作系统和代码部署在EBS中以供将来重用(除非您具有自动代码部署机制)。并且您必须确保RDS将处理突发I / O,否则它将成为瓶颈。
更好的是,使用r3.large实例,您可以将CSV文件拆分为较小的块,并行加载它们,然后在所有内容完成后关闭实例。您只需要在之后支付最小根EBS存储成本。
如果进程很长,我不建议使用lambda,因为lambda只是短时间和快速处理的意思(它将在300秒后终止)。
(更新): 如果打开一个文件,解析它的简单方法是按顺序读取它,它可能无法完全使用整个CPU。您可以拆分CSV文件,并按照 CPULIMIT进行参考。
然后使用相同的脚本,您可以通过向后台进程发送一些来同时调用它们,下面的示例显示在Linux下将python进程放在后台。
parse_csvfile.py csv1 &
parse_csvfile.py csv2 &
parse_csvfile.py csv3 &
所以改为单文件顺序I / O,它将使用多个文件。此外,拆分文件应该是SSD下的快照。
答案 3 :(得分:0)
所以我让它像这样工作。
我使用了Python和两个很棒的库。首先,我创建了一个Python代码,用于从FTP请求和下载csv文件,以便将其加载到内存中。第一个包是Pandas,它是分析大量数据的工具。它包括从csv轻松读取文件的方法。我使用了包含的功能进行过滤和排序。我通过字段过滤了大型csv并创建了大约25个新的较小的csv文件,这使我能够处理内存问题。我也使用了Eloquent这是一个受Laravel ORM启发的图书馆。此库允许您使用AWS公共DNS,数据库名称,用户名和密码创建连接,并使用简单方法进行查询,而无需编写单个Postgres查询。最后我创建了一个T2微型AWS实例,安装了Pandas和Eloquent更新了我的代码,就是这样。