钱文翔的博客

(翻译)Sharding-mongo官方文档3.2版本

此篇文章为mongo官方文档,版本为3.2. 地址为:https://docs.mongodb.com/v3.2/core/sharded-cluster-components/

分片(Sharding)

分片是一个在多个主机上分发数据的方法。 MongoDB用分片实现大数据集合和高吞入量操作。
大数据量集合和高吞吐量操作应用数据库系统挑战单个服务器的容量。例如,高请求速率能耗尽CPU性能。工作集大小大于系统的RAM给磁盘驱动器的I / O性能施加压力
有两种方法处理系统的增长:垂直扩展和水平扩展
垂直扩展涉及扩大单个服务器的性能,例如使用更强大的CPU,添加更多RAM,或者增加存储空间。可用技术中的限制可能会限制单个机器的工作负载能力。另外,云服务提供商在可用的硬件配置上设置上限。所以,对于垂直扩展存在实际的最大值。
水平扩展涉及将系统的数据集切分并通过多服务器加载,添加另外的服务器来扩大需要的容量。既然单个机器的整体速度和容量不高,那么每个机器处理整个工作量的一部分,可能提供比一个高速度高容量服务器更好的效果。扩展部署的容量仅需要根据需要添加额外的服务器,总体成本可能比单个机器的高端硬件低。
MongoDb支持通过分片来进行水平扩展。

分片集群

MongoDB的分片集群由以下组件组成:

  • 分片(shard):每个分片包含被分片数据的子集。每个分片可以被部署成副本集
  • mongos:mogos扮演查询路由(query router)的角色,提供一个在客户端个分片集群之间的接口
  • config servers: 配置服务器存储元数据(metadata)并配置集群的设置。在MongoDB 3.4,配置服务器必须部署成副本集

下面这张图描述了在一个分片集群中的交互
Alt text

MongoDB分片数据是collection级别的,在集群中分发collection数据

Shard keys

为了分发collection中的document,MongoDB使用shard key来对collection进行分区。shard key包含存在于目标collection中的每个document中的不可变的一个字段或者多个字段。
当分片一个collection的时候选择shard key。分片后不能修改选择的shard key。一个分片collection只有一个shard key。
为了分片一个非空的collection,collection必须有一个由shard key开始的索引。对应空的collection,如果collection没有社和的索引来作为特殊的shard key。MongoDB创建一个索引。
shard key的选择影响分片集群的性能,效率和课扩展性。拥有最佳的可能的硬件和基础设施的集群可以通过选择shard key来突破瓶颈。选择分片键及其后缀索引还可以影响集群可以使用的分片策略。

块(Chunks)

MongoDb将分片的数据分割成块(Chunks)。每一个Chunk都根据shard key包含上限和下限。
MongoDB使用分片集群均衡器(sharded cluster balancer)来在分片集群中的shard中迁移块(chunks)。均衡器尝试在集群中的所有分片之间实现块(chunk)的平衡

分片的优势

读/写

MongoDB分发读写工作负载到分片集群中的分片服务器中(shard),允许每一个shard运行集群操作的子集。读和写工作负载都可以通过增加更多的shard来水平扩展。
对于包含shard key或复合shard key的前缀的查询,mongos可以在特定的分片(shard)或分片集上定位查询。这些目标操作通常比向集群中的每个分片广播更有效。

存储容量

在集群中的分片服务器(Shard)中分发共享数据,允许每一个shard包含集群中所有数据的子集。随着数据增长,额外的shards扩大了集群的存储容量。

高可用性

分片集群可以继续执行部分读/写操作,即使一个或者更多的分片服务器(shards)不能使用。虽然在宕机的时间内无法访问在不可用分片服务器上的数据子集,但针对可用分片的读取或写入仍然可以成功。
在生产环境中,应将单个碎片部署为副本集,从而提高冗余和可用性

分片前的注意事项

分片式集群基础架构要求和复杂性需要仔细规划,执行和维护。
仔细考虑选择shard key对于确保集群性能和效率是必要的。您不能在分片后更改分片键,也不能取消分片集合。
如果查询不包括shard key或复合shard key的前缀,则mongos执行广播操作,查询分片群集中的所有分片。这些分散/聚集查询可能导致长时间运行操作。

分片的和未分片的集合

数据库可以混合着分片和非分片集合。分片集合被分区并分布在集群中的分片上。未分片集合存储在主分片上。每个数据库都有自己的主分片。
Alt text

连接分片集群

您必须连接到mongos路由器才能与分片集群中的任何集合进行交互。这包括分片和非分片集合。客户端不应该连接到单个分片以执行读取或写入操作。
Alt text

你可以像连接到mongod一样连接到mongos,例如通过mongo shell或MongoDB驱动程序

分片策略

MongoDB支持两种分片策略,用于在分片集群中分发数据。

散列分片(Hashed Sharding)

散列分片涉及计算分片键字段值的散列。然后根据散列分片键值为每个块分配一个范围。
Alt text

虽然分片键的范围“相近”,但是它们的散列值不可能在同一块上。 基于散列值的数据分布有助于更均匀的数据分布,特别是在碎片键单调变化的数据集中
然而,散列分布意味着对分片键的基于范围的查询不太可能针对单个分片,导致更多的集群广播操作。

范围分片(Ranged Sharding)

远程分片涉及基于shard key将数据划分为范围。然后根据shard key为每个块(chunk)分配一个范围。
Alt text

其值“相近”的分片键(shard key)的范围更可能驻留在同一块上。这允许目标操作,因为mongos可以将操作路由到只包含所需数据的分片。
范围分片的效率取决于所选的分片键。考虑不周的分片键可能导致数据分布不均匀,这可能会抵消分片的一些好处,或者可能导致性能瓶颈。

Tag Aware Sharding(3.4版本为Zones in Sharded Clusters)

在分片集群中,您可以标记分片键的特定范围,并将这些标签与分片或分片子集相关联。MongoDB将落入标记范围的读取和写入仅路由到分配了该标记的那些分片。另外,均衡器在均衡时检查标签,确保每一个分片只包含不违反它配置的标签范围的数据。
每一个标签都有一个包含上限和下限的范围。管理员可以在集群中每一个分片上(shard)分配一个或者更多的标签
Alt text

标记范围必须使用来自分片键的字段,并遵守复合分片键字段的顺序。
在选择shard key时,请仔细考虑将来使用标记感知分片的可能性,因为在分片collection后无法更改分片键。
最常见的是,标记感知分片用于改善跨越多个数据中心的分片簇的数据的局部性。