你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
数据分区建议
适用于此 Azure 架构良好的框架可靠性清单建议:
RE:06 | 在应用程序、数据和基础结构级别实施及时、可靠的缩放策略。 |
---|
相关指南:缩放
本指南介绍了为部署的数据库和数据存储技术设计数据分区策略的建议。 此策略可帮助你提高数据资产的可靠性。
关键设计策略
在许多大规模解决方案中, 分区 用于划分数据,以便可以单独管理和访问数据。 分区数据可提高可伸缩性、减少争用并优化性能。 实现数据分区以按使用模式划分数据。 例如,可以在廉价的数据存储中存档旧数据。 请仔细选择分区策略,以最大限度地发挥优势并最大程度地减少负面影响。
注意
在本文中,术语“分区”是指以物理方式将数据分割成独立数据存储的过程。 它不同于 SQL Server 表分区。
可以将数据分区为:
提高缩放性。 纵向扩展单一数据库系统时,数据库最终达到物理硬件限制。 如果将数据划分为多个分区,且每个分区托管在单独的服务器上,则可以几乎无限期地横向扩展系统。
改善性能。 在每个分区中,与未分区的数据相比,数据访问操作在较小的数据量上执行。 对数据进行分区,使系统更高效。 影响多个分区的操作可以同时运行。
提高安全性。 在某些情况下,可以将敏感和非敏感数据分成不同的分区,并将不同的安全控制应用于敏感数据。
提供操作灵活性。 可以将数据分区,以微调操作、最大程度地提高管理效率并最大程度地降低成本。 例如,可以根据每个分区中数据的重要性定义管理、监视、备份和还原和其他管理任务的策略。
将数据存储和使用模式相匹配。 可以根据数据存储提供的成本和内置功能,在不同类型的数据存储上部署每个分区。 例如,可以在 Blob 存储中存储大型二进制数据,并将结构化数据存储在文档数据库中。 有关详细信息,请参阅 “了解数据存储模型”。
提高可用性。 若要避免单一故障点,可以跨多个服务器分隔数据。 如果一个实例发生故障,只有该分区中的数据不可用。 操作在其他分区中继续。 此注意事项与托管平台即服务(PaaS)数据存储不太相关,因为它们具有内置冗余。
选择正确的分区策略
数据分区有三个典型策略:
水平分区\(通常称为分片)。 在此策略中,每个分区都是独立的数据存储,但所有分区具有相同的架构。 每个分区称为 分片 ,并保存一部分数据,例如一组客户订单。
垂直分区。 在此策略中,每个分区在数据存储中保存项字段的子集。 这些字段已根据其使用模式进行分割。 例如,将经常访问的字段放在一个垂直分区,将较不经常访问的字段放在另一个垂直分区。
功能分区。 在此策略中,数据根据系统中每个绑定上下文如何使用数据进行聚合。 例如,电子商务系统可能在一个分区中存储发票数据,在另一个分区中存储产品库存数据。
设计分区方案时,请考虑合并这些策略。 例如,可以将数据分割成分片,然后使用垂直分区进一步细分每个分片中的数据。
水平分区(分片)
下图显示了水平分区或分片的示例。 此示例将产品清单数据划分为基于产品密钥的分片。 每个分片保存分区键(A-G 和 H-Z)的连续范围数据,根据字母顺序排列。 执行分片时,它会将负载分散到更多计算机上,从而减少争用并提高性能。
最重要的因素是所选的分片键。 系统运行之后,就很难更改该键。 键必须确保在进行数据分区时,工作负荷能够尽量跨分片平均分配。
分片不需大小一致。 请求数的平衡更为重要。 某些分片可能很大,但分片中的每个项都有少量的访问操作。 其他分片可能更小,但分片中的每个项都会更频繁地访问。 此外,请务必确保单个分片不超过数据存储的容量和处理资源的规模限制。
避免创建 可能影响性能和可用性的热 分区。 例如,如果使用客户名称的第一个字母,则它可以创建不平衡的分布,因为某些字母比其他字母更常见。 而是使用客户标识符哈希在分区之间均匀分布数据。
选择一个分片键,以最大程度地减少将来需要拆分大型分片、将小分片合并到较大的分区或更改架构。 这些操作非常耗时,可能需要脱机一个或多个分片。
如果复制了分片,则可以使某些副本保持联机状态,而另一些副本则进行拆分、合并或重新配置。 但是,系统可能会限制可以在重新配置期间执行的操作。 例如,可以将副本中的数据标记为只读,避免出现数据不一致的情况。
有关详细信息,请参阅分片模式。
垂直分区
垂直分区的最常见用途是降低与提取经常访问的项相关的 I/O 和性能成本。 下图显示了垂直分区的示例。 在此示例中,项的不同属性存储在不同的分区中。 一个分区保存更频繁访问的数据,包括产品名称、说明和价格。 另一个分区保存库存数据,包括库存计数和最后一个订购日期。
在此示例中,应用程序会在向客户显示产品详细信息时定期查询产品名称、说明和价格。 库存计数和最后一个排序日期位于单独的分区中,因为这两个项目通常一起使用。
请参阅垂直分区的以下优势:
可以将相对缓慢移动的数据(产品名称、说明和价格)与更动态的数据(库存水平和上次订购日期)分开。 慢移动数据是应用程序在内存中缓存的好候选项。
可以使用添加的安全控制将敏感数据存储在单独的分区中。
垂直分区可以减少必需的并发访问数量。
垂直分区在数据存储中的实体级运行,会部分规范化某个实体,以将它从宽项分割成一组窄项。 它非常适合用于面向列的数据存储,如 HBase 和 Cassandra。 如果列集合中的数据不太可能更改,请考虑在 SQL Server 中使用列存储。
功能分区
如果可以为应用程序中每个不同的业务区域标识绑定上下文,则功能分区可以提高隔离和数据访问性能。 功能分区的另一种常见用途是将读写数据与只读数据隔离。 下图显示了功能分区的概述,该分区具有与客户数据分离的清单数据。
此分区策略可帮助减少跨系统中不同部件的数据访问争用。
设计分区以实现可伸缩性
考虑每个分区的大小和工作负荷至关重要。 平衡它们,使数据分布以实现最大可伸缩性。 但是,还必须对数据进行分区,使其不超过单个分区存储的缩放限制。
在设计分区以实现可伸缩性时,请按照以下步骤操作:
分析应用程序以了解数据访问模式,例如每个查询返回的结果集的大小、访问频率、固有延迟和服务器端计算处理要求。 在许多情况下,少数主要实体需要大部分处理资源。
使用此分析来确定当前和将来的可伸缩性目标,例如数据大小和工作负荷。 然后将数据跨分区分布以符合缩放性目标。 对于水平分区,请选择正确的分片键以确保均匀分布。 有关详细信息,请参阅分片模式。
确保每个分区有足够的资源来处理数据大小和吞吐量方面的可伸缩性要求。 根据数据存储,每个分区的存储空间量、处理能力或网络带宽可能会有限制。 如果要求可能超过这些限制,可能需要优化分区策略或进一步拆分数据。 可能需要组合两个或多个策略。
对系统进行监视,以验证数据是否按预期分配,以及分区是否可以处理负载。 实际使用情况并不总是与分析预测的内容匹配。 可能需要重新平衡分区或重新设计系统的某些部分才能产生所需的平衡。
某些云环境根据基础结构边界分配资源。 确保所选边界的限制为数据量、数据存储、处理能力和带宽的预期增长提供了足够的空间。
例如,如果使用 Azure 表存储,则单个分区在特定时间段内可以处理的请求量有限制。 有关详细信息,请参阅 标准存储帐户的可伸缩性和性能目标。 繁忙的分片所需的资源可能会超出单个分区的处理能力。 可能需要重新分区分片以分散负载。 如果这些表的总大小或吞吐量超过存储帐户的容量,则可能需要创建更多存储帐户并将表分散到这些帐户中。
设计用于查询性能的分区
可以使用小型数据集和运行并行查询来提高查询性能。 每个分区应包含整个数据集的一小部分。 这种数量缩减可以提高查询性能。 但是,分区不是适当的数据库设计和配置的替代方法。 确保实现必要的索引。
在为查询性能设计分区时,请按照以下步骤操作:
检查应用程序要求和性能。
根据业务要求来确定必须始终快速执行的重要查询。
监视系统以识别性能缓慢的查询。
确定最常执行的查询。 即使单个查询的成本最低,累积资源消耗也可能会很大。
对导致性能缓慢的数据进行分区。
限制每个分区的大小,使查询响应时间在目标范围内。
如果使用水平分区,请设计分片键,以便应用程序可以轻松选择适当的分区。 此规范可防止查询扫描每个分区。
考虑分区的位置。 尝试将数据保存在与访问它的应用程序和用户相近的分区中。
如果实体具有吞吐量和查询性能要求,请使用基于该实体的功能分区。 如果此分配仍不符合要求,可以添加水平分区。 单个分区策略通常足够,但在某些情况下,合并这两种策略更高效。
跨分区并行运行查询以提高性能。
设计可用性分区
对数据进行分区以提高应用程序的可用性。 分区可确保整个数据集没有单一故障点,并且可以独立管理数据集的各个子集。
请注意以下会影响可用性的因素:
确定数据的关键性。 确定关键业务数据,例如事务,以及不太关键的操作数据,例如日志文件。
将关键数据存储在高可用性分区中,并创建适当的备份计划。
为不同的数据集建立单独的管理和监视过程。
在同一分区中放置具有相同严重性级别的数据,以便可以使用相同的频率进行备份。 例如,可能需要备份保存事务数据的分区,而不是保存日志记录或跟踪信息的分区。
管理单个分区。 设计分区以支持独立的管理和维护。 这种做法提供了多种优势,例如:
如果分区故障,可以独立恢复该分区,不需使用在其他分区中访问数据的应用程序。
按地理区域对数据进行分区允许在每个位置的非高峰时段执行计划的维护任务。 确保分区太大,防止计划内维护在此时间段内完成。
跨分区复制关键数据。 此策略可提高可用性和性能,但也可能会带来一致性问题。 在每个副本中同步所做的更改需要时间。 在同步期间,不同的分区包含不同的数据值。
优化应用程序代码以使用分区
分区会增大系统设计和开发的复杂性。 将数据分区为系统设计的基本部分,即使系统最初仅包含单个分区也是如此。 如果以事后方式解决分区问题,则很难,因为你已经有一个要维护的实时系统。 你可能会:
必须修改数据访问逻辑。
必须迁移大量的现有数据,以便将其分布到分区中。
遇到难题,因为用户在迁移过程中希望继续使用系统。
在某些情况下,分区并不重要,因为初始数据集很小,单个服务器可以轻松处理它。 某些工作负荷可以不使用分区,但随着用户数量的增加,许多商业系统需要扩展。
一些小型数据存储也受益于分区。 例如,数百个并发客户端可能会访问小型数据存储。 如果在这种情况下对数据进行分区,则有助于减少争用并提高吞吐量。
在设计数据分区方案时,请注意以下几点:
尽量减少跨分区数据访问操作。 尝试将数据保存在分区中最常见的数据库操作中,以最大程度地减少跨分区数据访问操作。 跨分区查询而不是在单个分区中进行查询可能更耗时。 但是,为一组查询优化分区可能会对其他查询集产生不利影响。 如果必须跨分区查询,则应通过运行并行查询并在应用程序中聚合结果来尽量减少查询时间。 在某些情况下,不能使用此方法,例如,如果下一个查询中使用了一个查询的结果。
复制静态引用数据。 如果查询使用相对静态的引用数据(如邮政编码表或产品列表),请考虑在所有分区中复制此数据,以减少不同分区中的单独查找操作。 此方法还可以减少引用数据成为 来自整个系统的大量流量的热 数据集的可能性。 与同步对引用数据的更改相关的额外成本。
尽量减少跨分区联接。 尽量减少跨垂直和功能分区的引用完整性的要求。 在这些方案中,应用程序负责维护跨分区的引用完整性。 跨多个分区联接数据的查询效率低下,因为应用程序通常执行基于键和外键的连续查询。 建议复制或取消规范化相关的数据。 如果需要进行跨分区联接,请对各分区运行并行查询,并在应用程序内部联接数据。
实现最终一致性。 评估强一致性是否是必需的。 分布式系统中的一种常见方法是实施最终一致性。 每个分区中的数据单独更新,应用程序逻辑可确保更新成功完成。 应用程序逻辑还处理在最终一致的操作运行时查询数据产生的不一致。
考虑查询如何查找正确的分区。 如果查询必须扫描所有分区才能找到所需的数据,即使运行多个并行查询,它也会显著影响性能。 使用垂直分区和功能分区,查询可以指定分区。 另一方面,水平分区可能会使定位项变得困难,因为每个分片具有相同的架构。 典型的解决方案是维护用于查找项分片位置的映射。 在应用程序的分片逻辑中实现此映射。 如果数据存储支持透明分片,则数据存储还可以维护它。
定期重新平衡分片。 使用水平分区,重新均衡分片有助于按大小和工作负荷均匀分配数据。 重新平衡分片,以最大程度地减少热点、最大化查询性能,以及解决物理存储限制。 此任务很复杂,通常需要自定义工具或流程。
复制分区。 复制每个分区以提供针对故障的附加保护。 如果单个副本失败,则查询将定向到工作副本。
将可伸缩性扩展到不同的级别。 如果达到了分区策略的物理限制,可能需要将缩放性扩展到其他级别。 例如,如果分区位于数据库级别,则可能需要在多个数据库中查找或复制分区。 如果分区已在数据库级别,并且存在物理限制,则可能需要在多个托管帐户中找到或复制分区。
避免执行在多个分区中访问数据的事务。 某些数据存储对修改数据的操作实现事务一致性和完整性,但前提是数据位于单个分区中。 如果需要跨多个分区的事务支持,请将其作为应用程序逻辑的一部分实现,因为大多数分区系统不提供本机支持。
所有数据存储都需要某种操作管理和监视活动。 这些任务包括加载数据、备份和还原数据、重新组织数据以及确保系统能够正确高效地执行。
请注意以下会影响操作管理的因素:
对数据进行分区时,实现适当的管理和操作任务。 这些任务可能包括备份与还原、存档数据,监视系统及其他管理任务。 例如,在备份和还原操作期间保持逻辑一致性可能很困难。
将数据加载到多个分区中,并添加来自其他源的新数据。 某些工具和实用工具可能不支持分片数据操作,例如将数据加载到正确的分区。
定期存档和删除数据。 为了防止分区的过度增长,每月存档和删除数据。 可能需要转换数据以匹配不同的存档架构。
查找数据完整性问题。 请考虑运行定期进程来查找数据完整性问题,例如一个分区中的数据引用另一个分区中缺少的信息。 该过程可以自动尝试修复这些问题,也可以生成报告进行手动评审。
重新平衡分区
随着系统成熟,可能需要调整分区方案。 例如,单个分区可能会开始接收不成比例的流量并变得热,从而导致争用过多。 或者,你可能低估了某些分区中的数据量,这会导致分区接近容量限制。
某些数据存储(例如 Azure Cosmos DB)可能会自动对分区进行重新均衡。 在其他情况下,可以在两个阶段重新平衡分区:
确定新的分区策略。
需要拆分或组合哪些分区?
新分区键是什么?
将数据从旧的分区方案迁移到一组新的分区。
重新定位数据(称为 脱机迁移)时,可能需要使分区不可用。 根据数据存储,可以在分区之间迁移数据,而分区正在使用这些数据。 此方法称为 联机迁移。
脱机迁移
脱机迁移可减少争用的可能性。 若要执行脱机迁移,请执行以下操作:
将分区标记为脱机。 可以将分区标记为只读,以便应用程序在移动分区时仍可读取数据。
拆分/合并数据,并将其转移到新分区。
验证数据。
使新分区联机。
删除旧分区。
联机迁移
与脱机迁移相比,联机迁移更为复杂,但中断性更低。 此过程类似于脱机迁移,但不会将原始分区标记为脱机。 根据迁移过程的粒度,例如逐项排序,而不是分片分片,客户端应用程序中的数据访问代码可能需要读取和写入位于两个位置的数据,即原始分区和新分区。
Azure 便利化
以下部分介绍有关对 Azure 服务中存储的数据进行分区的建议。
Azure SQL 数据库中的分区
单个 SQL 数据库对其包含的数据列施加了限制。 吞吐量受体系结构因素及数据库支持的并发连接数的约束。
弹性池支持对 SQL 数据库进行水平缩放。 使用弹性池将数据分区为分布在多个 SQL 数据库的分片中。 还可以在数据量增长和收缩时添加或删除分片。 使用弹性池还有助于在数据库之间分散负载,减少争用。
每个分片将作为 SQL 数据库实施。 分片可以保存多个数据集。 每个数据集称为 shardlet。 每个数据库都有描述其包含的 shardlet 的元数据。 shardlet 可以是单个数据项,也可以是共享同一 shardlet 键的一组项。 例如,在多租户应用程序中,shardlet 密钥可以是租户 ID,租户的所有数据都可以位于同一 shardlet 中。
应用程序负责将数据集与 shardlet 密钥相关联。 独立的 SQL 数据库将充当全局分片映射管理器。 此数据库有一个列表,其中包含系统中的所有分片和 shardlet。 应用程序在连接到分片映射管理器数据库后,可以获取分片映射的副本。 它会在本地缓存分片映射,并使用映射将数据请求路由到相应的分片。 此功能隐藏在 SQL 数据库 弹性数据库功能的客户端库中的一系列 API 后面,此功能适用于 Java 和 .NET。
有关弹性池的详细信息,请参阅使用SQL 数据库横向扩展。
若要减少延迟并提高可用性,可以复制全局分片映射管理器数据库。 使用高级定价层,可以配置活动异地复制,以持续将数据复制到不同区域中的数据库。
或者,将SQL 数据同步用于SQL 数据库或Azure 数据工厂跨区域复制分片映射管理器数据库。 这种形式的复制会定期运行,如果分片映射不常更改且不需要高级层,则更合适。
弹性数据库提供了两种方案用于将数据映射到 shardlet 并将 shardlet 存储在分片中:
列表分片映射将单个键与 shardlet 相关联。 例如,在多租户系统中,每个租户的数据可与唯一的键相关联,并存储在自身的 shardlet 中。 为了保证隔离,可将每个 shardlet 都保存在自身的分片中。
下载此图的 Visio 文件。
范围分片映射将一组连续键值与 shardlet 相关联。 例如,可以在同一 shardlet 中对一组租户(每个租户都有自己的密钥)进行分组。 此方案的成本低于列表分片映射,因为租户共享数据存储,但它提供较少的隔离。
下载此示意图的 Visio 文件
单个分片可以包含多个 shardlet 的数据。 例如,可以使用列表 shardlet 将不同非连续租户的数据存储在同一分片中。 还可以在同一分片中混合范围 shardlet 和列出 shardlet,但随后会通过不同的映射对它们进行寻址。 下图显示了此方式:
下载此图的 Visio 文件。
使用弹性池,可以在数据量增长和收缩时添加和删除分片。 客户端应用程序可以动态和透明地创建和删除分片映射管理器。 但删除分片是破坏性操作,还需要删除该分片中的所有数据。
如果应用程序需要将一个分片拆分成两个独立的分片或者将分片组合在一起,请使用拆分/合并工具。 此工具作为 Azure Web 服务运行,并在分片之间安全地迁移数据。
分区方案可能会显著影响系统的性能。 它还会影响添加或删除分片的速率,或者跨分片对数据重新分区的速率。 请考虑以下要点:
将同一分片中一起使用的数据分组,并避免访问多个分片中的数据的操作。 分片是自己的 SQL 数据库,当操作访问多个分片时,必须在客户端上执行跨数据库联接。
尽管SQL 数据库不支持跨数据库联接,但可以使用弹性数据库工具来执行多分片查询。 多分片查询会将单个查询发送到每个数据库,然后将结果合并在一起。
设计一个在分片之间没有依赖关系的系统。 引用完整性约束、触发器和一个数据库中的存储过程不能引用另一个数据库中的对象。
如果你有查询经常使用的引用数据,请考虑跨分片复制数据。 这种方法可以消除跨数据库联接数据的需求。 理想情况下,此类数据应该是静态的或缓慢移动的,以尽量减少复制工作,并降低它变得过时的可能性。
对属于同一分片映射的 shardlet 使用相同的架构。 SQL 数据库不会强制执行本指南,但如果每个 shardlet 具有不同的架构,数据管理和查询就很复杂。 为了避免这种情况,请为每个架构创建单独的分配映射。 可以将属于不同 shardlet 的数据存储在同一分片中。
如果业务逻辑需要执行事务,请将数据存储在同一分片中或实现最终一致性。 事务操作仅支持分片中的数据,而不支持跨分片。 如果事务属于同一分片,则事务可以跨越 shardlet。
将分片放置在访问这些分片中的数据的用户的附近。 此策略有助于缩短延迟。
避免将高度活动和非活动分片组合在一起。 尽量跨分片平均分散负载。 可能需要对分片键进行哈希处理。 如果要定位分片,请确保哈希键映射到存储在靠近访问该数据的用户的分片中保存的 shardlet。
Azure Blob 存储中的分区
使用 Blob 存储,可以存储大型二进制对象。 在需要快速上传或下载大量数据的方案中使用块 Blob。 对需要随机(而不是串行)访问部分数据的应用程序使用页 Blob。
每个块 Blob 或页 Blob 保存在 Azure 存储帐户中的容器中。 使用容器对具有相同安全要求的相关 Blob 进行分组。 这种分组是逻辑性的,而不是物理性的。 在容器中,每个 Blob 都有唯一的名称。
Blob 的分区键是帐户名称、容器名称和 Blob 名称。 分区键用于将数据分区为范围。 这些范围在整个系统中进行负载均衡。 Blob 可以分布在多个服务器上,以横向扩展对这些服务器的访问。 单个 Blob 只能由单个服务器提供。
如果命名方案使用时间戳或数字标识符,则可能会导致流量过多到一个分区。 它可防止系统有效地进行负载均衡。 例如,如果每日操作使用带有时间戳的 Blob 对象(例如 yyyy-mm-dd),则该操作的所有流量将转到单个分区服务器。 而是使用三位数哈希作为名称前缀。 有关详细信息,请参阅 分区命名约定。
写入单个块或页面的操作是原子操作,但跨块、页或 Blob 的操作不是。 如果需要确保在跨块、页面和 Blob 执行写入操作时保持一致性,请使用 Blob 租约获取写入锁。
注意事项
数据分区引入了一些需要考虑的挑战和复杂性。
分区之间的数据同步可能会成为挑战。 确保以及时且一致的方式将一个分区的更新或更改传播到其他分区。
需要协调多个分区的备份和还原时,故障转移和灾难恢复过程会变得复杂。 如果某些分区或其备份损坏或不可用,则可能会出现数据完整性问题。
如果需要跨分区进行查询,并且重新平衡分区(如果数据增长不均匀),则数据分区可能会影响性能和可靠性。
相关链接
- 构建可缩放的云数据库
- 数据工厂
- 索引表模式
- 具体化视图模式
- 在扩展云数据库之间移动数据
- 使用弹性数据库工具进行多分片查询
- 分区命名
- 查看数据选项
- 标准存储帐户的可伸缩性和性能目标
- 使用SQL 数据库横向扩展
- 分片模式
- 了解数据存储模型
- 使用弹性池在SQL 数据库中管理和缩放多个数据库
- 什么是 Azure SQL 数据同步?
可靠性清单
请参阅完整的建议集。