从 Azure Table 存储中检索 1+ 百万条记录
Retrieve 1+ million records from Azure Table Storage
我的 table 存储大约有 1-2 百万条记录,我的日常工作需要检索所有没有 属性 A 的记录并做一些进一步处理。
预计大约有 1 - 150 万条记录没有 属性 A。我知道有两种方法。
- 查询所有记录然后过滤
后的结果
- 进行 table 扫描
目前使用的是我们在c#中查询所有记录和过滤的方式。但是,该任务在 Azure Function App 中是 运行。检索所有结果的查询有时需要超过 10 分钟,这是 Azure Functions 的限制。
我想了解为什么检索 100 万条记录需要这么长时间以及如何优化查询。 table 的现有设计是分区和行键相同并且是一个 guid - 这让我相信每个分区都有一个实体。
查看 Microsoft 文档,这里有一些关键 Table 存储限制 (https://docs.microsoft.com/en-us/azure/storage/common/storage-scalability-targets#azure-table-storage-scale-targets):
- 每个存储帐户的最大请求率:每秒 20,000 个事务,假设实体大小为 1-KiB
- 单个 table 分区的目标吞吐量(1 KiB 实体):每秒最多 2,000 个实体。
我最初的猜测是,我应该使用另一个分区键对每个分区 2,000 个实体进行分组,以实现每个分区每秒 2,000 个实体的目标吞吐量。这是否意味着理论上可以在 1 秒内返回 2,000,000 条记录?
感谢任何想法或建议。
我看到两种在批处理过程中检索 1+ 条记录的方法,其中结果必须保存到单个媒体 - 如文件。
第一)你identity/select所有主要id/key相关数据。然后,您使用这些主要 id/key 的块生成并行作业,您可以在其中读取实际数据并进行处理。然后每个作业将结果报告给单一媒体。
其次)你identity/select(更新)相关数据的前n个,并将此数据标记为正在处理状态。在这里使用并发锁定,如果这是并行完成的,那应该可以防止其他人获取该数据。
如果可能的话,我会选择第一个解决方案,因为它是最简单、最干净的解决方案。如果您使用 "select for update",则第二种解决方案最好,我不知道 Azure Table 存储是否支持它。
您需要完成任务。由于您不知道分区键,运行 24 个单独的查询 PK 以字母表的每个字母开始和结束。编写一个查询,其中 PK > A && PK < B, and > B < C 等。然后在内存中加入 24 个结果。超级容易在一个功能中完成。在 JS 中只需使用 Promise.all([]).
我在写关于这个主题的博客后发现了这个问题。我有一个项目,我正在使用 Azure Functions Consumption 计划并且有一个很大的 Azure 存储 Table(350 万条记录)。
这是我的博客 post:
https://www.joelverhagen.com/blog/2020/12/distributed-scan-of-azure-tables
我在这个博客中提到了几个选项 post 但我认为最快的方法是将“table 扫描”工作分配到更小的工作项目中,这些项目可以在 10-分钟限制。如果您想尝试一下,我在博客 post 中链接了一个实现。它可能需要一些时间来适应您的 Azure 函数,但大部分聪明的部分(查找分区键范围)都已实现和测试。
这看起来基本上就是 user3603467 所建议的 。
我的 table 存储大约有 1-2 百万条记录,我的日常工作需要检索所有没有 属性 A 的记录并做一些进一步处理。
预计大约有 1 - 150 万条记录没有 属性 A。我知道有两种方法。
- 查询所有记录然后过滤 后的结果
- 进行 table 扫描
目前使用的是我们在c#中查询所有记录和过滤的方式。但是,该任务在 Azure Function App 中是 运行。检索所有结果的查询有时需要超过 10 分钟,这是 Azure Functions 的限制。
我想了解为什么检索 100 万条记录需要这么长时间以及如何优化查询。 table 的现有设计是分区和行键相同并且是一个 guid - 这让我相信每个分区都有一个实体。
查看 Microsoft 文档,这里有一些关键 Table 存储限制 (https://docs.microsoft.com/en-us/azure/storage/common/storage-scalability-targets#azure-table-storage-scale-targets):
- 每个存储帐户的最大请求率:每秒 20,000 个事务,假设实体大小为 1-KiB
- 单个 table 分区的目标吞吐量(1 KiB 实体):每秒最多 2,000 个实体。
我最初的猜测是,我应该使用另一个分区键对每个分区 2,000 个实体进行分组,以实现每个分区每秒 2,000 个实体的目标吞吐量。这是否意味着理论上可以在 1 秒内返回 2,000,000 条记录?
感谢任何想法或建议。
我看到两种在批处理过程中检索 1+ 条记录的方法,其中结果必须保存到单个媒体 - 如文件。
第一)你identity/select所有主要id/key相关数据。然后,您使用这些主要 id/key 的块生成并行作业,您可以在其中读取实际数据并进行处理。然后每个作业将结果报告给单一媒体。
其次)你identity/select(更新)相关数据的前n个,并将此数据标记为正在处理状态。在这里使用并发锁定,如果这是并行完成的,那应该可以防止其他人获取该数据。
如果可能的话,我会选择第一个解决方案,因为它是最简单、最干净的解决方案。如果您使用 "select for update",则第二种解决方案最好,我不知道 Azure Table 存储是否支持它。
您需要完成任务。由于您不知道分区键,运行 24 个单独的查询 PK 以字母表的每个字母开始和结束。编写一个查询,其中 PK > A && PK < B, and > B < C 等。然后在内存中加入 24 个结果。超级容易在一个功能中完成。在 JS 中只需使用 Promise.all([]).
我在写关于这个主题的博客后发现了这个问题。我有一个项目,我正在使用 Azure Functions Consumption 计划并且有一个很大的 Azure 存储 Table(350 万条记录)。
这是我的博客 post: https://www.joelverhagen.com/blog/2020/12/distributed-scan-of-azure-tables
我在这个博客中提到了几个选项 post 但我认为最快的方法是将“table 扫描”工作分配到更小的工作项目中,这些项目可以在 10-分钟限制。如果您想尝试一下,我在博客 post 中链接了一个实现。它可能需要一些时间来适应您的 Azure 函数,但大部分聪明的部分(查找分区键范围)都已实现和测试。
这看起来基本上就是 user3603467 所建议的