你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。

分片模式

将数据存储划分为一组水平分区或分片。 在存储和访问大量数据时,此方法可以提高可伸缩性。

上下文和问题

单个服务器上的数据存储具有以下限制:

  • 存储空间: 大型云应用程序的数据存储可以包含随着时间的推移而增长的大量数据。 服务器提供有限的磁盘存储量,可以将现有磁盘替换为更大的磁盘,或者随着数据卷的增长而添加更多磁盘。 系统最终达到限制,无法在单个服务器上增加存储容量。

  • 计算资源: 云应用程序必须支持大量并发用户,他们每次对数据存储运行查询。 单个服务器可能无法为此负载提供足够的计算能力,这会导致响应时间和超时时间延长。 可以添加内存或升级处理器,但系统达到限制,无法进一步增加计算资源。

  • 网络带宽: 单个服务器可以接收请求和发送答复的速率会限制数据存储性能。 网络流量可能超过网络连接的容量,这会导致请求失败。

  • 地理: 法律、合规性或性能要求可能需要将用户数据存储在用户所在的同一地理区域中。 如果用户跨越国家/地区,则可能无法将所有应用程序的数据存储在单个数据存储中。

若要暂时推迟这些限制,可以通过添加磁盘容量、处理能力、内存和网络连接来垂直缩放。 必须支持大量用户和大量数据的云应用程序需要水平缩放。

解决方案

将数据存储划分为水平分区或分片。 每个分片具有相同的架构,但包含其自己的不同数据子集。 每个分片都是一个完整的数据存储,可以包含不同类型的许多实体的数据。 分片在充当存储节点的服务器上运行。

此模式具有以下优点:

  • 可以通过在额外的存储节点上添加更多分片来横向扩展系统。

  • 系统可以使用预生成的硬件,而不是为每个存储节点使用专用且昂贵的计算机。

  • 通过在分片间平衡工作负荷可减少争用并提高性能。

  • 在云中,数据分片可以物理上接近访问数据的用户。

将数据存储划分为分片时,确定要将哪些数据放置在每个分片中。 每个分片通常保存按一个或多个数据属性分组的项。 这些属性构成分片键,有时称为 分区键。

分片以物理方式组织数据。 当应用程序存储和检索数据时,分片逻辑会将其定向到相应的分片。 可以在应用程序的数据访问代码或数据存储系统中(如果透明地支持分片)中实现此逻辑。

提取分片逻辑中数据的物理位置可以控制哪些分片包含哪些数据。 如果需要重新分发数据(例如分片变得不平衡),还可以在分片之间迁移数据,而无需修改应用程序业务逻辑。 权衡在于为了确定每个数据项的位置而产生的额外数据访问开销。

分片键选择

分片键是分片系统中最重要的设计决策。 若要在选择后更改分片键,通常必须将所有数据迁移到新的分片布局,这是实时系统上的昂贵且有风险的操作。 在编写任何代码之前,请仔细做出此决定。

有效的分片键是不可变的,具有较高的基数,能够均匀地分布数据和负载,并与主要查询模式保持一致,以便大多数请求能够定位到单个分片上进行解析。 避免单调递增值(自动增加整数和顺序时间戳)、低基数属性(布尔值和小枚举集),以及频繁更改的可变属性。 这些属性会导致热点或成本高昂的跨分片数据移动。

如果没有单个属性满足这些条件,则通过组合两个或多个属性来定义复合分片键。 如果查询需要按不属于分片键的属性检索数据,请使用 索引表 模式等模式来提供辅助查找。

有关如何跨 Azure 服务选择分区键的详细信息,请参阅设计数据分区策略和数据分区策略。

分片策略

选择分片键并决定如何在分片之间分配数据时,请使用以下策略之一。 分片与托管它们的服务器之间不需要一对一对应关系。 单个服务器可以托管多个分片。

查找分片策略

