MongoDB Sharded Cluster
Overview
mongodb 分片集群,是为了保证服务的扩展性与高可用,当数据量达到一定大小之后,可以很好的支持水平扩展,同时在服务运行时down一个分片对服务的影响很小。
可以理解为:Shard Cluster是一个高可用的mongodb服务,一个Shard Server就是一块硬盘,同时mongodb数据量增加的同时可以为它动态的增加硬盘。
Config Server Replica Set
配置服务器用来保存shard的元数据信息,本身是一个副本集。
Shard & ReplicaSet
Shard服务器保存数据,用副本集保证数据的高可用。
Router
路由器用来做mongodb服务的代理,客户端读写都连接它跟standalone模式一样。
Architecture
Deploy a Sharded Cluster
现在我们准备部署一个Shard Cluster,本次采用docker来部署一个Shard Cluster,三台主机是单独的docker,暂时没用集群的模式。
特别注意:以下搭建方式无权限控制,在公网上部署务必使用权限控制
- 环境: 主机:192.168.120.208、192.168.120.228、192.168.120.245 Config Server:部署在三台上形成一个副本集,端口27019 Shard:部署在三台上形成一个副本集,端口27018 Router:部署在208上,208机器好一点,多部署一个程序
本次本书由于没有那么多机器所以服务都部署在一起,官方建议分开部署,其中Router对性能的要求不高。
mkdir
首先创建需要的文件夹 根文件夹 /usr/local/mongo-cluster
- config // 配置服务器文件夹
-
- db // 数据
-
- configdb // 配置数据
- shard
- mongos 设置一下文件夹的访问权限 chmod 777 config|shard|mongos
Deploy Config Server Replica Set
// 进入config文件夹
cd config
docker run -d --name mongo-config -p 27019:27019 -v $(pwd)/db:/data/db -v $(pwd)/configdb:/data/configdb mongo --configsvr --replSet config --bind_ip 0.0.0.0
在三台机器上分别执行以上代码,部署采用shell命令的方式传入配置,主要说明一下参数的后面一段
mongo --configsvr --replSet config --bind_ip 0.0.0.0
- mongo 指定镜像名称真实环境应该包括tag(mango:4.2.5)
- --configsvr 之后的都是给 mongo 传参 --configsvr 表示此为配置服务器 --replSet config 副本集名称 config(副本集名称要与shard的副本集名称不一致),这里特别注意在下面初始化的时候 要跟此名称一致 --bind_ip 0.0.0.0 接收所有的请求,也可特定ip
三台都运行完成后,进入其中一个容器,初始化configserver
// 进入容器,为了使用mongo shell
docker exec -it mongo-config /bin/bash
// 连接
mongo --host localhost --port 27019
// 初始化
rs.initiate(
{
_id: "config",
configsvr: true,
members: [
{ _id : 0, host : "192.168.120.208:27019" },
{ _id : 1, host : "192.168.120.228:27019" },
{ _id : 2, host : "192.168.120.245:27019" }
]
}
)
Deploy Shard Replica Set
部署Shard Replica Set与Config Replica Set大同小异
// 进入目录
cd shard
// 运行程序
docker run -d --name mongo-shard -p 27018:27018 -v $(pwd)/db:/data/db -v $(pwd)/configdb:/data/configdb mongo --shardsvr --replSet shard --bind_ip 0.0.0.0
// 进入容器
docker exec -it mongo-shard /bin/bash
// 连接
mongo --host localhost --port 27018
// 初始化,初始化里面没有 configsvr: true 的配置
rs.initiate(
{
_id: "shard",
members: [
{ _id : 0, host : "192.168.120.208:27018" },
{ _id : 1, host : "192.168.120.228:27018" },
{ _id : 2, host : "192.168.120.245:27018" }
]
}
)
Deploy Router
// 进入目录
cd mongos
// 运行程序
docker run -d --name mongos -p 27017:27017 -v $(pwd)/db:/data/db -v $(pwd)/configdb:/data/configdb --entrypoint "mongos" mongo --configdb config/192.168.120.208:27019,192.168.120.228:27019,192.168.120.245:27019 --bind_ip 0.0.0.0
注意一下 --entrypoint "mongos"的参数,因为mongo镜像默认启动的是 mongod 的程序,但是router是mongos的程序,加上--entrypoint "mongos"告诉容器启动 mongos 的程序。
添加 Shard
// 进入容器
docker exec -it mongos /bin/bash
// 连接
mongo --host localhost --port 27017
// 添加一个Shard
sh.addShard("shard/192.168.120.208:27018,192.168.120.228:27018,192.168.120.245:27018")
// 数据库开启shard,返回一个json,ok:1 表示成功
sh.enableSharding("shardtest")
// 集合开启shard,并且指定shard key field
sh.shardCollection("shardtest.test", { "_id" : "hashed" } )
// 大功告成、测试一下写数据
use shardtest
for (i = 1; i <= 1000; i=i+1){
db.test.insert({‘index‘: i})
}
//查到数据,表示写入成功
db.test.findOne()
目前集群访问没有添加权限访问,如果是公网上需要特备注意 目前的mongo链接字符串为:mongodb://192.168.120.208:27017/shardtest
Extensions
// 查询shard的状态,包括balance的状态
sh.status()
// 查询集合的状态
db.xxx.stats()