你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
用于在 Azure Cosmos DB for MongoDB vCore 中实现横向缩放的分片功能
Azure Cosmos DB for MongoDB vCore 支持进行分片,从而能够以横向方式分配数据和流量。 集合中的文档被划分为多个区块,这些区块称为逻辑分片。
分片行为是使用集合文档结构中的指定分片键为每个集合单独定义的。 然后,将数据存储到区块中,每个区块对应于一个逻辑分区。 分片键属性的每个唯一值所对应的文档都存储在同一逻辑分片中。
对于插入到分片集合中的每个文档,分片键属性的值经过哈希处理,以计算指定的逻辑分片。 用户无需承担放置逻辑分片并在群集内分配所有逻辑分片的责任,这些工作将完全由服务托管。
逻辑分片
包含相同分片键值的所有文档都属于同一逻辑分片。
例如,我们假设有一个名为“员工”的集合,其文档结构如下。
此表显示了分片键值到逻辑分区的映射关系。
文档 ID | 分片键值 | 逻辑分区 |
---|---|---|
"12345" | "Steve Smith" | 分片 1 |
"23456" | "Jane Doe" | 分片 2 |
"34567" | "Steve Smith" | 分片 1 |
"45678" | "Michael Smith" | 分片 3 |
"56789" | "Jane Doe" | 分片 2 |
集合没有逻辑分片数限制。 一个集合可以拥有与文档数量一样多的逻辑分片,即每个文档中的分片键属性都采用一个唯一的值。
也没有单个逻辑分片的大小限制。
此外,该服务不会将事务限制在逻辑分片的范围内。 Azure Cosmos DB for MongoDB 的基于 vCore 的服务支持适用于多个逻辑分片和群集中的多个物理分片的读取和写入事务。
物理分片
物理分片是负责保存数据和完成数据库事务的底层计算机和磁盘。 该服务将在幕后管理物理分片,这一点与逻辑分片有所不同。
物理分片的数量是在创建群集时定义的。 单个分片群集有一个物理分片,该分片全权负责群集的存储和数据库事务。 多分片群集会在群集中的物理分片之间分配数据和事务。
将逻辑分片映射到物理分片
添加新的逻辑分片时,群集将无缝更新逻辑分片到物理分片的映射关系。 同样,在向群集中添加新的物理分片时,为每个物理分片分配的地址空间将会发生变化,之后,逻辑分片会在整个群集内进行重新平衡。
用于映射逻辑分片和物理分片的哈希范围将在群集中的物理分片之间均匀分布。 每个物理分片都将拥有一个均匀大小的哈希范围存储桶。 对于写入的每个文档,分片键属性的值经过哈希处理,并且该哈希值将决定该文档到底层物理分片的映射。 在内部,多个逻辑分片映射到单个物理分片。 此外,逻辑分片永远不会跨物理分片拆分,并且逻辑分片的所有文档都将仅映射到同一个物理分片。
基于前面使用具有两个物理分片的群集的示例,此表显示了文档到物理分片的示例映射方式。
文档 ID | 分片键值 | 逻辑分区 | 物理分区 |
---|---|---|---|
"12345" | "Steve Smith" | 分片 1 | 物理分片 1 |
"23456" | "Jane Doe" | 分片 2 | 物理分片 2 |
"34567" | "Steve Smith" | 分片 1 | 物理分片 1 |
"45678" | "Michael Smith" | 分片 3 | 物理分片 1 |
"56789" | "Jane Doe" | 分片 2 | 物理分片 2 |
物理分片的容量
预配群集时选择的群集层将决定物理分片的 CPU 和内存容量。 同样,存储 SKU 将决定物理分片的存储和 IOPS 容量。 较大的群集层可提供更高的计算能力和更大的内存,而更大的存储磁盘则可提供更高的存储和 IOPS 容量。 读取繁重型工作负载将受益于更大的群集层,而写入繁重型工作负载则将受益于更大的存储 SKU。 在创建群集后,可以根据应用程序不断变化的需求纵向扩展和缩减群集层。
在多分片群集中,每个物理分片的容量相同。 纵向扩展群集层或存储 SKU 不会更改逻辑分片在物理分片上的位置。 纵向扩展操作后,物理分片数将保持不变,因此无需在群集中重新平衡数据。
物理分片的计算、内存、存储和 IOPS 容量决定了可用于逻辑分片的资源。 未能均匀分配存储和请求量的分片键可能会导致群集中的存储和吞吐量消耗不均衡。 热分区可能会导致物理分片利用不均衡,从而导致不可预知的吞吐量和性能。 因此,分片群集需要预先进行仔细规划,以确保性能可在应用程序需求随时间推移而发生变化时保持稳定。
副本集
每个物理分片都由一组副本组成,也称为副本集。 每个副本都托管数据库引擎的一个实例。 副本集使物理分片中的数据存储具有持久性、高可用性和一致性。 构成物理分片的每个副本都会继承物理分片的存储和计算容量。 Azure Cosmos DB for MongoDB vCore 会自动管理副本集。
进行数据分片的最佳做法
除非集合的存储和事务量可以超过单个物理分片的容量,否则不需要在 Azure Cosmos DB for MongoDB vCore 中进行分片。 例如,该服务为每个分片提供 32 TB 磁盘。 如果集合需要 32 TB 以上的容量,则应将其进行分片。
对于具有多个物理分片的群集,不一定要对其中的每个集合都进行分片。 分片和未分片集合可以在同一群集中共存。 该服务会以最佳方式在群集中分配集合,以尽可能均匀地利用群集的计算和存储资源。
对于读取繁重型应用程序,必须根据使用最频繁的查询模式来选择分片键。 具体而言,应选择集合中最常用的查询筛选器作为分片键,通过将搜索局限在单个物理分片中来优化占比最高的数据库事务。
对于写入性能比读取更重要的读取密集型应用程序,应选择能使数据在物理分片之间均匀分布的分片键。 具有最高基数的分片键可提供尽可能均匀分布的最佳机会。
为了获得最佳性能,逻辑分片的存储大小应小于 4 TB。
为了获得最佳性能,逻辑分片的存储和请求量应在群集的物理分片中均匀分布。
如何进行集合分片
请考虑“cosmicworks”数据库和“employee”集合中的以下文档
{
"firstName": "Steve",
"lastName": "Smith",
"companyName": "Microsoft",
"division": "Azure",
"subDivision": "Data & AI",
"timeInOrgInYears": 7
}
以下示例根据 firstName 属性对 cosmicworks 数据库中的员工集合进行了分片。
use cosmicworks;
sh.shardCollection("cosmicworks.employee", {"firstName": "hashed"})
该集合还可以使用管理员命令进行分片:
use cosmicworks;
db.adminCommand({
"shardCollection": "cosmicworks.employee",
"key": {"firstName": "hashed"}
})
在集合的存储量显著增加后,虽然更改分片键并非理想做法,但还是可以使用 reshardCollection 命令做到这一点。
use cosmicworks;
sh.reshardCollection("cosmicworks.employee", {"lastName": "hashed"})
该集合还可以使用管理员命令进行重新分片:
use cosmicworks;
db.adminCommand({
"reshardCollection": "cosmicworks.employee",
"key": {"lastName": "hashed"}
})
最佳做法是基于分片键属性创建索引。
use cosmicworks;
db.runCommand({
createIndexes: "employee",
indexes: [{"key":{"firstName":1}, "name":"firstName_1", "enableLargeIndexKeys": true}],
blocking: true
})