在查找策略(也称为 基于目录的策略)中,分片逻辑实现一个映射,该映射使用分片键将数据请求路由到包含该数据的分片。 在多租户应用程序中,可以使用租户 ID 作为分片键将租户的所有数据一起存储在分片中。 多个租户可以共享相同的分片,但单个租户的数据不会分散到多个分片中。 下图显示了根据租户 ID 分片的租户数据。

显示基于租户 ID 的租户数据的关系图

两个应用程序实例将特定租户的查询发送到分片逻辑组件。 分片逻辑根据租户 ID 将每个请求路由到正确的分片,例如分片 A、分片 B 或分片 C。 每个分片存储一个不同的数据子集。

分片键值和物理存储之间的映射可以是直接的,其中每个分片键值映射到物理分区。 更灵活的技术是虚拟分区,其中分片键值映射到虚拟分片,然后系统将这些虚拟分片映射到更少的物理分区。 应用程序使用引用虚拟分片的分片键值查找数据,并且系统以透明方式将虚拟分片映射到物理分区。 虚拟分片和物理分区之间的映射可以更改,而无需修改应用程序代码。

基于范围的分片策略

基于范围的策略将相关项组合在同一分片中,并按顺序分片键对它们进行排序。 此策略支持使用范围查询频繁检索项集的应用程序。 范围查询返回属于给定范围的分片键的一组数据项。

例如,如果应用程序经常需要查找给定月份下达的所有订单,则可以更快地检索数据(如果在同一分片中以日期和时间顺序存储一个月的所有订单)。 如果将每个订单存储在不同的分片中,应用程序必须通过进行大量的点查询来逐个检索它们。 下图显示了分片中存储的数据的顺序集或范围。

显示分片中存储的连续的数据集或范围的关系图。

应用程序实例提交关于在特定月份下的订单的查询。 分片逻辑组件每月映射到分片,例如 10 月到分片 A、11 月到分片 B 和 12 月到分片 C。订单存储在每个分片中的日期和时间序列中。

在此示例中,分片键是一个复合键,其中包含订单月份作为最重要的元素,后跟订单日期和时间。 新订单在它们被创建和添加到分片时会自然地进行排序。

某些数据存储系统支持由两部分构成的分片键。 分区键标识分片,行键唯一标识分片中的项。 分片通常以行键顺序存储数据。 对于需要范围查询且必须组合在一起的项,可以使用分区键具有相同值的分片键,但对行键具有唯一值。

基于哈希的分片策略

基于哈希的策略可以降低产生热点的几率,即那些接收过多不成比例负载量的分片。 此策略跨分片分配数据,以平衡每个分片的大小以及每个分片遇到的平均负载。 分片逻辑基于数据的一个或多个属性的哈希值来计算将项目存储在哪个分片中。 所选的哈希函数应在分片之间均匀分布数据。 通过租户 ID 的哈希来分片租户数据的示意图如下。

显示基于租户 ID 哈希的分片租户数据的关系图。

特定租户的查询由应用程序实例提交。 分片逻辑组件对租户 ID 进行哈希处理,并将每个请求路由到分片,例如租户 55 将分片 B 和租户 56 路由到分片 N。每个分片存储租户数据的子集。

若要了解哈希策略与其他分片策略的优势,请考虑如何按顺序注册新租户的多租户应用程序将租户分配到数据存储中的分片。 使用范围策略时,租户 1 到 n 的数据存储在分片 A 中,租户 n+1 到 m 的数据存储在分片 B 中,更高版本的租户范围映射到连续分片。 如果最近注册的租户也是最活跃的,则大多数数据活动会集中在几个分片中,这可能会导致热点。 相比之下,哈希策略根据租户 ID 的哈希将租户分配到分片。 哈希通常会将排好的租户分配到不同的分片上,从而实现负载均衡。 上图显示了租户 55 和 56 的此方法。

地理分片策略

地理策略根据该数据的地理原点或预期消耗区域将数据分配到分片。 在许多工作负荷中,用户及其生成的数据集中在特定区域中。 数据驻留法等法规要求可能要求特定数据保留在特定司法管辖区内。 即使没有法规驱动程序,将数据放置在最频繁访问数据的用户附近,也会降低读取和写入的网络延迟。

