从 Azure Table 存储中的数千万条记录中查询一条记录
Querying one record from tens of millions of records in Azure Table Storage
我有一个典型的场景,其中消费者调用 Azure Function (EP1)(同步),然后根据 Azure Function 的输入参数查询 Azure Table 存储(有 500 万条记录) API。
Azure Table 存储有以下列:
- 订单号(递增)
- IsConfirmed(可以有值 Y 或 N)
- 订单类型(最多可以有 6 种)
- 订购日期
- 订单详情
- UUID
现在,当消费者查询时,它通常使用订单号进行搜索,并期望在响应中提供订单日期和订单详细信息以及订单号。
为此,我们选择了:
- 分区键:IsConfirmed + 订单类型
- 行键:UUID
现在500万条记录搜索,由于分区键类型,搜索分区往往会遇到超过300万条记录(最大订单IsConfirmed为Y,订单类型为六种类型中的特定一种)和Table 查询需要超过 5 分钟。
因此,消费者通常会超时,因为消费者端配置的等待时间为 60 秒。
所以正在寻找有关如何有效执行此操作的建议。
- 我们可以选择分区键作为 Order Number(但这将创建 500 万个分区)还是 Order NUmber+IsConfirmed+TypeofOrder 的组合?
- 我们的 Java 应用程序需要大量写入,读取次数要少得多。
+++++++++++更新++++++++++++++
正如 Gaurav 在回答中所建议的那样,将 orderid 作为分区键后,查询按预期工作。
现在带来下一个问题 - 我们确实有其他 API 查询,其中订单数据和类型仅用作输入搜索条件。
由于这与分区键不匹配,因此在第二种类型的查询中,它基本上进行了一次整体扫描,并且消费者再次超时。
那么应该设计什么来处理这些类型的查询。Azure 文档说创建一个单独的 table,其中订单类型 + 订单日期成为分区键。然而,这意味着每当我们写入 table 时,我们都必须在两个 table 上写入(一个以 orderid 作为部分键,另一个作为订单日期 + 类型作为部分键)。
Can we choose partition key as Order Number (but that will create 5
million partitions) or a combination of Order
NUmber+IsConfirmed+TypeofOrder?
你当然可以选择partition key作为order number,partition数量多也没什么不好。但是,请记住分区键值是字符串类型。你可能想要做的是用一些字符(比如 0)填充你的订单号,这样你所有的订单都具有相同的长度。
在这种情况下,我实际上建议您将行键保留为空。
根据您的查询要求,您可能还想考虑使用不同分区 key/row 键组合存储相同数据的多个副本。例如,如果您要按订单日期查询,您可能希望制作另一个以订单日期作为分区键的数据副本。
一般来说建议做点查询(同时查询partition key和row key)。下一个最佳选择是按分区键查询(您希望将分区键中的数据保持较小,这样您就不会进行分区扫描)。所有其他选项将导致完全 table 扫描,完全不推荐。
您可能会发现此 link 有用:https://docs.microsoft.com/en-us/azure/storage/tables/table-storage-design-guidelines。
我有一个典型的场景,其中消费者调用 Azure Function (EP1)(同步),然后根据 Azure Function 的输入参数查询 Azure Table 存储(有 500 万条记录) API。 Azure Table 存储有以下列:
- 订单号(递增)
- IsConfirmed(可以有值 Y 或 N)
- 订单类型(最多可以有 6 种)
- 订购日期
- 订单详情
- UUID
现在,当消费者查询时,它通常使用订单号进行搜索,并期望在响应中提供订单日期和订单详细信息以及订单号。
为此,我们选择了:
- 分区键:IsConfirmed + 订单类型
- 行键:UUID
现在500万条记录搜索,由于分区键类型,搜索分区往往会遇到超过300万条记录(最大订单IsConfirmed为Y,订单类型为六种类型中的特定一种)和Table 查询需要超过 5 分钟。 因此,消费者通常会超时,因为消费者端配置的等待时间为 60 秒。
所以正在寻找有关如何有效执行此操作的建议。
- 我们可以选择分区键作为 Order Number(但这将创建 500 万个分区)还是 Order NUmber+IsConfirmed+TypeofOrder 的组合?
- 我们的 Java 应用程序需要大量写入,读取次数要少得多。
+++++++++++更新++++++++++++++
正如 Gaurav 在回答中所建议的那样,将 orderid 作为分区键后,查询按预期工作。
现在带来下一个问题 - 我们确实有其他 API 查询,其中订单数据和类型仅用作输入搜索条件。
由于这与分区键不匹配,因此在第二种类型的查询中,它基本上进行了一次整体扫描,并且消费者再次超时。
那么应该设计什么来处理这些类型的查询。Azure 文档说创建一个单独的 table,其中订单类型 + 订单日期成为分区键。然而,这意味着每当我们写入 table 时,我们都必须在两个 table 上写入(一个以 orderid 作为部分键,另一个作为订单日期 + 类型作为部分键)。
Can we choose partition key as Order Number (but that will create 5 million partitions) or a combination of Order NUmber+IsConfirmed+TypeofOrder?
你当然可以选择partition key作为order number,partition数量多也没什么不好。但是,请记住分区键值是字符串类型。你可能想要做的是用一些字符(比如 0)填充你的订单号,这样你所有的订单都具有相同的长度。
在这种情况下,我实际上建议您将行键保留为空。
根据您的查询要求,您可能还想考虑使用不同分区 key/row 键组合存储相同数据的多个副本。例如,如果您要按订单日期查询,您可能希望制作另一个以订单日期作为分区键的数据副本。
一般来说建议做点查询(同时查询partition key和row key)。下一个最佳选择是按分区键查询(您希望将分区键中的数据保持较小,这样您就不会进行分区扫描)。所有其他选项将导致完全 table 扫描,完全不推荐。
您可能会发现此 link 有用:https://docs.microsoft.com/en-us/azure/storage/tables/table-storage-design-guidelines。