在分片群集中,您可以基于shard key创建分片数据区域。您可以将每个区域与集群中的一个或多个分片关联。分片可以与任意数量的区域关联。在平衡的集群中,MongoDB 仅将区域覆盖的块迁移到与该区域关联的碎片。
小费
在版本4.0.3中更改:通过在分片一个空的或不存在的集合之前定义区域和区域范围,分片收集操作将为定义的区域范围以及所有其他覆盖整个区域范围的块创建块。分片键值,并根据区域范围执行初始块分配。块的这种初始创建和分配允许更快地设置分区分片。在初始分配之后,平衡器将管理后续的块分配。
有关示例,请参见为空集合或不存在的集合预定义区域和区域范围。
本教程使用区域根据创建日期将文档路由到分区以支持最新文档的区域,或分区以支持归档文档的区域。
以下是一些根据服务水平协议(SLA)或服务水平目标(SLO)细分数据的示例用例:
下图说明了使用基于硬件的区域来满足数据访问SLA或SLO的分片群集。
照片共享应用程序需要快速访问最近6个月内上传的照片。该应用程序将每张照片的位置及其元数据存储在集合photoshare
下的数据库中data
。
以下文档代表单个用户上传的照片:
请注意,只有的文档是在过去一年(截至2016年6月)内上传的。_id : 10003012
该应用程序需要根据其硬件层将每个分片添加到区域中。每个硬件层代表一个特定的硬件配置,旨在满足给定的SLA或SLO。
这些是性能最快的计算机,具有大量的RAM,快速的SSD磁盘和强大的CPU。
该区域需要具有以下范围:
{ creation_date : ISODate(YYYY-mm-dd)}
YYYY-mm-dd
{ creation_date : MaxKey }
这些计算机使用较少的RAM,较慢的磁盘和更多的基本CPU。但是,它们每台服务器的存储量更大。
该区域需要具有以下范围:
{ creation_date : MinKey }
{ creation_date : ISODate(YYYY-mm-dd)}
recent
随着性能需求的提高,添加额外的碎片并将其基于其硬件层与适当的区域相关联,可以使群集水平扩展。
在基于时间跨度定义区域范围时,请权衡不频繁更新区域范围的好处与更新时必须迁移的数据量。例如,为数据视为“最新”设置一个1年的限制可能比设置1个月的限制覆盖更多的数据。虽然以1个月为单位轮换需要更多的迁移,但是必须迁移的文档数量少于以1年为单位轮换的文档数量。
对于区域,如果插入或更新的文档与配置的区域匹配,则只能将其写入该区域内的分片。
MongoDB可以将与配置的区域不匹配的文档写入集群中的任何分片。
注意
上述行为要求群集处于稳定状态,且没有块违反配置的区域。有关更多信息,请参见平衡器的以下部分。
如果查询包含分片键,则MongoDB可以将查询路由到特定分片。
例如,MongoDB可以对以下查询尝试有针对性的读取操作,因为它包含
creation_date
在查询文档中:
如果请求的文档在recent
区域范围内,则MongoDB会将此查询路由到该区域内的分片,从而确保与集群范围的广播读取操作相比,读取速度更快
所述平衡器 迁移组块到相应的碎片尊重任何配置的区域。在迁移之前,碎片可能包含违反已配置区域的块。平衡完成后,分片应仅包含范围不违反其指定区域的块。
添加或删除区域或区域范围可能导致块迁移。根据数据集的大小以及区域或区域范围影响的块数,这些迁移可能会影响群集性能。考虑在特定的计划窗口内运行平衡器。有关如何设置调度窗口的教程,请参阅调度平衡窗口。
对于使用基于角色的访问控制运行的分片群集,至少要clusterManager
以具有admin
数据库角色的用户身份进行身份验证。
您必须连接到mongos
以创建区域或区域范围。您不能直接连接到创建区域或区域范围的
碎片。
必须在集合上禁用平衡器,以确保在配置新区域时不进行任何迁移。
使用sh.disableBalancing()
(指定集合的名称空间)停止平衡器
使用sh.isBalancerRunning()
检查,如果平衡器进程当前正在运行。等到当前的所有平衡操作完成后再继续。
添加shard0000
到recent
区域。
添加shard0001
到recent
区域。
添加shard0002
到archive
区域。
您可以通过运行查看分配给任何给定分片的区域
sh.status()
。
定义最近照片的范围,并recent
使用sh.addTagRange()
方法将其关联到区域。此方法要求:
定义较旧照片的范围,并archive
使用sh.addTagRange()
方法将其关联到
区域。此方法要求:
重新启用平衡器以重新平衡集群。
使用sh.enableBalancing()
(指定集合的名称空间)启动平衡器
使用sh.isBalancerRunning()
检查,如果平衡器进程当前正在运行。
平衡器下一次运行时,它将 在尊重已配置区域的碎片之间拆分和 迁移块。
平衡完成后,recent
区域中的碎片仅应包含creation_date
大于或等于的
文档ISODate("2016-01-01")
,而archive
区域中的碎片应仅包含creation_date
小于的
文档ISODate("2016-01-01")
。
您可以通过运行确认块分布sh.status()
。
要更新分片范围,作为cron作业或其他计划的过程的一部分,请执行以下操作:
必须在集合上禁用平衡器,以确保在配置新区域时不进行任何迁移。
使用sh.disableBalancing()
(指定集合的名称空间)停止平衡器
使用sh.isBalancerRunning()
检查,如果平衡器进程当前正在运行。等到当前的所有平衡操作完成后再继续。
recent
使用sh.removeTagRange()
方法删除旧的区域范围
。此方法要求:
archive
使用sh.removeTagRange()
方法删除旧的区域范围
。此方法要求:
定义最近照片的范围,并recent
使用sh.addTagRange()
方法将其关联到区域。此方法要求:
定义较旧照片的范围,并archive
使用sh.addTagRange()
方法将其关联到
区域。此方法要求:
重新启用平衡器以重新平衡集群。
使用sh.enableBalancing()
(指定集合的名称空间)启动平衡器
使用sh.isBalancerRunning()
检查,如果平衡器进程当前正在运行。
下次平衡器运行时,它将在必要时 拆分块,并 在尊重已配置区域的情况下跨碎片迁移块。
在进行平衡之前,recent
区域中的分片仅包含creation_date
大于或等于的文档ISODate("2016-01-01")
,而archive
区域中的分片仅包含creation_date
小于的文档
ISODate("2016-01-01")
。
平衡完成后,recent
区域中的碎片仅应包含creation_date
大于或等于的
文档ISODate("2016-06-01")
,而archive
区域中的碎片应仅包含creation_date
小于的
文档ISODate("2016-06-01")
。
您可以通过运行确认块分布sh.status()
。