显示基于应用实例地理位置的分片数据图。

在此策略中,将从地理属性(例如用户的国家/地区、原始数据中心区域或区域租户标识符)派生分片密钥。 在地理边界内托管每个分片,或将其固定到本地基础设施。

例如,为北美、欧洲和 Asia-Pacific 的客户提供服务的应用程序可能会维护三个分片组,每个相应的 Azure 区域中都有一个组。 仅为欧洲用户提供服务的欧洲应用程序将请求路由到欧洲分片。 此方法可降低延迟并满足数据驻留要求。

地理分片引入了数据分布不均匀的风险。 如果大多数用户驻留在一个区域中,则该区域的分片具有不成比例的负载和存储份额。 可以在每个区域内将地理分片与其他策略(例如哈希或查找)结合起来,以均匀分配同一地理范围内的多个分片的负载。

每个策略的优点和注意事项

四个分片策略具有以下优点和注意事项:

  • 查找策略 可更好地控制分片配置。 虚拟分片减少了重新均衡的影响,因为可以添加新的物理分区来平衡工作负荷。 可以修改虚拟分片与其物理分区之间的映射,而不会影响应用程序代码。 查找分片位置会增加开销。

  • 范围策略 易于实现,并且适用于范围查询。 范围查询可以在一个操作中从单个分片中检索多个数据项。 数据管理更简单。 例如,当同一区域中的用户共享分片时,可以根据本地负载模式计划每个时区的更新。 但是,此策略不会在分片之间平均均衡负载。 当大多数活动集中在相邻分片键上时,重新均衡很困难,并且可能无法解决负载不均衡的问题。

  • 哈希策略 提供了更好的数据和负载的均衡分布。 可以使用哈希函数直接路由请求,而无需维护映射。 计算哈希会增加一些开销。 如果不进行一致的哈希处理,则很难重新平衡。

  • 地理策略 满足其他策略本身无法解决的数据驻留和主权要求。 当用户访问其区域中的数据时,它会减少读取和写入延迟。 但是,当用户群体不均匀分布在区域时,地理分片可能会产生显著的数据和负载不平衡。 跨区域(如全局报告)的查询必须从所有地理分片中检索数据,并产生更高的延迟。 当您需要同时满足合规性和均衡负载分布时,可以在每个区域将地理分片与其他策略结合使用。

大多数分片系统实现以下方法之一,但还应考虑应用程序的业务要求及其数据使用模式。 例如,在多租户应用程序中:

  • 可以根据工作负荷对数据进行分片。 在单独的分片中隔离高度易失性租户的数据,以提高其他租户的数据访问速度。

  • 可以根据租户位置对数据进行分片。 使特定地理区域中的租户数据处于脱机状态,以便在该区域非高峰时段进行备份和维护,而其他区域中的租户数据在其工作时间保持联机状态。

  • 为高价值租户分配自己的专用轻负载分片。 价值较低的租户可以共享更高密度的分片。

  • 在单独的服务器上存储需要强数据隔离和隐私的租户的数据。

每个策略的缩放和数据移动操作

