一 MongoDB分片介绍
1.1 分片
Mongodb另外一种集群,就是分片技术,能够知足MongoDB数据量大量增加的需求。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,可经过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。即经过分片进行水平扩展。
延伸:
复制与分片的区别:复制时让多台服务器都拥有一样的数据副本,每一台服务器都是其余服务器的镜像,而每个分片都和其余分片拥有不一样的数据子集。
1.2 为何使用分片
- 复制全部的写入操做到主节点
- 延迟的敏感数据会在主节点查询
- 单个副本集限制在12个节点
- 当请求量巨大时会出现内存不足。
- 本地磁盘不足
- 垂直扩展价格昂贵
1.3 分片的优点
分片为应对高吞吐量与大数据量提够了方法:
- 使用分片减小了每一个分片须要处理的请求数:经过水平扩展,群集能够提升本身的存储容量。好比,当插入一条数据时,应用只须要访问存储这条数据的分片。
- 使用分片减小了每一个分片存储的数据:分片的优点在于提供相似线性增加的架构,提升数据可用性,提升大型数据库查询服务器的性能。当MongoDB单点数据库服务器存储成为瓶颈、单点数据库服务器的性能成为瓶颈或须要部署大型应用以充分利用内存时,可使用分片技术。
二 MongoDB分片架构
2.1 主要组件
Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障。
Config Server:mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
Query Routers:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用能够透明使用。
数据划分
MongoDB的数据划分,是以集合级别为标准。分片经过shard key来划分集合数据。
2.2 shard key
在集合中分发文档,MongoDB使用shard key对进行进行分片。shard key既能够是集合的每一个文档的索引字段也能够是集合中每一个文档都有的组合索引字段。
MongoDB将shard keys值按照块(chunks)划分,而且均匀的将这些chunks分配到各个分片上。MongoDB使用基于范围划分或基于散列划分来划分chunks的。
注意:肯定shard key时须要谨慎,以确保集群性能和效率。分片后不能更改shard key,也不能取消分片。
2.3 分片集和非分片集
数据库能够混合使用分片和非分片集合。分片集合在集群中的分片上进行分区和分布,非分片集合存储在主分片上,每一个数据库都有本身的主分片。
2.4 分片集链接
可使用与链接到单个mongos相同的方式链接分片集mongod,如经过mongoshell或MongoDB 驱动程序。但必须链接到mongos路由器,才能与分片集群中的任何集合进行交互。这包括分片和非分片集合,客户端永远不该链接到单个分片以执行读取或写入操做。
三 分片策略
3.1 基于范围划分
MongoDB经过shard key值将数据集划分到不一样的范围就称为基于范围划分。
对于数值型的shard key:能够虚构一条从负无穷到正无穷的直线(理解为x轴),每一个shard key 值都落在这条直线的某个点上,而后MongoDB把这条线划分为许多更小的没有重复的范围成为块(chunks),一个chunk就是某些最小值到最大值的范围。
3.2 基于散列划分
MongoDB计算每一个字段的hash值,而后用这些hash值创建chunks。基于散列值的数据分布有助于更均匀的数据分布,尤为是在shard key单调变化的数据集中。
可是,散列分布意味着对shard key的基于范围的查询不太可能以单个分片为目标,从而致使更多群集范围的广播操做。
基于范围和基于散列划分的性能比较:
基于范围划分对于范围查询比较高效。假设在shard key上进行范围查询,查询路由很容易可以知道哪些块与这个范围重叠,而后把相关查询按照这个路线发送到仅仅包含这些chunks的分片。
可是基于范围划分很容易致使数据不均匀分布,这样会削弱分片集群的功能。例如当shard key是个成直线上升的字段,如时间。那么,全部在给定时间范围内的请求都会映射到相同的chunk,也就是相同的分片上。这种状况下,小部分的分片将会承受大多数的请求,那么系统总体扩展并不理想。
相反的,基于散列划分是以牺牲高效范围查询为代价,它可以均匀的分布数据,散列值可以保证数据随机分布到各个分片上。
3.3 自定义标签划分
MongoDB支持经过自定义标签标记分片的方式直接平衡数据分布策略,能够建立标签而且将它们与shard key值的范围进行关联,而后分配这些标签到各个分片上,最终平衡器转移带有标签标记的数据到对应的分片上,确保集群老是按标签描述的那样进行数据分布。标签是控制平衡器行为及集群中块分布的主要方法。
四 数据均衡
新加入的数据及服务器都会致使集群数据分布不平衡,MongoDB采用两种方式确保数据分布的平衡:
4.1 拆分
拆分是一个后台进程,防止块变得太大。当一个块增加到指定块大小的时候,拆分进程就会块一分为二,整个拆分过程是高效的。不会涉及到数据的迁移等操做。
4.2 平衡
平衡器是一个后台进程,管理块的迁移。平衡器可以运行在集群任何的mongd实例上。当集群中数据分布不均匀时,平衡器就会将某个分片中比较多的块迁移到拥有块较少的分片中,直到数据分片平衡为止。
举个例子:若是集合users有100个块在分片1里,50个块在分片2中,那么平衡器就会将分片1中的块迁移到分片2中,直到维持平衡。
分片采用后台操做的方式管理着源分片和目标分片之间块的迁移。在迁移的过程当中,源分片中的块会将全部文档发送到目标分片中,而后目标分片会获取并应用这些变化。最后,更新配置服务器上关于块位置元数据。
4.3 从集群中增长和删除分片
添加新分片到集群中会产生数据不平衡,由于新分片中没有块,当MongoDB开始迁移数据到新分片中时,等到数据分片平衡须要必定时间。
当删除一个分片时,平衡器将会把分片中全部块迁移到另外一个分片中,在完成这些迁移并更新元数据后,才可安全的删除分片了。
更多分片参考官方:https://docs.mongodb.com/manual/sharding/#sharding-strategy
相关参考:
https://blog.51cto.com/13643643/2148825
https://www.cnblogs.com/Jtianlin/p/5128977.html
https://www.jianshu.com/p/cb55bb333e2d