1、MongoDB Sharding
- 基本共识
-
- 随机I/O转为顺序I/O;
- 步骤越少,查询越简单,性能越高。多做不如少做,少做不如不做;
- 大数据查询,分布式并行查询能力高;
- 三个注意事项
-
- 插入文档必须带上sharding key
- 不接受修改片键值(读取、删除、插入新文档)
- 如果文档中包含不同类型的值,排序规则,按照类型排序,同类型与大家期望相同;
- ChunkSize选择
-
- 默认64M;
- 与线上实际引用有关;
- Chunk的分裂与迁移非常消耗IO资源;
- 分裂时机(插入更新、更新文档时,读数据不会产生分裂)
- ChunkSize(数据预填充、浪费空间但是只在最初进行分裂,获取平滑的查改性能);
- 小的迁移速度块、分布均匀,但是数据均衡比较频繁、块分裂更频繁、路由节点消耗更多资源定位;
- 优点:块分裂小、路由定位块、避免虚假迁移;缺点:迁移时资源消耗比较大,抖动,数据分布不均匀;
- 通常100-200M,不同系统磁盘介质不同(前十几块为64M,数据量大时将会变成设置);Read10;centos,xfs
- MonogoDB支持修改ChunkSize;请测试确认后再进行调整;线上调整ChunkSize可能会导致灾难性I/O;调小可能会引起过多分裂;调大时可能在达到阈值才进行调整;
2、MongoDB Sharding存在问题及建议;
- 重要两点
-
- 优化均衡器时间
- mongodb很lazy,但是脑残;(均衡器执行器的执行过程可能很长,导致影响应用)
- Balacer设置(问题)
-
- count值布准确;
- 唯一值不唯一
- update更新的记录数出现问题;
- 0~7点进行均衡,mongos进行设置,使用config表进行设置,$set,$unset;
- Sharding key选择
-
- 指定sharding key;
- chunk分布不均衡时导致chunk迁移;
- 集群角色
-
- Mongos数据读写;
- config保存映射:key-》chunk,chunk-》node;
- 路由节点通过config server获取数据;
- 路由节点判定是否超过具体大小;
- 分片key路由到update进行操作;
- 按分片查询进行具体操作;
- 不同分片会分别进行操作,然后进行结果聚合;
- Sharding key选择
-
- 递增sharding key;数据文件挪动少(优势);数据文件递增所以insert都会会放在最后一个分片,成为热点;随着最后的扩大导致分裂;
- 随机sharding key;数据分布均匀(优势);大量的随机IO,磁盘压力比较大;
- 混合型sharing key,大范围递增key+随机分布的key;大方向但调增不断写入新的文件,尽量不要让写放在多个节点上;小方向随机分布保证数据均匀分布在分片上分摊写压力;
- Sharding key总结
-
- 单一Sharding key导致分布不均匀,无法充分利用分片性能;
- 使用复合Sharding key,符合Sharding key不可更改,并且在MapReduce性能消耗;
- count在chunk移动时计数偏大,务必减少chunk移动;
- Balance稳定性不够智能、稳定;
- Auto-Sharding key并不是很靠谱;
3、MongoDB库设计原则及实践
- 线上环境禁用Auto-Sharding;
- 开启库级分片;
- 特定库制定到固定分片上;
- Collection级别手动Sharding;
- MongoDB数据模型选择
-
- CAP原则
- CP,w=Replica Set,开启SlaveOK
- w=1,slaveOk开启;
- w=1,不开启slaveOK;
- 库设计
-
- 判断业务增长速度,什么量级,之后是什么增长速度;
- sharding分片数;
- memory>index+hot data;
- 索引和热门数据要大于内存;
- local库存放oplog,oplog需要消耗内存;
- 高插入高更新,并带有延时库需要设置较大oplog
- 如果没有延时可选用小一些oplog