每个分片策略提供不同的功能和复杂性级别,用于管理扩展缩小、扩展增加、数据移动和状态维护。

  • 查找策略允许用户级别的在线或离线扩展和数据移动操作。 要移动数据,请按照以下步骤操作:

    1. 暂停部分或所有用户活动,通常是在非高峰期。

    2. 将数据移到新的虚拟分区或物理分片。

    3. 更新映射表。

    4. 使保存此数据的任何缓存失效或刷新。

    5. 恢复用户活动。

    通常可以集中管理此操作。 查找策略要求状态高度可缓存且副本友好。

  • 范围策略 会限制缩放和数据移动操作,因为必须在分片之间拆分和合并数据,通常当部分或所有数据存储处于脱机状态时。 移动数据以重新平衡分片时,如果大多数活动集中在同一范围内的相邻分片键或数据标识符上,则可能无法消除不均衡的负载。 范围策略可能还需要状态才能将范围映射到物理分区。

  • 哈希策略 使缩放和数据移动操作复杂化。 分区键是分片键或数据标识符的哈希。 使用标准哈希函数(例如 hash(key) mod N,添加或删除分片)会重新分配大多数键并触发大规模数据迁移。 一致的哈希处理通过排列哈希空间来减少这种影响,以便在分片计数更改时仅移动一小部分键。 哈希策略不需要维护单独的映射状态。

  • 地理策略 直接将缩放操作链接到区域基础结构预配。 在一个区域中添加容量不会缓解另一个区域中的负载。 要求地理分片的法规要求还可以限制跨地理边界的数据移动。 在每个区域中,缩放使用次要策略在该区域的分片之间分配数据。

问题和注意事项

在决定如何实现此模式时,请考虑以下几点:

  • 使用分片补充其他形式的分区,例如垂直分区和功能分区。 例如,单个分片可以包含垂直分区的实体,并且可以将功能分区实现为多个分片。 有关详细信息,请参阅 水平、垂直和功能数据分区。

  • 保持分片平衡,以便它们都可以处理类似的输入/输出(I/O)负载。 随着记录的插入和删除,数据倾斜会随着时间的推移而累积,从而导致热点。 计划定期重新平衡。

    重新均衡在分片之间移动数据,通常会导致系统停机或吞吐量降低。 若要不太频繁地重新平衡,请使用虚拟分区。 将许多逻辑分区映射到更少的物理分片。 当某个分片超载时,重新分配其虚拟分区到新的物理分片,而无需对整个数据集进行重新哈希。 Azure Cosmos DB 使用此方法将分区方案与物理基础结构分离。

    首选多个小型分片而不是少数大型分片。 较小的分片迁移速度更快,更均衡负载,并为数据重新分发提供更大的灵活性。

  • 将稳定数据用于分片键。 如果分片键发生更改,可能需要在分片之间移动相应的数据项,这会增加更新操作开销。 避免将分片键基于潜在的易失性信息。 选择固定或自然构成键的属性。

  • 确保分片键是唯一的。 例如,避免使用自动递增字段作为分片键。 在某些系统中,自动递增字段无法跨分片进行协调,这可能会导致不同分片中的项具有相同的分片键。

    注释

    在非分片键的其他字段中,自动递增的值也可能会导致问题。 例如,如果使用自增字段生成唯一 ID,可能会为位于不同分片中的两个不同项分配相同的 ID。

  • 对数据进行分片,以支持最常执行的查询。 你可能无法设计一个分片键,该键能够满足针对数据的每个查询的要求。 如有必要,请创建辅助索引表以支持按不属于分片键的属性检索数据的查询。 有关详细信息,请参阅 索引表模式。

  • 设计分片键和数据模型,以确保大多数操作限定在单个分片内。 仅访问单个分片的查询比从多个分片检索数据的查询更有效。 为了减少单独读取的次数,应对数据进行非规范化,将通常同时查询的相关实体(例如客户及其订单)保持在同一分片内。

    跨分片查询增加了延迟、资源消耗和复杂性。 当应用程序必须从多个分片中检索数据时,请使用针对每个分片同时运行的并行扇出查询并聚合结果。 即便进行并行处理,最慢的分片也决定了总体延迟。

    小窍门

    如果一个分片中的实体引用另一个分片中的实体,则包含第二个实体的分片键作为第一个实体架构的一部分。 此方法可以提高跨分片引用相关数据的查询的性能。

  • 重新考虑你的分片键,如果你的工作负载需要跨分片边界的强事务完整性,还需要考虑分片是否符合你的需求。 跨分片事务存在挑战。 分布式协调协议(例如两阶段提交、添加延迟、引入故障模式和降低吞吐量)。 大多数分片系统都避免分布式事务,而是采用最终一致性。 在此模型中,每个分片独立更新,应用程序处理临时不一致。

  • 确保每个分片存储节点可用的资源可以处理数据大小和吞吐量方面的可伸缩性要求。 有关详细信息,请参阅 数据分区策略。

  • 考虑将引用数据复制到所有分片。 如果针对分片的查询还引用静态或移动缓慢的数据,请将此数据添加到分片。 然后,应用程序可以提取查询的所有数据,而无需往返单独的数据存储。

    注释

    如果多个分片中保存的引用数据发生更改,系统必须跨所有分片同步这些更改。 此同步运行时可能会出现某种程度的不一致。 设计应用程序以容忍这种不一致。

  • 分片系统会增加操作负担。 考虑以下问题:

    • 监测: 必须跨所有分片聚合指标和日志,才能获取系统运行状况的完整视图。

    • 备份和还原: 必须独立备份每个分片并设计还原过程,以保持跨分片一致性。 将一个分片恢复到某个时间点可能会导致与其他分片的不一致。

    • 架构更改: 必须跨每个分片协调数据定义语言(DDL)更改。

    可以使用脚本或其他自动化解决方案来实现这些任务。

  • 可以将分片进行地理定位,将其数据放置在使用它的应用程序实例附近。 此方法可以提高性能,但需要对必须在不同位置访问多个分片的操作进行额外规划。

