分片是将数据分配到不同机器的方法。
拥有很大数据量的数据库系统或者高吞吐量的应用会挑战单机的能力上限。比如,高的查询率会耗尽服务器的 CPU 能力,大于系统内存的工作集会对磁盘设备的 IO 造成压力。
MongoDB 通过分片支持水平扩容。水平扩容指将系统的数据集和负载分割到不同的服务器,通过增加服务器来提高系统的能力上限。虽然一台机器的性能可能不高,但通过使每台机器处理总体负载的子集,可以比一个高配置机器提供更高的性能。提高能力上限的部署只需要增加额外的服务器,这小于给单机增加高配置硬件的成本。与此而来的是更复杂的架构以及部署。
分片集群
分片集群由以下组件构成:
- 分片:每个分片包含了总数据的一部分
- mongos:查询路由器,给客户端应用(Mongo Driver)提供与集群交互的接口
- 配置服务器:储存集群的元数据和配置
MongoDB 分割 collection 级别的数据,将其分配到集群的分片中。
分片键
MongoDB 根据分片键分割 collection 中的文档。详情见 MongoDB 分片键。
Chunks
MongoDB 将数据分割到 chunks。每个 chunk 有一个基于分片键的左闭右开的区间。分片可以含有多个 chunks。
MongoDB 使用分片集群平衡器在分片集群中迁移 chunks。这个平衡器尝试让 chunks 在分片集群中均匀分布。
在 chunks 数目不同的分片间迁移 chunks:
移动限制
MongoDB 不能移动文件数超过 250000 或者超过 设置的 chunk 大小 / 平均文件大小
1.3 倍的 chunk。
对编程的影响
分片的操作限制[2]
- 要使用
mapReduce
和aggregrate
代替group
db.eval()
不向下兼容$where
不允许引用db
对象- 不支持
geoSearch
- 对分片的 collection 进行
update()
或者remove()
操作必须包含分片键或者_id
,否则会报错
其他
- 从 MongoDB 3.0 开始,如果一个索引包含分片键,索引可以覆盖查询,而在之前是不会覆盖的。如果只查询并只返回
_id
,那么也可以覆盖查询 - 什么情况下需要多个 Mongos 进行负载均衡?