用于更改 SLA 或 SLO 的分层硬件

在本页面

在分片群集中,您可以基于shard key创建zones的分片数据。您可以将每个区域与集群中的一个或多个分片关联。分片可以与任意数量的区域关联。在平衡群集中,MongoDB 仅将区域覆盖的chunks迁移到与该区域关联的分片。

本教程使用Zones根据创建日期将文档路由到分区以支持最新文档的分区,或分区为支持归档文档的分区。

以下是一些根据服务水平协议(SLA)或服务水平目标(SLO)细分数据的示例用例:

  • 应用程序需要提供对最近插入/更新的文档的低延迟访问

  • 应用程序需要优先考虑对文件范围或子集的低延迟访问

  • 通过确保将特定范围或数据子集存储在具有适合 SLA 访问数据的硬件的服务器上而受益的应用程序

下图说明了使用基于硬件的区域来满足数据访问 SLA 或 SLO 的分片群集。

分层 SLA 的分片群集 Schema

Scenario

照片共享应用程序需要快速访问最近 6 个月内上传的照片。该应用程序将每张照片的位置及其元数据存储在data集合下的photoshare数据库中。

以下文档代表单个用户上传的照片:

{
  "_id" : 10003010,
  "creation_date" : ISODate("2012-12-19T06:01:17.171Z"),
  "userid" : 123,
  "photo_location" : "example.net/storage/usr/photo_1.jpg"
}
{
  "_id" : 10003011,
  "creation_date" : ISODate("2013-12-19T06:01:17.171Z"),
  "userid" : 123,
  "photo_location" : "example.net/storage/usr/photo_2.jpg"
}
{
  "_id" : 10003012,
  "creation_date" : ISODate("2016-01-19T06:01:17.171Z"),
  "userid" : 123,
  "photo_location" : "example.net/storage/usr/photo_3.jpg"
}

请注意,在过去的一年(截至 2016 年 6 月)中仅上载了带有_id : 10003012的文档。

Shard Key

照片集使用{ creation_date : 1 }索引作为分片键。

每个文档中的creation_date字段允许在创建日期创建区域。

Architecture

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

分层 SLA 的分片群集 Schema

Zones

该应用程序需要根据其硬件层将每个分片添加到区域中。每个硬件层代表一个特定的硬件配置,旨在满足给定的 SLA 或 SLO。

分层 SLA 的分片群集 Schema

  • 快速层(“最近”)

    • 这些是性能最快的计算机,具有大量的 RAM,快速的 SSD 磁盘和强大的 CPU。

该区域需要具有以下范围:

  • 下限{ creation_date : ISODate(YYYY-mm-dd)},其中YYYY-mm-dd指定的年,月和日位于最近 6 个月内。

  • 上限{ creation_date : MaxKey }

  • Files 层(“Files”)

    • 这些计算机使用较少的 RAM,较慢的磁盘和更多的基本 CPU。但是,它们每台服务器的存储量更大。

该区域需要具有以下范围:

  • 下限{ creation_date : MinKey }

  • 上限{ creation_date : ISODate(YYYY-mm-dd)},其中年,月和日期与用于recent层下限的值匹配。

Note

MinKeyMaxKey值是保留的特殊值,用于比较。

随着性能需求的增加,添加额外的碎片并将其基于其硬件层与适当的区域相关联,可以使群集水平扩展。

在基于时间 Span 定义区域范围时,请权衡不频繁更新区域范围的好处与更新时必须迁移的数据量。例如,为数据视为“最新”设置 1 年的限制可能比设置 1 个月的限制覆盖更多的数据。虽然以 1 个月为单位轮换需要更多的迁移,但是必须迁移的文档数量少于以 1 年为单位轮换的文档数量。

Write Operations

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

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

Note

上述行为要求群集处于稳定状态,且没有块违反配置的区域。有关更多信息,请参见balancer的以下部分。

Read Operations

如果查询包含分片键,则 MongoDB 可以将查询路由到特定分片。

例如,MongoDB 可以对以下查询尝试有针对性的读取操作,因为它在查询文档中包括creation_date

photoDB = db.getSiblingDB("photoshare")
photoDB.data.find( { "creation_date" : ISODate("2015-01-01") } )

如果请求的文档位于recent区域范围内,则 MongoDB 会将此查询路由到该区域内的分片,从而确保与群集范围内的Broadcast 读取操作相比,读取速度更快

Balancer

balancer migrates块分配到适当的分片,尊重任何已配置的区域。在迁移之前,碎片可能包含违反已配置区域的块。平衡完成后,分片应仅包含范围不违反其指定区域的块。

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

Security

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

Procedure