何时使用此模式

小窍门

在设计自定义分片层之前,请确定数据平台已处理哪些分片责任。 某些服务完全管理分片。 例如,Azure Cosmos DB 在物理分区之间分配数据,处理拆分和路由查询,而无需应用程序参与。 其他服务只进行部分分片管理。 例如,Azure SQL 数据库为分片映射管理和数据依赖型路由提供了 弹性数据库工具,但是您需要设计分片密钥并管理拆分操作。 当您自己构建和操作分片逻辑时,请使用分片模式。

在以下情况下使用此模式:

  • 总数据量超过单个数据库实例的存储容量,并且没有垂直缩放选项解决短缺问题。

  • 事务吞吐量或查询并发超出了单个实例可以维持的内容,而只读副本无法解决瓶颈,因为写入负载也很高。

    注释

    分片提高了系统的性能和可伸缩性,还可以提高可用性。 一个分区中的故障不一定阻止应用程序访问其他分区中的数据。 操作员可以执行一个分区的维护或恢复,而不会使所有数据不可用。 有关详细信息,请参阅 设计数据分区策略。

  • 法规或合规性要求要求要求特定数据子集驻留在特定地理司法管辖区,并且任何单区域部署都不能满足所有要求。

  • 出于安全、性能或合同原因,不同的租户或客户细分需要物理数据隔离。

    在这些方案中,分片模式有时会应用于传统数据存储之外。 例如,DNS 区域管理系统可由团队、环境或区域分片,以减少 DNS 更改的爆破半径并建立明确的所有权边界。 在这种情况下,主要动机是操作分段,而不是可伸缩性。 有关详细信息,请参阅 分片专用 DNS 区域。

分片在数据体系结构中引入了大量和永久性的复杂性。 这种复杂性会影响系统生存期的开发、操作、测试、查询设计和故障恢复。

在以下情况下,此模式可能不适用:

  • 即便考虑到未来的增长,你的数据量和吞吐量仍能够在一个单一的数据库实例中进行处理。 垂直缩放可保持查询简单性和事务完整性。

  • 瓶颈在于读取量,而不是写入量或存储容量。 只读副本和缓存层级可以分担读取流量,而无需由分片引入的跨分片查询复杂性。

  • 数据库引擎支持满足性能需求的表级分区。 单个实例中的分区不需要多个服务器或路由逻辑。

  • 你的主导查询模式需要跨实体联接、多实体事务或全数据集聚合。 分片使这些操作变得昂贵,扇出查询和分布式协调的开销可能会超出其扩展带来的好处。

工作负载设计

评估如何在工作负荷的设计中使用分片模式来解决 Azure Well-Architected Framework 支柱中涵盖的目标和原则。 下表提供有关此模式如何支持每个支柱目标的指南。

