分片
分片(Sharding)是一个将数据在多台机器之间进行分发的方法。MongoDB使用分片技术,来实现海量数据的存储和高性能的吞吐操作。
在单服务的条件下,海量数据存储和高性能的读写操作,会是一个极大的挑战。例如,高频率的查询,会耗尽CPU的资源。当操作的单位数据量大于系统内存容量时,将极大的考验硬盘的IO。s
有两种方式来满足系统的增长需要:垂直(vertical)和水平(horizontal)的扩容。
垂直扩容
可以提升单服务的处理能力,例如,使用更强大的CPU、增加更多的内存,或者增加更多的存储空间。有限的可用技术,限制了单台服务提升的空间。另外,云服务提供商,在硬件配置上都会提供一些固定的最高配置。因此,垂直扩容,也存储明显的瓶颈。
水平扩容
将数据和负载分摊到多台机器上,当需要时,可以通过增加服务机器的方式,来提高性能。一台机器的性能可能不高,单当多台机器作为一个整体,将会比单台高速度高性能的机器,拥有更好的效果。(Horizontal Scaling involves dividing the system dataset and load over multiple servers, adding additional servers to increase capacity as required.)要增大服务器的容量时,只需要增加额外的机器即可。在成本上,整体的费用也会低于单台顶配高性能机器。其中需要权衡的只是,生产环境部署的复杂性和维护的成本。
MongoDB使用sharding来支持水平扩容。
分片集群(Sharded Cluster)
MongoDB分片集群由以下部分内容组成:
- shard: 每一个分包含了整个数据集的一部分。每一个分片都可以部署为一个复制集群(replica set)(3.4以后,shard必须部署为replica set)
- mongos:mongos实际是一个查询的路由,提供客户端与分片集群的通信接口
- config servers: Config servers存储元数据和集群的配置信息。Mongo3.4,配置服务必须部署成replica set(CSRS)
下图描述了分片集群的交互关系:
MongoDB在集合纬度进行数据分片,将集合的数据在分片之间进行分发。
Shard Keys
为了分发集合中文档数据,MongoDB使用shard key来进行分区。shard key由一个或多个不会变化,且所有文档中都存在的字段。
在进行分片时,可以选择字段作为shard key。一旦选择之后,就无法修改。一个集合,只能拥有一个shard key。参见:Shard Key Specification。
在一个不为空的集合上使用分片处理时,集合必须先存在以Shard key开头的索引。集合为空,并且索引不存在时,创建shard key则会自动的创建索引。参见:Shard Key Indexes
Shard Key将决定分片的性能、效率(efficiency)和可扩展性(scalability)。不合适的shard key可能成为拥有最好配置和基础架构的集群的瓶颈(原文:A cluster with the best possible hardware and infrastructure can be bottlenecked by choice of shard key)。选择不同的shard key和其对应的index,也决定了可以使用的分片策略。
阅读shard key来获取更多信息。
块(Chunks)
MongoDB将分区后的数据存储在chunks中。每一个Chunk对应了基于shard key值的包含最小值、不包含最大值的闭开区间。
MongoDB使用分片集群均衡器(sharded cluster balancer)来在分片集群之间移动Chunks。Balancer试图在整个分片集群之间实现块的均匀分布。
参考Data Partitioning with Chunks。
分片的优势(Advantages of Sharding)
Reads / Writes
MongoDB将在分片集群之间分发读写的负荷,允许每一个分片处理集群子集的操作。读写操作都可以通过增加分片的方式来水平扩展。
查询时,如果条件中包含分片键或组合分片键前面的部分,mongos
可以直接的定位到指定的分片或分片集合。能定位的操作(targeted operations)对比广播式查询,通常会更加高效。
存储能力
分片功能将数据分布在集群的每个分片节点上,每个节点将包含整个数据的一部分。增加分片的数量将增加整个集群的存储量。
高可用
分片集群,在部分分片服务不可用时,也可以提供部分的读写操作功能。单个分片服务down机时,其它的可用分片还可以正常的提供数据的读写服务。
从MongoDB3.2开始,你可以将配置服务以replica sets方式进行部署。