从 Azure 表存储的千万条记录中查询一条记录
Posted
技术标签:
【中文标题】从 Azure 表存储的千万条记录中查询一条记录【英文标题】:Querying one record from tens of millions of records in Azure Table Storage 【发布时间】:2021-12-21 20:03:09 【问题描述】:我有一个典型的场景,其中消费者调用 Azure 函数 (EP1)(同步),然后根据 Azure 函数 API 的输入参数查询 Azure 表存储(有 500 万条记录)。 Azure 表存储具有以下列:
-
订单号(递增号)
IsConfirmed(值可以是 Y 或 N)
订单类型(最多可以有 6 种类型)
订购日期
订单详情
UUID
现在,当消费者查询时,它通常使用订单号进行搜索,并期望订单日期和订单详细信息以及订单号作为响应。
为此,我们选择了:
-
分区键:IsConfirmed + 订单类型
行键:UUID
现在对于 500 万条记录搜索,由于分区键类型的原因,搜索分区经常会遇到超过 300 万条记录(最大订单有 IsConfirmed 为 Y,订单类型为六种类型中的特定一种)和表查询时间超过 5 分钟。 结果,消费者通常会超时,因为消费者端配置的等待时间为 60 秒。
所以寻找有关如何有效地做到这一点的建议。
-
我们可以选择分区键作为订单号(但这会创建 500 万个分区)还是订单号+IsConfirmed+TypeofOrder 的组合?
我们的 Java 应用程序是一个写入量大的 Java 应用程序,而读取的次数要少得多。
+++++++++++++更新+++++++++++++++
正如 Gaurav 在回答中所建议的那样,将 orderid 作为分区键后,查询按预期工作。
现在这带来了下一个问题 - 我们确实有其他 API 查询,其中订单数据和类型仅用作输入搜索条件。
由于这与分区键不匹配,所以在第二类查询中,它基本上是进行全扫描,消费者再次超时。
那么应该如何设计来处理这些类型的查询.. Azure 文档说创建一个单独的表,其中订单类型 + 订单日期成为分区键。然而,这意味着每当我们写入表时,我们都必须在两个表上写入(一个以 orderid 作为部分键,另一个作为订单日期 + 类型作为部分键)。
【问题讨论】:
分区键作为“订单类型”和 RowKey 作为“订单号”怎么样 @user1672994 - 如果我们将分区键保留为“订单类型”,那么我们会看到大约 300 万条记录移动到单个分区中。 'Typeof order' 有六种类型 - 所以总共有 6 个分区 - 所以总体时间查询仍然很昂贵...... 【参考方案1】:我们可以选择分区键作为订单号吗(但这会创建 5 百万分区)或Order的组合 NUMber+IsConfirmed+TypeofOrder?
您当然可以选择分区键作为订单号,因为拥有大量分区并没有错。但是,请记住分区键值是字符串类型的。您可能想要做的是用一些字符(例如 0)填充您的订单号,以便您的所有订单的长度相同。
在这种情况下,我实际上建议您将行键保留为空。
您可能还需要考虑根据查询要求使用不同的分区键/行键组合存储相同数据的多个副本。例如,如果您要按订单日期查询,您可能希望以订单日期作为分区键来制作数据的另一个副本。
一般来说建议你做点查询(查询包括分区键和行键)。下一个最佳选择是按分区键查询(您希望将分区键中的数据保持较小,以免进行分区扫描)。所有其他选项都会导致完全不推荐的全表扫描。
您可能会发现此链接很有用:https://docs.microsoft.com/en-us/azure/storage/tables/table-storage-design-guidelines。
【讨论】:
由于我们的应用程序是一个写入量大的应用程序,如果我们将订单号作为分区键并将行键设置为空白,您是否预见到写入操作期间会出现任何性能问题? 只要你保持在吞吐量限制内(我相信 20000 个实体/秒),你应该没问题。不过我建议运行一些测试来确认。 Gaurav - 用额外的场景更新了我的 OP - 请提出建议 您能否针对您提出的新问题再发表一个问题?请链接此问题以设置新问题的上下文。以上是关于从 Azure 表存储的千万条记录中查询一条记录的主要内容,如果未能解决你的问题,请参考以下文章