支柱 此模式如何支持支柱目标
可靠性 设计决策有助于工作负荷在发生故障后 复原 ,并确保它在发生故障后 恢复到 正常运行状态。 数据和处理与分片隔离,因此一个分片中的故障仍与该分片隔离。

- 数据分区
- RE:07 自我保护
成本优化 侧重于 维持和改善 工作负荷的 投资回报。 实现分片的系统通常受益于使用成本较低的计算或存储资源的多个实例,而不是使用单个成本较高的资源。 在许多情况下,这种配置可以为你省钱。

- CO:07 组件成本
通过缩放、数据和代码的优化,性能效率可帮助工作负荷高效地满足需求。 在缩放策略中使用分片时,数据和处理会与每个分片隔离,因此请求只会在其分配的分片中争用资源。 也可以使用分片来根据地理位置进行优化。

- PE:05 缩放和分区
- PE:08 数据性能

如果此模式在某个支柱中引入权衡取舍,请将它们与其他支柱的目标进行对比。

示例

考虑一个网站,显示关于全球出版书籍的广泛信息集合。 在此工作负荷中编录的可能书籍数以及典型的查询和使用模式超过了单个关系数据库可以处理的数量。 负载架构师决定使用书籍的静态 ISBN 作为分片键,将数据分片到多个数据库实例中。 具体而言,架构师使用 ISBN 的 校验码 (0 - 10),该校验码为 11 个可能的逻辑分片提供相对均衡的数据分布。

首先,架构师将 11 个逻辑分片并置为三个物理分片数据库。 在此 虚拟分区方法中,许多逻辑分区映射到更少的物理节点。 架构师使用 查找 分片方法,并将密钥到服务器映射存储在分片映射数据库中。

显示书籍目录应用程序的分片 SQL 数据库体系结构的关系图。

查询分片映射

分片映射数据库包含以下分片映射表和数据。

SELECT ShardKey, DatabaseServer
FROM BookDataShardMap
| ShardKey | DatabaseServer |
|----------|----------------|
|        0 | bookdbshard0   |
|        1 | bookdbshard0   |
|        2 | bookdbshard0   |
|        3 | bookdbshard1   |
|        4 | bookdbshard1   |
|        5 | bookdbshard1   |
|        6 | bookdbshard2   |
|        7 | bookdbshard2   |
|        8 | bookdbshard2   |
|        9 | bookdbshard0   |
|       10 | bookdbshard1   |

示例网站代码:单分片访问

该网站不知道有多少物理分片数据库(在本例中为 3 个)或将分片键映射到数据库实例的逻辑。 它只知道书的 ISBN 的校验位是分片键。 该网站对分片映射数据库具有只读访问权限,对所有分片数据库具有读写访问权限。 在此示例中,网站使用其 Azure 应用服务主机的系统托管标识进行授权,该标识将机密从连接字符串中排除。

网站可以通过 appsettings.json 文件(如示例所示)或通过 App Service 应用设置使用以下连接字符串进行配置。

{
  ...
  "ConnectionStrings": {
    "ShardMapDb": "Data Source=tcp:<database-server-name>.database.windows.net,1433;Initial Catalog=ShardMap;Authentication=Active Directory Default;App=Book Site v1.5a",
    "BookDbFragment": "Data Source=tcp:SHARD.database.windows.net,1433;Initial Catalog=Books;Authentication=Active Directory Default;App=Book Site v1.5a"
  },
  ...
}

以下代码演示如何网站针对工作负荷的数据库分片池运行更新查询。

...

// All data for this book is stored in a shard based on the book's ISBN check digit,
// which is converted to an integer 0 - 10 (special value 'X' becomes 10).
int isbnCheckDigit = book.Isbn.CheckDigitAsInt;

