引用geekdemo课程
分片集群和复制集不同,分片集群有路由,配置节点,并且对数据量增加,访问性能日渐降低,高并发,数据量大的场景有着显著的作用。而mongoos路由为应用程序提供集群的单一入口。根据请求转发到多个节点,并且把请求的返回进行合并后返回给应用端。
config1配置节点: 提供高可用,提供集群元数据(mongodb数据存储位置等)。shard表存储key范围等信息,通过对照表信息将信息加载到内存进行对比,从而才能得知请求应该发送到那个shard上。
mongodb:一个分片就是一个复制集,每一个分片对应的必须是一个复制集,分片和分片的数据是不重复的,每一个分片存储了一部分数据如下
- 分片集群特点
应用透明,无特殊处理,使用复制的代码可以无缝使用在分片中
数据自动均衡,mongodb会自动检测分片的分布情况
动态扩容,无需下线
提供三种分片方式:基于范围,基于hash,基于zone
基于范围
查询性能较好
hash
为了解决上面的热点写和写分布不均匀的情况,使用hash。按某个字段的hash,不连续的随机的写到各个不同的范围中的节点上。
zone
通过有效打标签的方式可以有效的把地域化的分片组织到当地的分片。
image-20210807175421800.png
合理配置分片集群
是否需要分片,需要多少分片,数据分布规则
选择需要分片的表,正确的片键,合适的负载均衡
足够的资源,CPU,RAM,存储
分片大小
关于数据:不超过2TB,保持2TB以内一个片
关于索引:常用索引必须容纳进内存
需要多少个分片
- 从存储看:
存储总量/单服务器容量=分片节点
- 从内存看:
热数据内存大小:mongodb默认用来做缓存的是%60的内存空间。48g内存,工作集100G数据,而真正用来做缓存的是%60为0.6.
热点数据和索引数据和除(内存总大小乘0.6)等于分片节点数
100G / (48G*0.6) = 2 ,只看内存的话,工作集就需要2个分片
- 从并发看:
0.7为额外开销
总的并发数除/(单台并发数乘以0.7)等于分片节点数
其他考虑:是否跨机房灾备等。
片键的选择
- 片键shard key:
文档中的一个或多个字段,组成一个核心数据分布的准则,需要选择一个键来作为分片
影响片键效率的因素:
取值基数(cardinality),取值分布,分散写,集中读,被尽可能多的业务场景用到,避免单调递增或递减的片键
取值基数(cardinality)
选择基数(值的范围)大的片键,基数决定的了片的大小。如果备选值有限,那么快就不能超过有限的值的范围,随数据增多块大小会越来越大。而这些太大的块会导致水平扩展困难,在负载中移动块将会非常困难
取值分布
选择分布均匀的片键。数据均衡是以块为单位的,而对于一些不均匀的片键会造成某些快的数据急剧增大,压力也随之增大。
定向
4个分片的集群,希望读某条特定的数据,如果用片键作为查询条件,mongos可以直接定位到具体的分片,如果不用片键,mongos需要把查询发到4个分片,等最后一个分片响应,mongdos才能响应应用端
以email作为例子
{
_id: ObjectID(),
user:123
time: Date(),
subject: "",
recipients: [],
body: "",
attachements: []
}
如上,最常见的使用\_id作为片键,\_id是16个字节无穷大的数值,基数是非常理想的,而id自增的,新写入的都会进入第一个分片或者最后一个分片,写入完成后在搬入到另一个分片节点,这样一个写入就变成了两个写入,这样一来写入就以热分片的方式固定在某一个区域。对于查询也是不友好的。这并不是一个好的片键。
hash作为片键相比较之上,把自增的去掉了,hash随机写,但是还是 有一个定向查询的问题,查询一次还是会到每个节点查询
用户user_id作为片键,如果基于用户id,定向查询是可以的,写分片也是ok的,但是基数不够大,一个用户的邮件是在一个块里面,短期内写入量少,但是如果使用时间太长,数据沉淀太多,使用一个id存储了大量的数据就变成了一个超级块,超级块的负载移动将会成后困难。
最佳实践:组合片键
用户id和时间,用户会导致基数不够大导致大块,而解决这个问题需要增加字段,userid加上time字段,综合起来就是一个比较理想的片键。
- 文档doc:
包含shard key的一行数据,存储的基本单位
- 块chunk:
包含n个文档,逻辑概念,通常是64Mb,集群在做均衡的时候以快为单位均衡
-
分片shard:
包含n个chunk ,一般为三个节点的复制集组成分片集群数据里的集合
- 集群cluster:包含n个分片
资源
mongos与config通常消耗较少的资源
资源消耗较大的是shard的服务器:
- 需要足以容纳热数据索引的内存
- 正确创建索引后CPU通常不会成为瓶颈,除非涉及到非常多的计算
- 磁盘使用SSD
足够的资源是必要的,当监控项使用率在60%以上则开始考虑扩展,因为扩展的需要均衡,均衡需要时间,如果资源即将耗尽,均衡也很低效