使用boto改进SimpleDB查询性能

时间:2010-06-23 15:38:24

标签: python amazon-simpledb boto

我试图以下列方式使用SimpleDB。

我希望随时将48小时的数据保存到simpledb中并查询它以用于不同的目的。 每个域都有1小时的数据,所以在任何时候simpledb中都有48个域。 随着新数据不断上传,我删除了最旧的域,并为每个新的小时创建一个新域。

每个域的大小约为50MB,所有域的总大小约为2.2 GB。 域中的项具有以下类型的属性
标识符 - 大约50个字符长 - 每个项目1个 时间戳 - 时间戳值 - 每项1个 serial_n_data - 500-1000字节数据 - 每项200个

我正在使用python boto库来上传和查询数据。 我在域中发送大约200个属性的1项/秒。

对于这个数据的应用之一,我需要从所有48个域中获取所有数据。 对于所有域,查询看起来像“SELECT * FROM domain”。 我使用8个线程来查询数据,每个线程负责几个域 例如域1-6线程1
    域7-12线程2等等

获取整个数据需要将近13分钟。我正在使用boto的select方法。我需要比这更快的性能。有关加快查询过程的建议吗?有没有其他语言我可以用,这可以加快事情的发展?

3 个答案:

答案 0 :(得分:5)

使用更多线程

我建议将你的线程/域比率从1/6反转到接近30/1的值。从SimpleDB中提取大量数据所花费的大部分时间都将用于等待。在这种情况下,增加线程数将大大提高您的吞吐量。

SimpleDB的一个限制是查询响应大小上限为1MB。这意味着在单个域中下拉50MB将至少需要50个选择(原始+ 49个附加页面)。这些必须按顺序发生,因为下一个请求需要当前响应中的NextToken。如果每个选择需要2秒以上(对于大响应和高请求量而言并不罕见),您在每个域上花费2分钟。如果每个线程必须依次迭代6个域中的每个域,那就是大约12分钟。每个域一个线程应该可以轻松地将其减少到大约2分钟。

但你应该能做得更好。 SimpleDB针对并发性进行了优化。我会尝试每个域30个线程,给每个线程一小部分时间来查询,因为它毕竟是日志数据。例如:

SELECT * FROM domain WHERE timestamp between '12:00' and '12:02'

(显然,您使用的是实时时间戳值)所有30个查询都可以在不等待任何响应的情况下启动。通过这种方式,您仍然需要为每个域至少进行50次查询,但不是按顺序进行,而是可以获得更多的并发性。您必须自己测试有多少线程为您提供最佳吞吐量。我鼓励你尝试每个域60个,将选择条件降低到一分钟增量。如果它适合您,那么您将完全并行查询,并且很可能已经删除了所有后续页面。如果出现503 ServiceUnavailable错误,请缩小线程。

域是SimpleDB可扩展性的基本单元,因此您可以方便地对数据进行分区。您只需要利用并发性。如果你能够在13秒内获得在同一地区的EC2上运行的应用程序的数据,而不是13分钟,我不会感到惊讶。但实际花费的时间取决于许多其他因素。

成本问题

作为旁注,我应该提一下你正在做的事情的成本,即使你没有提出这个问题。 CreateDomain和DeleteDomain是重量级操作。通常我不建议经常使用它们。每次收取大约25秒的盒子使用费,因此每小时创建和删除一个盒子,每月只需70美元,仅用于域名管理。您可以在域中存储比您提到的50MB更多的数据。因此,您可能希望在删除之前让数据累积更多。如果您的查询包含时间戳(或者可以包含时间戳),则查询性能可能不会受到域中额外GB的旧数据的影响。在任何情况下,GetAttributes和PutAttributes都不会受到大域大小的性能影响,只有查询不能很好地利用选择性索引。你必须测试你的查询才能看到。这只是一个建议,我意识到创建/删除在概念上更清晰。

由于盒子使用公式中的怪癖,一次写入200个属性也很昂贵。写入的盒子使用量与提升到3的幂的属性数量成正比!小时的公式是:

0.0000219907 + 0.0000000002 N^3

对于基本费用加上每个属性费用,其中N是属性的数量。在您的情况下,如果您在一个请求中写入所有200个属性,则框使用费将为每百万个项目约250美元(如果您编写256个属性,则为每百万470美元)。如果您将每个请求分成4个请求,每个请求具有50个属性,则您的PutAttributes卷将翻两番,但会将盒使用费减少一个数量级,达到每百万个项目约28美元。如果你能够打破请求,那么它可能值得做。如果你不能(由于请求数量,或仅仅是应用程序的性质),这意味着从成本的角度来看,SimpleDB最终会变得非常缺乏吸引力。

答案 1 :(得分:0)

我和查理有同样的问题。在分析代码之后,我将性能问题缩小到SSL。看起来这就是花费大部分时间和CPU周期的地方。

我已经读过httplib库中的一个问题(boto用于SSL),除非数据包超过一定的大小,否则性能不会提高,尽管这是针对Python 2.5并且可能已经修复。

答案 2 :(得分:0)

SBBExplorer使用Multithreaded BatchPutAttributes在将批量数据上传到Amazon SimpleDB时实现高写入吞吐量。 SDB Explorer允许多个并行上传。如果您有带宽,则可以通过在并行队列中一次运行多个BatchPutAttributes进程来充分利用该带宽,从而减少处理时间。

http://www.sdbexplorer.com/