// Establish a pooled connection to the database shard for this specific book.
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: isbnCheckDigit, cancellationToken))
{
  // Update the book's Library of Congress catalog information.
  SqlCommand cmd = sqlConn.CreateCommand();
  cmd.CommandText = @"UPDATE LibraryOfCongressCatalog
                         SET ControlNumber = @lccn,
                             ...
                             Classification = @lcc
                       WHERE BookID = @bookId";

  cmd.Parameters.AddWithValue("@lccn", book.LibraryOfCongress.Lccn);
  ...
  cmd.Parameters.AddWithValue("@lcc", book.LibraryOfCongress.Lcc);
  cmd.Parameters.AddWithValue("@bookId", book.Id);

  await cmd.ExecuteNonQueryAsync(cancellationToken);
}

...

在前面的示例代码中,如果book.Isbn为 978-8-1130-1024-6,则isbnCheckDigit应为 6。 调用 OpenShardConnectionForKeyAsync(6) 通常通过缓存旁路策略实现。 如果分片键 6 的缓存分片信息不可用,该方法将查询连接字符串标识的 ShardMapDb 分片映射数据库。 该方法从应用程序缓存或分片数据库检索值 bookdbshard2 ,并将其替换为 SHARD 连接字符串中的 BookDbFragment 值。 然后,该方法建立或重新建立与 bookdbshard2.database.windows.net 的共用连接,将其打开,并将其返回到调用代码。 然后,代码将更新该数据库实例上的现有记录。

示例网站代码:多个分片访问

在极少数情况下,当网站需要直接的跨分片查询时,应用程序会跨所有分片执行并行扇出查询。

...

// Retrieve all shard keys.
var shardKeys = shardedDatabaseConnections.GetAllShardKeys();

// Run the query in a fan-out style against each shard in the shard list.
Parallel.ForEachAsync(shardKeys, async (shardKey, cancellationToken) =>
{
  using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: shardKey, cancellationToken))
  {
    SqlCommand cmd = sqlConn.CreateCommand();
    cmd.CommandText = @"SELECT ...
                          FROM ...
                         WHERE ...";

    SqlDataReader reader = await cmd.ExecuteReaderAsync(cancellationToken);

    while (await reader.ReadAsync(cancellationToken))
    {
      // Collect the results into a thread-safe data structure.
    }

    reader.Close();
  }
});

...

作为跨分片查询的替代方法,此工作负荷可以在 Azure AI 搜索中使用外部维护的索引进行站点搜索或分面导航。

添加分片实例

工作负荷团队知道,如果数据目录或其并发使用量显著增长,则可能需要三个以上的数据库实例。 工作负荷团队预计不会动态添加数据库服务器,并且当新的分片联机时,它们会接受工作负荷停机。 若要使新的分片实例联机,它们必须将现有分片中的数据移到新的分片中,并更新分片映射表。 使用这种相对静态的方法,工作负载能够放心地在网站代码中缓存分片键数据库映射。

此示例中的分片键逻辑的上限为 11 个物理分片。 如果工作负荷团队通过负载估计来确定它们最终需要 11 个以上的数据库实例,则必须对分片密钥逻辑进行侵入性更改。 此更改涉及仔细规划代码修改和数据迁移到新的密钥逻辑。

SDK 功能

考虑评估弹性数据库客户端库,而不是为 SQL 数据库实例编写自定义代码以进行分片管理和查询路由。 此库支持 C# 和 Java 中的分片映射管理、数据依赖型查询路由和跨分片查询。

后续步骤

  • Azure Cosmos DB 中的一致性级别:跨分片分布数据引入了一致性权衡。 本文介绍一致性模型范围,从强到最终,以及它们对可用性和延迟的影响。
  • 水平、垂直和功能数据分区:本文介绍了用于在云中分区数据以提高可伸缩性、减少争用和优化性能的其他策略。
  • 索引表模式:有时不能仅通过设计分片键来支持所有查询。 应用程序可以使用索引表模式通过指定除分片键以外的键从大型数据存储中检索数据。
  • 具体化视图模式:为了维护某些查询操作的性能,可以创建聚合和汇总数据的具体化视图,尤其是在将数据分散到分片时。