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