集群技术,可以满足MongoDB的数据量大量增长的需求。当MongoDB存储海量数据时,一台机器不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能够存储和处理更多的数据。
一:mongos
数据路由,和客户端打交道的模块。增删改查都会找config server,config server返回要操作的分片集群。
二:config server
管理shard集群的节点信息,配置信息,对shard数据的读取方式配置,本身虽然也是副本集,但是不存储数据。
三:shard
一个shard就是一个副本集,存储数据,存储数据以chunk为单位进行存,chunk大小默认64M
1:chunk
shard存储数据的基本单位。默认大小64M,超出该大小,就会进行裂变(变成两个等大小的chunk),当一个shard裂变产生一定次数,整个shard就会产生不平衡(有的shardchunk很多,有的chunk很少,甚至没有),此时就会进行平衡处理(分片:根据分片键的配置,chunk转移到chunk少的shard集群上)
2:shard key分片键
分片键指的是表中的一个字段,作为分片的依据(即什么时候分片)以及存储依据(新的数据存储在哪个分片),该字段必须在集合每条数据中都存在,该字段必须是索引字段。以集合为单位
3:分片策略
自增片键:
一个自增的片键对写入和数据分布不是很好,只有达到某个阈值才会写入到别的分片。但是查询效率高。
随机片键:
丢数据均匀分布效果很好,对查询效果不是很好,可能会在更多分片集群上查询。
hash片键:
MongoDB使用基于范围分片 与 hash分片
四:配置流程
a:配置副本集rs1,rs2,rs3,rs1作为config server,rs2,rs3作为分片(rs1与rs2,rs3文件配置有所差别)
b:启动一个普通的mongo作为router,增加mongos配置文件,启动mongos
c:启动副本集(rs1,2,3)
d:登录mongos,配置分片集群
1:启动shard1
配置文件如下,其余参考副本集启动
# 每个配置文件都要配置
storage:
dbPath: /data/db # 容器里的路径,并非挂载路径
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /data/log/mongodb.log # 容器里的路径,并非挂载路径
processManagement:
timeZoneInfo: /usr/share/zoneinfo
net:
port: 27017
bindIp: 0.0.0.0
# 复制集的名字
replication:
replSetName: rs2
# 分片集群必须要的属性
sharding:
clusterRole: shardsvr # 注意该值,与config server有所不同
2:启动shard2
同上
3:启动config副本集
配置文件如下,其余参考副本集启动
# 每个配置文件都要配置
storage:
dbPath: /data/db # 容器里的路径,并非挂载路径
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /data/log/mongodb.log # 容器里的路径,并非挂载路径
processManagement:
timeZoneInfo: /usr/share/zoneinfo
net:
port: 27017
bindIp: 0.0.0.0
# 复制集的名字
replication:
replSetName: rs2
# 分片集群必须要的属性
sharding:
clusterRole: configsvr
4:启动router(mongos)
1):创建配置文件(用于后面进入容器启动mongos服务)
systemLog:
destination: file
logAppend: true
path: /data/log/router.log
processManagement:
timeZoneInfo: /usr/share/zoneinfo
net:
port: 28018 # router端口,与mongo共存
bindIp: 0.0.0.0
sharding:
# 指定config副本集(包含所有节点)
configDB: rs1/10.0.4.17:27021,10.0.4.17:27022,10.0.4.17:27023
processManagement:
fork: true # 后台启动,不然使用mongos启动会卡在哪里
2):启动一个普通的mongo容器
docker run -itd --name router -p 27019:27017 --restart=always -v /docker_volume/router/data/db:/data/db -v /docker_volume/router/data/conf:/data/conf -v /docker_volume/router/data/log:/data/log mongo:4.4
3):启动mongos
# 进入容器
sudo docker exec -it router /bin/bash
# 启动mongos
mongos -f /data/conf/router.conf.orig
5:配置分片集
# 登录
mongo
# 切换数据库
use admin
# 添加切片集合rs2
db.runCommand({addShard:"rs2/10.0.4.17:27024,10.0.4.17:27025,10.0.4.17:27026"})
# 添加切片rs3
db.runCommand({addShard:"rs2/10.0.4.17:27027,10.0.4.17:27028,10.0.4.17:27029"})
6:开启数据库分片功能
sh.enableSharding("table_name")
7:对集合进行分片初始化
#用哈希算法进行分片
sh.shardCollection("MyTestDB.UserInfo" , {_id: 'hashed'})