Docs 菜单
Docs 主页
/
MongoDB Manual
/ /

按应用程序或客户细分数据

在此页面上

  • Scenario
  • 步骤

在分片集群中,您可以根据分 片键 创建分片数据的 区域 。您可以将每个区域与集群中的一个或多个分片相关联。一个分片可以与任意数量的区域关联。在均衡集群中, MongoDB 仅将区域覆盖的数据段迁移到与该区域关联的分片。

提示

通过对空集合或不存在的集合进行分片之前定义区域和区域范围,分片集合操作会为定义的区域范围创建数据段以及任何其他数据段,以覆盖分片键值的整个范围,并执行基于区域范围的初始数据段分配。数据段的初始创建和分布可以更快地设置区域分片。在初始分布之后,负载均衡器将管理未来的数据段分布。

有关示例,请参阅为空集合或不存在的集合预先定义区域和区域范围

本教程向您展示如何使用区域分割数据。

考虑以下场景,可能需要按应用程序或客户对数据进行分段:

  • 一个数据库为多个应用程序提供服务

  • 为多个客户提供服务的数据库

  • 需要隔离应用程序或客户数据的范围或子集的数据库

  • 需要为应用程序或客户数据的范围或子集分配资源的数据库

此图说明了一个分片集群,该集群使用区域根据应用程序或客户对数据进行分段。 这样就可以将数据隔离到特定的分片。 此外,每个分片都可以分配特定的硬件,以满足该分片上存储的数据的性能要求。

用于支持数据分段的区域概述

应用程序追踪用户的分数以及client gamifyusers字段,将分数存储在collection集合下的数据库中。client的每个可能值都需要自己的区域,以便进行数据分段。 它还允许管理员优化与client关联的每个分片的硬件,以提高性能和成本。

以下文档表示两个用户的部分视图:

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"client" : "robot",
"userid" : 123,
"high_score" : 181,
...,
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fb"),
"client" : "fruitos",
"userid" : 456,
"high_score" : 210,
...,
}

users 集合使用 { client : 1, userid : 1 } 复合索引作为分片键。

每个文档中的client字段允许为每个不同的客户端值创建一个区域。

userid 字段为分片键提供相对于 country 的高关联基数和低分量。

有关选择分片键的更多一般说明,请参阅选择分片键。

应用程序需要将分片添加到与特定client关联的区域。

分片集群部署当前由四个分片组成。

使用区域的数据分段架构示意图

此应用程序有两个客户端区域。

用于支持数据分段的区域图
机器人客户端(“机器人”)
此区域表示满足client : robot条件的所有文档。
FruitOS 客户端(“Fruitos”)
此区域表示满足client : fruitos条件的所有文档。

对于区域,如果插入或更新的文档与配置的区域匹配,则只能将其写入该区域内的分片。

MongoDB 可以将与已配置区域不匹配的文档写入集群中的任何分片。

注意

上述行为要求集群处于稳定状态,没有任何数据段违反已配置的区域。 有关更多信息,请参阅以下有关负载均衡器的部分。

如果查询至少包含 client 字段,MongoDB 可以将查询路由到特定分片。

例如,MongoDB 可以尝试对以下查询执行针对性的读取操作

chatDB = db.getSiblingDB("gamify")
chatDB.users.find( { "client" : "robot" , "userid" : "123" } )

不带 client 字段的查询执行广播操作。

负载均衡器会根据任何已配置区域将数据段迁移到相应的分片。在迁移之前,分片可能包含违反已配置区域的数据段。平衡完成后,分片应仅包含其范围不违反分配区域的数据段。

添加或删除区域或区域范围可能会导致数据段迁移。根据数据集的大小以及区域或区域范围影响的数据段数量,这些迁移可能会影响集群性能。考虑在特定的计划窗口运行负载均衡器。有关如何设置计划窗口的教程,请参阅计划平衡窗口

对于在自管理部署中使用基于角色的访问控制运行的分片集群,请以在admin数据库上至少具有clusterManager角色的用户身份进行身份验证。

mongos您必须连接到与目标 分片集群 关联的 才能继续。您无法通过直接连接到分片来创建区域或区域范围

1

必须在collection上禁用负载均衡器,以确保在配置新区域时不会发生迁移。

使用 sh.disableBalancing(),指定集合的命名空间,停止均衡器。

sh.disableBalancing("chat.message")

使用 sh.isBalancerRunning() 检查负载均衡器进程是否正在运行。等待当前所有平衡轮次完成后再继续。

2

shard0000添加到robot区域。

sh.addShardTag("shard0000", "robot")

shard0001添加到robot区域。

sh.addShardTag("shard0001", "robot")

shard0002添加到fruitos区域。

sh.addShardTag("shard0002", "fruitos")

shard0003添加到fruitos区域。

sh.addShardTag("shard0003", "fruitos")

运行sh.status()以查看为分片集群配置的区域。

3

定义robot客户端的范围,并使用sh.addTagRange()方法将其与robot区域关联。

此方法需要:

  • 目标collection的完整命名空间

  • 范围的下限(含)

  • 范围的独占上限

  • 区域名称

sh.addTagRange(
"gamify.users",
{ "client" : "robot", "userid" : MinKey },
{ "client" : "robot", "userid" : MaxKey },
"robot"
)

定义fruitos客户端的范围,并使用sh.addTagRange()方法将其与fruitos区域关联。

此方法需要:

  • 目标collection的完整命名空间

  • 范围的下限(含)

  • 范围的独占上限

  • 区域名称

sh.addTagRange(
"gamify.users",
{ "client" : "fruitos", "userid" : MinKey },
{ "client" : "fruitos", "userid" : MaxKey },
"fruitos"
)

MinKeyMaxKey 特殊值保留用于比较。MinKey 总是比其他所有可能的值都低,而 MaxKey 总是比其他所有可能的值都高。配置的范围捕获每个 client 的每个用户。

4

重新启用负载均衡器以重新平衡集群。

使用 sh.enableBalancing(),指定集合的命名空间,启动负载均衡器。

sh.enableBalancing("chat.message")

使用 sh.isBalancerRunning() 检查负载均衡器进程是否正在运行。

5

下次负载均衡器运行时,它会根据配置的区域跨分片迁移数据。

均衡完成后, robot区域中的分片仅包含带有client : robot的文档,而fruitos区域中的分片仅包含带有client : fruitos的文档。

您可以通过运行sh.status()来确认数据块分布。

后退

按位置细分数据

在此页面上