mongo 分布式 docker版示例
本章介绍的mongo指令,主要是管理员用的。包括一些分布式的内容。对于开发者来说,不管副本集还是分片,都是透明的,无需关注。
副本集replica set
## 创建一个副本集,端口10000,名字myrs,数据存放./data
mongod --port 10000 --dbpath ./data --replSet myrs
# 访问这个实例,并初始化
rs.initiate()
# 添加其他实例到副本集
rs.add($HOST_NAME:$PORT)
# 查看副本集信息
rs.conf()
分片
当单台服务器满足不了mongodb的性能要求(内存、磁盘读写)时,我们考虑将数据分布到多台服务器。
当客户端访问我们的门户时,通过算法,找到存储数据的服务器;通过路由访问到这个分片,返回数据。
一个分片集群需要具备以下角色:
- Shard:分片,存储整个库中的数据,由算法决定某条数据该分配到哪个分片。
- Config Server:配置服务器,储存所有分片的元数据,我使用的4.0版本,要求配置服务器必须是副本集,并建议有3个实例。
- mongos(Router):路由,所有分片的访问入口,主要起到路由、分发、合并的作用。对开发来说,这层是可见的。路由需要指定配置服务器、并维护分片。
docker建立一个简单分片集群
因为我本机没装mongodb,所以通过建几个容器来实现一个分片集群。如果使用多台物理机实现集群,道理也是一样的。
mongodb镜像准备 docker pull mongo:4.0
mongos镜像,自己做一个Dockerfile
FROM mongo:4.0
MAINTAINER it_laowu
EXPOSE 27017
ENTRYPOINT ["usr/bin/mongos"]
编译 Docker build -t it_laowu/mongos:4.0 .
开始执行命令:
# docker network
docker network create -d bridge --subnet 172.18.0.0/24 --gateway 172.18.0.1 my_net
# 三个shard,必须加上 --shardsvr ,否则mongos拒绝处理
sudo docker run -d --network my_net --name sh1 mongo:4.0 --shardsvr --port 27017 &&\
sudo docker run -d --network my_net --name sh2 mongo:4.0 --shardsvr --port 27017 &&\
sudo docker run -d --network my_net --name sh3 mongo:4.0 --shardsvr --port 27017
# 三个Config,需要做成副本集,使用configsvr参数可能会改变port,所以又指定了一次
sudo docker run -d --network my_net --name mc1 mongo:4.0 --replSet mcrs --configsvr --port 27017 &&\
sudo docker run -d --network my_net --name mc2 mongo:4.0 --replSet mcrs --configsvr --port 27017 &&\
sudo docker run -d --network my_net --name mc3 mongo:4.0 --replSet mcrs --configsvr --port 27017
## 进入config容器
docker exec -it mc1 mongo
## 在容器内操作
rs.initiate()
rs.add("mc2:27017")
rs.add("mc3:27017")
rs.conf() #配置
rs.status() #状态
# 一个mongos,这里千万注意两点
## 3.4版本以后--configdb参数必须是个副本集,否则报错
## mc地址不能使用localhost或127.0.0.1;否则shard无法访问(云)
sudo docker run -d --network my_net --name ms1 it_laowu/mongos:4.0 --configdb mcrs/mc1:27017,mc2:27017,mc3:27017 --bind_ip_all --port 27017
## 登陆mongos;注册shard
docker exec -it ms1 mongo admin
sh.status()
sh.addShard("sh1:27017")
sh.addShard("sh2:27017")
sh.addShard("sh3:27017")
# 添加副本集(云)
# sh.addShard("mcrs/mc1:27017,mc2:27017,mc3:27017")
分片操作
开库、建表
# 登陆mongos
docker exec -it ms1 mongo admin
# 开库
sh.enableSharding("shardtest")
sh.status()
效果见下图:
# 建表,片键studentId,根据这个键和算法,决定某条记录放到哪个分片服务器
## 可能是因为shard没有shardsvr参数,也可能config必须是多个节点的副本,反正加上后,不报错了。
sh.shardCollection("shardtest.students",{
"studentId":1})
sh.status()
效果见下两图:
# 插入数据
db.students.insert([{
studentId:1},{
studentId:2},{
studentId:3},{
studentId:4},{
studentId:5}])
# 检查数据后,发现全部数据都在shard0000,并没有平均分布。。。
sh.status()
均衡器
# 检查均衡器是否可用,可以
sh.getBalancerState()
# 检查均衡器是否运行,没有;事实上这个属性只有真正起作用时才会true,均衡完利马false
sh.isBalancerRunning()
# 调整
use config # 切换数据库
# 设置平衡器运行时间段
db.settings.update({
_id:"balancer"},{
$set:{
activeWindow:{
start:"06:00",stop:"08:00"}}})
##强制分片
sh.splitAt("shardtest.students",{
studentId:500})
## 貌似没用,新的chunk还是都是在第一个shard上。。。
use shardtest
for(i=0;i<1000;i++){
db.students.insert({
studentId:i,name:'it_laowu'}) }
## 换一种均衡策略hashed,起效了,分布很均匀
sh.shardCollection("shardtest.students2",{
studentId:"hashed"})
use shardtest
for(i=0;i<1000;i++){
db.students2.insert({
studentId:i,name:'it_laowu'}) }
hashed策略,效果如下图,三个shard各有2个chunk:
备份
## 备份标准指令
mongodump -h dbhost -d dbname -o dbdirectory
## 例子
mongodump -d test -o ./aaa
## 恢复标准指令
mongorestore -h <hostname><:port> -d dbname <path>
## 例子
mongorestore ./aaa
监控
## 查看mongo的运行状态、性能
mongostat
## 查看细化到table的读写数据
mongotop