分片,就是提供水平扩展能力。。应对海量数据。
=========================
搭建分片集群
三种节点:
- mongos (s for sharding)
- 消息路由
- mongos 需要读取config server的metadata。。所以启动参数是:
- mongos --configdb <replset_name/config_server:port>
- mongos和config Server,通过mongos的启动参数,绑定在一起
- 其他参数,主要是port、logpath、logappend等(注意不需要dbpath)
- mongos --configdb <replset_name/config_server:port>
- config server
- 存放metadata
- mongod --configSvr
- 其他配置选项,跟mongod复制集一致。
- 特别注意:mongodb 3.6.3版本中,config Server 已经不支持单点实例模式了,必须以复制集模式运行。
- Shard Server
- 用于数据存储
- mongod --shardSvr
- 连接mongos,通过add shard,将mongos和shard Server绑定
- 客户端Driver 需要连接mongos,来读写数据。。。方式和mongod一致
- use admin,
- 执行db.runCommand({addshard:"[replset_name/]shardserver:port"[, name:"shard_name"]})
- 如果不指定name,将生成默认的shardXXX的名字。
- Add Shards操作,可以理解为向mongos上挂载分区。。因为mongos并不存储数据,他的数据需要存储在shard Server上
- 这一步,相当于绑定mongos 和shard Server
执行db.runCommand,需要首先use admin
注意:db.runCommand已经可以使用sh.XX来代替了
config server 和shard Server,都是普通的mongod 复制集,加上指定的参数(--configsvr/--shardsvr)
mongos 不需要指定dbpath。。其他配置和mongod类似。
====================================================
基于集合进行分片
1)首先,要把集合所在数据库 enable sharding
db.runCommand({enablesharding: "db_name"});
注意:对数据库enable sharding的过程,可能是在相关的shard server上创建相应数据库等操作,
所以,enable sharding之后,使用add shard挂载进来的shard server,将无法参与该数据库的分片
2)对集合进行分片
use admin
db.runCommand({shardcollection:"以数据库名开头的集合namespace全限定名", key:{字段索引定义方式}})
shard key字段上,必须加索引
此处key的值,是相应索引的定义方式。。
比如hash索引定义方式是field_name:"hashed",则此处key的定义方式是key:{field_name:"hashed"}
==========================
mongodb分片键(shard_key)、chunks
查看集合状态:
db.coll_name.stats()
查看分片状态:
db.printShardingStatus()
什么是chunk
- mongodb分片后,存储数据的单元块
===================================
1)chunk会在config server上保存metadata。
chunk拆分和均衡移动,都需要更新相关的metadata
chunk,由拆分(splitting)到均衡(balancing)过程
1)mongos 根据shard key,将数据打到某个shard Server上
chunk达到阀值,发生chunk拆分
2)由于chunks数量不均衡,
balancer(均衡器)
在周期性检查
中会触发
移动chunk的操作
最终,balancer会将所有chunk,均衡的移动到所有shard Server上。
====================================================
1)注意:是对shard key,使用【哈希索引】
2)hash shard key只能是一个字段
- 普通的shard key,可以是多个字段(类似复合索引)
3)原理:基于hash分片算法
- 每个shard key,最终换算成int类型的hash值(shard value)
- shard value 对当前shard Server count(总数),取模。值即要分片到的shard server编号(shard id)
4)hash索引是非空索引。。。即所有doc,相关字段非空
如何选择片键(shard key)
- shard key不能重复多。
- 对于单调递增、随机数字、随机字符串,可以添加hash索引来分片
- 对于存在server、time类型的数据(比如基于主机的日志),可以使用{server:1,time:1}这样的复合片键
============================
mongodb分片后的请求查询机制
1)Routed
2)Scatter Gather (分散、收集)----类似 Elasticsearch
3)Distributed Merge Sort
在shard中查询之后,进行排序(sort),然后在mongos中合并(merge)返回
==============================
mongodb手动分片
手动分片过程:
=======================================
分片常用部署场景
常用分布式应用,最少需要三台机器(虚机)
- 所有服务(复制集(shard server)、config server、 mongos),由三个节点构成集群。。并依次分布在三台机器上。
- shard server、config server以复制集的形式开启集群
- mongos则以每台机器上启动实例时,指定config server的形式,各自独立地启动服务
- 三个mongos实例并不直接联系
- 只能依靠外部的负载均衡机制,来保证将请求均衡的分布到三个mongos实例上。
假如有6台机器:
- 因为mongos、复制集的primary节点,承担的工作比较繁重,需要更多的资源
- 所以将mongos、复制集的primary节点分离各自独占一台机器。。
- mongos伴随一个复制集secondary节点。