2012-12-22 62 views
5

我是一名具有相当不错的RDBMS体验的python开发人员。我需要处理大量的数据(大约500GB)。数据在s3桶中大约有1200个csv文件。我用Python编写了一个脚本,并可以在服务器上运行它。但是,它太慢了。根据目前的速度和数据量,大概需要50天时间才能完成所有文件(当然,在此之前的截止日期是好的)。并行处理大量数据

注:处理是那种东西你的基本ETL型 - 没有什么可怕的幻想。我可以很容易地将它压入PostgreSQL中的临时模式,然后将脚本运行到它。但是,从我的初始测试来看,这将会变慢。

注意:一个全新的PostgreSQL 9.1数据库将是它的最终目的地。

所以,我在想试图旋转了一堆EC2实例,试图成批运行它们(并行)。但是,我从来没有做过以前,所以我一直在四处寻找的想法是这样的,等

同样,我是一个Python开发,所以它看起来像布+博托可能是有前途的。我不时使用boto,但从来没有使用Fabric的经验。

我从阅读/研究中了解到,这对于Hadoop来说可能是一项很好的工作,但我不知道它并且无法承担这项工作,并且时间线不允许学习曲线或招聘有人。我也不应该这样,这是一次性交易。所以,我不需要构建一个非常优雅的解决方案。我只需要它的工作,并能够在今年年底前完成所有数据。

另外,我知道这不是一个简单的计算器,各种问题(像“我怎样才能扭转蟒蛇名单”)。但是,我期望的是有人阅读这篇文章,“说,我做了类似的事情,并使用XYZ ......太棒了!”

我想我问的是有没有人知道我可以用来完成此任务的任何东西(鉴于我是Python开发人员,并且我不知道Hadoop或Java - 并且拥有时间紧迫,防止我学习一门新技术,如Hadoop的或学习一门新语言)

感谢您的阅读。我期待着任何建议。

+0

布+博托的确看起来像这个任务的良好结合。也可以在每个实例上并行执行任务(除非您希望有1200个实例,每个文件一个实例),也许可以使用'multiprocessing'模块中的'Pool'。此外,解析文件和编辑结果的方式可能会对总时间产生很大影响。你看过“numpy”吗? – goncalopp

+1

所以没有人试图重复可能的建议 - 你能描述一下你在现有脚本中做了什么太慢 - 所以我们不知道该走下去吗:) –

+0

@JonClements - 看起来像一个公平的请求。基本上,我尝试了两种方法。我已经尝试将数据放入临时模式中,并将其编入索引(根据需要)并对其运行查询以“按摩”数据并将其转换为请求的格式。这太慢了,因为我认为索引比PostgreSQL缓存大得多。注意:我在Heroku上运行一个小的PostgreSQL实例。 (接下来的评论会继续) –

回答

2

我经常在这种类型的批处理工作中使用SQS/S3/EC2的组合。在SQS中为所有需要执行的工作排队(分块成合理的小块)。分配N个配置为从SQS读取消息,执行工作并将结果放入S3的EC2实例,然后,只有这样,才从SQS中删除消息。

你可以将这个比例调整到疯狂的水平,并且它对我一直非常好。在你的情况下,我不知道你是否会在S3中存储结果或者直接去PostgreSQL。

+0

出于好奇,您如何将您的脚本发送到EC2实例?你会让他们从一个git回购拉?或者只是scp脚本(s)结束? –

+0

我使用了许多技巧。你可以编写基于Paramiko的脚本来抓取文件。您可以使用cloud-init并从S3中获取脚本。你可以使用Fabric。你可以使用CloudFormation模板。有很多选择。 – garnaat

+0

感谢您的回复。是啊;看起来像很多选择。正如我在我原来的问题中提到的,我倾向于使用Fabric,但是想知道你在这里做了什么。 –

2

我做了这样的事情,前一段时间,我的设置是一样

  • 一个多实例(X-大或以上),即原始的源文件(XML/CSV)转换为中间格式。您可以并行运行(转换器)脚本的(核心数量)副本。由于我的目标是mongo,我使用json作为中间格式,在你的情况下它将是sql。

  • 此实例有N个卷附加到它。一旦卷变满,它将被分离并连接到第二个实例(通过boto)。

  • 第二个实例运行的DBMS服务器和其中进口准备(SQL)数据到分贝的脚本。我对postgres一无所知,但我想它确实有一个工具,如mysqlmongoimport。如果是,请使用它进行批量插入,而不是通过python脚本进行查询。

3

您是否做过一些性能测量:瓶颈在哪里?它是CPU绑定,IO绑定,数据库绑定?

当它被CPU绑定时,你可以尝试python JIT,如pypy。

当它是IO绑定,你需要更多的HD(并把他们的一些条纹MD)。

当它是数据库绑定时,您可以尝试先删除所有索引和键。

上周我将Openstreetmap DB导入到服务器上的postgres实例中。输入数据约为450G。预处理(这里用JAVA完成)只是创建了可以用postgres'copy'命令导入的原始数据文件。导入密钥和索引后生成。

导入所有原始数据需要大约一天的时间 - 然后花费数天时间来构建密钥和索引。

1

您可能会从Amazon Elastic Map Reduce形式的hadoop中受益。如果没有太深入的话,它可以被看作是在parralel(Map阶段)中应用一些逻辑来处理海量数据的一种方式。
还有一种名为hadoop streaming的hadoop技术 - 可以使用任何语言的脚本/可执行文件(如python)。
您可以发现有用的另一个hadoop技术是sqoop--它在HDFS和RDBMS之间移动数据。

+0

感谢您的回答。 DEEEEEP在我内部,我知道Hadoop和Elastic MapReduce在这里是正确的。但是,我无法将自己的头脑与自己想要完成的工作联系起来。我的部分问题是几乎我见过的每一个例子都是同样愚蠢的字数计算问题。我的确更多地是ETL(提取,转换,加载)问题。我很容易想象Map函数处理大多数变换。但是,转换是依赖于客户的。所以,这不是一个简单的计算(例如。(x * y)/ 2)。 –