一、mongodb分片集群
1.1 相关概念
-
Mongodb sharding cluster:分布式mongodb集群:将海量数据水平扩展,数据分表存储在sharding的各个节点
-
片键:每个块区间的标识,可以是任意字段或字段的组合
-
块:chunk是一个逻辑概念,而非物理实现,一个块中的文档在物理上并不连续存在于磁盘上或以任何形式聚集在一起。一个区间的数据称为一个数据块,默认大小是200MB,超过则生成新的数据块
1.2 分片常用场景
- 机器磁盘不够用
- 单个mongod已经不能满足写数据的性能需要
- 想将大量数据放在内存中提高性能
1.3 分片角色类型:
1)shard server:存储实际数据的分片。每个shard可以是一个mongod实例,也可以一个replica set。为了实现每个分片内存的自动故障转移,官方建议每个shard为一组replica set。
2)config server:将一个特定的collection存储在多个shard中,需要为该集合指定一个shard key。通过shard key决定记录属于哪个chunk。config server就是用来存储所有shard节点的配置信息、每个chunk的shard key范围、chunk在各个shard的分别情况、该集群中所有DB和collection的sharding配置信息。
3)route process:前端路由,控制客户端的写入分配到哪个shard
1.4 分片集群搭建
1)启动shard server
## 创建数据目录
mkdir -p /data/mongodb/shard/s0
mkdir -p /data/mongodb/shard/s1
## 创建日志目录
mkdir -p /data/mongodb/shard/log
## 启动shard server实例1
mongod --shardsvr --port 20000 --dbpath /data/mongodb/shard/s0 --fork --logpath /data/mongodb/shard/log/s0.log --directoryperdb
## 启动shard server实例2
mongod --shardsvr --port 20001 --dbpath /data/mongodb/shard/s1 --fork --logpath /data/mongodb/shard/log/s1.log --directoryperdb
2)启动config server
## 创建数据目录
mkdir -p /data/mongodb/shard/config
## 启动config server实例
mongod --configsvr --port 30000 --dbpath /data/mongodb/shard/config --fork --logpath /data/mongodb/shard/log/config.log --directoryperdb
3)启动route process
##启动route server实例
##--chunkSize默认200MB
mongos --port 40000 --configdb localhost:30000 --fork --logpath /data/mongodb/shard/log/route.log --chunkSize 10
4)配置sharding
##登录到mongos实例上,添加shard节点
##登录
mongo localhost:4000/admin
// 添加shard1
db.runCommand({addshard:"localhost:20000"})
// 添加shard2
db.runCommand({addshard:"localhost:20001"})
// 设置分片存储的数据
db.runCommand({enablesharding:"test"})
// 设置分片的集合名称,且必须制定shard key,系统会自动创建索引
db.runCommand({shardcollection:"test.user",key:{_id:1}})
5)观察sharding是否正常
db.users.stats()
// 列出所有的shard server
db.runCommand({listhards:1})
// 查看sharding信息
printShardingStatus()
// 判断是否是sharding
db.runCommand({isdbgrid:1})
// 对现有的表进行sharding
use admin
db.runCommand({shardcollection:"test.test",key:{_id:1}})
二、新增shard server
启动一个新shard server
##创建数据目录
mkdir -p /data/mongodb/shard/s2
##启动新实例进程
mongod --shardsvr --port 20002 --dbpath /data/mongodb/shard/s2 --fork --logpath /data/mongodb/shard/log/s2.log --directoryperdb
##配置新分片
mongo localhost:4000/admin
//添加分片
db.runCommand({addshard:"localhost:20002"})
//查看分片状态
printShardingStatus()
三、删除分片
// 移除shard server
use admin
db.runCommand({"removeshard":"localhost:20002"})
四、replica sets + sharding高可用架构
- shard:使用副本集,确保每个数据节点都具有备份、自动容错转移、自动恢复能力
- config:使用3个配置服务器,确保元数据完整性
- route:使用3个路由进程,实现负载平衡,提高客户端接入性能
1)创建数据目录(分别在三台机器上执行)
mkdir -p /data/mongodb/shard_data/{s1,s2,s3}
mkdir -p /data/mongodb/shard_config/
mkdir -p /data/mongodb/log
2)启动服务(分别在三台机器上执行)
mongod --shardsvr --replSet shard1 --port 27017 --dbpath /data/mongodb/shard_data/s1 --logpath /data/mongodb/log/shard.log --logappend --fork
3)配置config server(三台机器上执行)
mongod --configsvr --dbpath /data/mongodb/shard/config --port 20000 --logpath /data/mongodb/shard/config.log --logappend --fork
4)配置route process(三台机器上执行)
mongos --configdb 172.16.0.105:20000,172.16.0.104:20000,172.16.0.103:20000 --port 30000 --chunkSize 10 --logpath /data/mongodb/log --logappend --fork
5)配置shard cluster
##登录mongos
// 配置
use admin
db.runCommand({addshard:"shard1/172.16.0.105:27017,172.16.0.104:27017,172.16.0.103:27017"})
db.runCommand({addshard:"shard2/172.16.0.105:28017,172.16.0.104:28017,172.16.0.103:28017"})
// 激活数据库及集合分片
db.runCommand({enablesharding:"test"})
db.runCommand({shardcollection:"test.user",key:{_id:1}})
// 查看集合信息
db.user.stats
五、分片管理
// 判断是否是分片集群
db.runCommand({isdbgrid:1})
// 列出所有分片信息
db.runCommand({listshards:1})
// 查看分片配置信息
db.printShardingStatus()
sh.status()
// 删除分片节点
sh.getBalancerState()
db.runCommand({removeShard:"shard2"})
分片集群的balance操作
// 查看balance状态
sh.getBalancerState()
// 查看数据是是否正在迁移
sh.isBalancerRunning()
// 开启balance
sh.getBalancerState(true)
// 关闭balance
sh.stopBalancer()
// 关闭某集合的balance
sh.disableBalancing("db.collection")
// 修改balance窗口时间
db.settings.update({_id:"balancer"},{$set:{activeWindow:{start:"00:00",stop:"3:00"}}},true)
// 禁用分片的自动平衡
use config
db.settings.update({_id:"balancer"},{$set:{stopped:true}},true)