如何从Azure Table Storage FAST下载1亿行

时间:2010-07-12 19:59:51

标签: azure azure-storage azure-table-storage

我的任务是从Azure Table Storage下载大约1亿行数据。这里重要的是速度。

我们正在使用的流程是从Azure Table存储中下载10,000行。将它们处理为Sql Server的本地实例。处理行时,它会从Azure表中一次删除100行。这个过程是有线程的,有8个线程一次下载10,000行。

唯一的问题是根据我们的计算。下载和处理我们存储的大约1亿行需要大约40天。有谁知道更快的方法来完成这项任务?

一个附带问题:在下载过程中,Azure将发送回没有任何数据的xml。它不会发回错误。但它发送了这个:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="azure-url/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">CommandLogTable</title>
  <id>azure-url/CommandLogTable</id>
  <updated>2010-07-12T19:50:55Z</updated>
  <link rel="self" title="CommandLogTable" href="CommandLogTable" />
</feed>
0

是否有其他人遇到此问题并对其进行了修复?

6 个答案:

答案 0 :(得分:15)

Disabling Nagling的建议外,improving performance of Azure Table Storage还有一篇非常好的帖子。实际上提高ADO.NET反序列化的速度为Sqwarea(使用Lokad.Cloud框架构建的大型在线多人游戏)提供了10倍的加速

但是,表存储可能不是大型存储方案的最佳解决方案(超过数百万条记录)。 延迟是此处的杀戮因素。为了解决这个问题,我已成功使用基于文件的数据库存储,其中更改在本地完成(没有任何CLAP的网络延迟),并通过上传文件提交给BLOB(并发和扩展由{强制执行} {3}}适用于Windows Azure的App Engine。

一次向SQLite数据库插入1000万条记录(在事务中,每条记录被2个字段索引,并且通过ProtoBuf序列化的任意无模式数据)平均只需要200秒。上传/下载生成的文件 - 平均大约15秒。按索引随机读取 - 即时(如果文件缓存在本地存储中且ETag匹配)。

答案 1 :(得分:7)

关于你的问题,我希望你得到一个“延续令牌”。如果您正在使用.NET存储客户端库,请尝试在查询中添加.AsTableServiceQuery()。

关于你的主要问题,散布查询是你能做的最好的事情。听起来您正在从本地计算机(而不是在Windows Azure中)访问存储。如果是这样,我想你可以通过向Windows Azure部署一个小型服务来加快速度,从而从表存储中获取数据(速度更快,因为数据中心内的带宽更高,延迟更低),然后压缩结果并将它们发送回本地计算机。 XML Windows Azure表发送回来有很多开销,因此剥离并捆绑行可能会节省大量的传输时间。

答案 2 :(得分:1)

除了有关带宽限制的建议之外,您可能很容易遇到存储帐户限制,因为每个表分区限制为每秒大约500个事务。

此外:部署的优化(Nagle算法)实际上可以减慢小读取(例如1K数据读取)的速度。这是一个blog post about disabling Nagling,它可能会大大加快您的读取速度,特别是如果您直接在Azure服务中运行而没有网络延迟。

答案 3 :(得分:1)

获得数据的最快方式是由亚马逊支持但尚未支持Azure,是为了向他们提供USB磁盘(甚至是USB记忆棒),让他们将数据放入磁盘并将其发回给您。

另一种选择是使用AppFabric Service Bus在创建数据时将数据输出到另一个系统,而不是等待一次全部下载。

答案 4 :(得分:0)

最有可能的是,您的限制因素是网络带宽,而不是处理。如果是这种情况,你唯一真正的希望是扩展:更多机器运行更多线程来下载数据。

BTW,Azure是否公开了一些“导出”机制,不再需要手动下载所有行?

答案 5 :(得分:0)

这里的重要因素是数据如何跨分区传播。跨越分区边界的查询将在每个需要重新提交的边界处返回 - 即使所讨论的分区有0行。如果数据是1 Partition = 1 Row,那么它会很慢,但你可以将线程数增加到8以上。如果数据在n个分区= m行,那么下面的想法应该加快你的速度。

假设您有多个分区且每个分区都有一些行,最快的方法是尽可能多地启动线程(如果您使用.Net PLINQ或Parallel.ForEach(分区)或QueueWorkItem) ())并有一个线程扫描其分区的所有行,进程,发布到SQL,&amp;在返回之前删除。

考虑到所涉及的延迟(10秒)和多次往返,即使是8个线程,您可能也没有想象的那么忙。此外,您没有提到您正在使用的VM,但您可能想要分析不同的大小。

或者,另一种方法是利用队列和一些'n'工人。对于每个分区(或一组分区),将消息放入队列中。让工作人员从队列中拉出(多线程)和查询/处理/发布/重复。您可以根据需要启动尽可能多的工作人员,并将其分布到更多的数据中心(即更多的吞吐量等)。