MongoDB官网有份分片集群架构图,如下图:
图中有三个主要组件:
- Router(mongos): 查询路由
数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求转发到对应的shard服务器上。在生产环境通常有多个mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。 - Config Server: 配置服务器
存储所有数据库元信息(路由、分片)的配置。 - Shard: 分片服务器
存储了一个集合部分数据的MongoDB实例,每个分片是单独的mongodb服务或者副本集。在生产环境中,所有的分片都应该是副本集。
mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,config配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从config server加载配置信息,以后如果配置服务器信息变化会通知到所有的mongos更新自己的状态,这样 mongos 就能继续准确路由,在生产环境通常有多个config server配置服务器,因为它存储了分片路由的元数据,防止数据丢失。
下面我用单台服务器模拟安装MongoDB分片集群。
首先需要编写docker-compose.yaml件,这里我已经准备好了一个(见文末)。
a、文末配置文件不是按照官方规范双路由、双分片(副本集)和单配置(副本集)来写的,你如果需要按照规范来,将里边的单分片调整成双分片即可。
b、文末配置文件是完整文件,安装过程需要使用2次,第一次使用UP命令时候,需要将里边的key.file相关和授权参数--auth去掉。
下面开始执行up命令安装:
docker-compose up -d
安装结束之后,ps命令查看结果:
docker exec -it mongors1n1 bash -c "echo 'rs.initiate({_id : \"mongors1\", members: [{ _id : 0, host : \"mongors1n1\" },{ _id : 1, host : \"mongors1n2\" },{ _id : 2, host : \"mongors1n3\" }]})' | mongo"
初始化配置服务器:
docker exec -it mongors1n1 bash -c "echo 'rs.status()' | mongo"
查看配置服务器状态:
docker exec -it mongors1n1 bash -c "echo 'rs.status()' | mongo"
初始化分片服务器:
docker exec -it mongors1n1 bash -c "echo 'rs.status()' | mongo"
查看分片服务器状态:
docker exec -it mongors1n1 bash -c "echo 'rs.status()' | mongo"
初始化分片服:
docker exec -it mongos1 bash
查看分片服状态:
mongo
创建数据库mydb:
# docker container shell
mongo
使mydb库支持分片:
# docker container shell
mongo
创建集合user:
# docker container shell
mongo
使集合user支持分片,片键是age属性:
# mongo shell
quit();
# docker container shell
exit
进入路由mongos1镜像服务器,并使用mongo命令连接登录数据库:
# mongo shell
quit();
# docker container shell
exit
# docker container shell
mongo
使用admin库,并新建super-user用户,它属于root用户:
#mongo shell
use admin
db.createUser({user:'super-user',pwd:'super123', roles:[{role:'root',db:'admin'}]});
show dbs;
# mongo shell
quit();
# docker container shell
exit
用MongoDB客户端工具测试链接,成功的。
下面来设置启用权限验证。
首先生成key.file.
openssl rand -base64 741 > key.file
chmod 600 key.file
chown 999 key.file
注意: 保证key.file 权限为 999。
停止和删除容器、网络、镜像。
docker-compose down
修改docker-compose.yaml配置,将key.file挂载docker容器里面,启动命令指定key.file,并启动命令增加需要认证参数--auth。
重新启动服务。
docker-compose ps
docker-compose ps
进入数据库
mongo 127.0.0.1:27017/mydb -u test -p test123
提示需要授权,目的达到了,现在给mydb库增加权限。
# mongo shell
use admin
db.auth("super-user", "super123");
use mydb;
db.createUser({user:'test',pwd:'test123',roles:[{role:'read',db:'mydb'},{role:'readWrite',db:'mydb'}]});
用户添加成功,然后我们退出来重试下:
# docker container shell
mongo 127.0.0.1:27017/mydb -u test -p test123
OK,目的达到了,成功授权连接。
到此,用docker-compose安装配置MongoDB集群完成。
这个单台服务器实现的集群方式理解了,对于之后的多台配置相对来说就简单了。
最后,附上完整的docker-compose.yaml配置。
第一次安装时候,需要将里边的key.file相关和授权参数--auth去掉。
version: "2"
services:
mongorsn1:
container_name: mongors1n1
image: mongo:4.2
restart: always
command: mongod --shardsvr --keyFile /etc/key.file --replSet mongors1 --dbpath /data/db --port 27017 --bind_ip_all --auth
ports:
- "27117:27017"
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/rs1n1/data/db:/data/db
- /data/mongodb/cluster/rs1n1/data/configdb:/data/configdb
- /data/mongodb/cluster/rs1n1/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
mongors1n2:
container_name: mongors1n2
image: mongo:4.2
restart: always
command: mongod --shardsvr --keyFile /etc/key.file --replSet mongors1 --dbpath /data/db --port 27017 --bind_ip_all --auth
ports:
- "27217:27017"
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/rs1n2/data/db:/data/db
- /data/mongodb/cluster/rs1n2/data/configdb:/data/configdb
- /data/mongodb/cluster/rs1n2/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
mongors1n3:
container_name: mongors1n3
image: mongo:4.2
restart: always
command: mongod --shardsvr --keyFile /etc/key.file --replSet mongors1 --dbpath /data/db --port 27017 --bind_ip_all --auth
ports:
- "27317:27017"
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/rs1n3/data/db:/data/db
- /data/mongodb/cluster/rs1n3/data/configdb:/data/configdb
- /data/mongodb/cluster/rs1n3/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
mongocfg1:
container_name: mongocfg1
image: mongo:4.2
restart: always
command: mongod --configsvr --keyFile /etc/key.file --replSet mongors1conf --dbpath /data/db --port 27017 --bind_ip_all --auth
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/cfg1/data/db:/data/db
- /data/mongodb/cluster/cfg1/data/configdb:/data/configdb
- /data/mongodb/cluster/cfg1/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
mongocfg2:
container_name: mongocfg2
image: mongo:4.2
restart: always
command: mongod --configsvr --keyFile /etc/key.file --replSet mongors1conf --dbpath /data/db --port 27017 --bind_ip_all --auth
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/cfg2/data/db:/data/db
- /data/mongodb/cluster/cfg2/data/configdb:/data/configdb
- /data/mongodb/cluster/cfg2/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
mongocfg3:
container_name: mongocfg3
image: mongo:4.2
restart: always
command: mongod --configsvr --keyFile /etc/key.file --replSet mongors1conf --dbpath /data/db --port 27017 --bind_ip_all --auth
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/cfg3/data/db:/data/db
- /data/mongodb/cluster/cfg3/data/configdb:/data/configdb
- /data/mongodb/cluster/cfg3/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
mongos1:
container_name: mongos1
image: mongo:4.2
restart: always
depends_on:
- mongocfg1
- mongocfg2
- mongocfg3
command: mongos --configdb mongors1conf/mongocfg1:27017,mongocfg2:27017,mongocfg3:27017 --keyFile /etc/key.file --port 27017 --bind_ip_all
ports:
- "27417:27017"
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/mongos1/data/db:/data/db
- /data/mongodb/cluster/mongos1/data/configdb:/data/configdb
- /data/mongodb/cluster/mongos1/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
mongos2:
container_name: mongos2
image: mongo:4.2
restart: always
depends_on:
- mongocfg1
- mongocfg2
- mongocfg3
command: mongos --configdb mongors1conf/mongocfg1:27017,mongocfg2:27017,mongocfg3:27017 --keyFile /etc/key.file --port 27017 --bind_ip_all
ports:
- "27517:27017"
expose:
- "27017"
networks:
- mongo
volumes:
- /data/mongodb/cluster/mongos2/data/db:/data/db
- /data/mongodb/cluster/mongos2/data/configdb:/data/configdb
- /data/mongodb/cluster/mongos2/data/backup:/data/backup
- /data/mongodb/cluster/key.file:/etc/key.file
networks:
mongo:
driver: bridge