您必须连接到mongos才能创建区域或区域范围。您不能通过直接连接到shard来创建区域或区域范围。

禁用平衡器

必须在集合上禁用平衡器,以确保在配置新区域时不进行任何迁移。

使用sh.disableBalancing()(指定集合的名称空间)来停止平衡器

sh.disableBalancing("photoshare.data")

使用sh.isBalancerRunning()检查平衡器进程当前是否正在运行。等到当前的所有平衡操作完成后再 continue。

将每个分片添加到适当的区域

shard0000添加到recent区域。

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

shard0001添加到recent区域。

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

shard0002添加到archive区域。

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

您可以通过运行sh.status()查看分配给任何给定分片的区域。

定义每个区域的范围

定义最近照片的范围,并使用sh.addTagRange()方法将其关联到recent区域。此方法要求:

  • 目标集合的完整名称空间。

  • 范围的下限值。

  • 范围的排他上限。

  • the zone.

sh.addTagRange(
  "photoshare.data",
  { "creation_date" : ISODate("2016-01-01") },
  { "creation_date" : MaxKey },
  "recent"
)

定义较旧照片的范围,并使用sh.addTagRange()方法将其关联到archive区域。此方法要求:

  • 目标集合的完整名称空间。

  • 范围的下限值。

  • 范围的排他上限。

  • the zone.

sh.addTagRange(
  "photoshare.data",
  { "creation_date" : MinKey },
  { "creation_date" : ISODate("2016-01-01") },
  "archive"
)

MinKeyMaxKey保留为比较用的特殊值。

启用平衡器

重新启用平衡器以重新平衡集群。

使用sh.enableBalancing()(指定集合的名称空间)启动平衡器

sh.enableBalancing("photoshare.data")

使用sh.isBalancerRunning()检查平衡器进程当前是否正在运行。

查看更改

balancer下次运行时,它将跨分片的splitsmigrates块遵循已配置的区域。

平衡完成后,recent区域中的分片应仅包含creation_date大于或等于ISODate("2016-01-01")的文档,而archive区域中的分片应仅包含creation_date小于ISODate("2016-01-01")的文档。

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

更新区域范围

要更新分片范围,请在 cron 作业或其他计划的过程中执行以下操作:

禁用平衡器

必须在集合上禁用平衡器,以确保在配置新区域时不进行任何迁移。

使用sh.disableBalancing()(指定集合的名称空间)来停止平衡器

sh.disableBalancing("photoshare.data")

使用sh.isBalancerRunning()检查平衡器进程当前是否正在运行。等到当前的所有平衡操作完成后再 continue。

删除旧的分片区域范围

使用sh.removeTagRange()方法删除旧的recent区域范围。此方法要求:

  • 目标集合的完整名称空间。

  • 范围的下限值。

  • 范围的排他上限。

  • the zone.

sh.removeTagRange(
  "photoshare.data",
  { "creation_date" : ISODate("2016-01-01") },
  { "creation_date" : MaxKey },
  "recent"
)

使用sh.removeTagRange()方法删除旧的archive区域范围。此方法要求:

  • 目标集合的完整名称空间。

  • 范围的下限值。

  • 范围的排他上限。

  • the zone.

sh.removeTagRange(
  "photoshare.data",
  { "creation_date" : MinKey },
  { "creation_date" : ISODate("2016-01-01") },
  "archive"
)

MinKeyMaxKey保留为比较用的特殊值。

为每个区域添加新的区域范围

定义最近照片的范围,并使用sh.addTagRange()方法将其关联到recent区域。此方法要求:

  • 目标集合的完整名称空间。

  • 范围的下限值。

  • 范围的排他上限。

  • the zone.

sh.addTagRange(
  "photoshare.data",
  { "creation_date" : ISODate("2016-06-01") },
  { "creation_date" : MaxKey },
  "recent"
)

定义较旧照片的范围,并使用sh.addTagRange()方法将其关联到archive区域。此方法要求:

  • 目标集合的完整名称空间。

  • 范围的下限值。

  • 范围的排他上限。

  • the zone.

sh.addTagRange(
  "photoshare.data",
  { "creation_date" : MinKey },
  { "creation_date" : ISODate("2016-06-01") },
  "archive"
)

MinKeyMaxKey保留为比较用的特殊值。

启用平衡器

重新启用平衡器以重新平衡集群。

使用sh.enableBalancing()(指定集合的名称空间)启动平衡器

sh.enableBalancing("photoshare.data")

使用sh.isBalancerRunning()检查平衡器进程当前是否正在运行。

查看更改

下次运行balancer时,它会在必要时splits个块,并在分片上migrates个块会尊重已配置的区域。

在进行平衡之前,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()来确认块分配。