1.分片集群概述
MongoDB分片集群,英文名称为: Sharded Cluster
旨在通过横向扩展,来提高数据吞吐性能、增大数据存储量。
分片集群由三个组件:“mongos”, “config server”, “shard” 组成。
框架如下(图片来自mongodb官网):
- mongos:数据库请求路由。负责接收所有客户端应用程序的连接查询请求,并将请求路由到集群内部对应的分片上。"mongos"可以有1个或多个。
- config server: 配置服务,负责保存集群的元数据信息,比如集群的分片信息、用户信息。
MongoDB 3.4 版本以后,“config server” 必须是副本集! - shard: 分片存储。将数据分片存储在多个服务器上。
有点类似关系数据库"分区表"的概念,只不过分区表是将数据分散存储在多个文件中,而sharding将数据分散存储在多个服务器上。一个集群可以有一个或多个分片。
MongoDB 3.6以后,每个分片都必须是副本集!
2. 环境准备
- 操作系统:CentOS6.6
- MongoDB 版本: 3.6.11 (mongodb-linux-x86_64-rhel62-3.6.11.tgz)
- 主机规划:mongos (2个) + “config server” (1个,由3台主机组成的副本集) + 分片(2个分片,每个分片由3台主机组成副本集)
一共11台虚拟机:
主机序号 | IP地址 | 角色 |
1 | 192.168.6. 20 | mongos 1 |
2 | 192.168.6.21 | mongos 2 |
3 | 192.168.6.22 | config 1 |
4 | 192.168.6.23 | config 2 |
5 | 192.168.6.24 | config 3 |
6 | 192.168.6.25 | shard1-1 |
7 | 192.168.6.26 | shard1-2 |
8 | 192.168.6.27 | shard1-3 |
9 | 192.168.6.28 | shard2-1 |
10 | 192.168.6.29 | shard2-2 |
11 | 192.168.6.30 | shard2-3 |
3. 分片集群搭建步骤
分片集群各部分组件搭建顺序(程序启动顺序也是如此):
- “config server” -> 2. “shard” -> 3. “mongos”
3.1 搭建"config server"
"config server"由三台主机组成,每台主机上运行一个mongod进程,三台主机的mongod组成一个副本集。
3.1.1 配置"config server" mongod.conf
dbpath = /home/mongodb/data/db
logpath = /home/mongodb/app/mongodb-3.6/mongodb.log
port = 27017
bind_ip = 0.0.0.0
fork = true # run background
#nohttpinterface = true
replSet = rs-config
oplogSize = 2048 #2G
configsvr = true
#auth = true
#keyFile = /home/mongodb/app/mongodb-3.6/keyfile
三台主机的mongod.conf配置相同。
注意: 必须配置:“configsvr = true”
3.1.2 启动mongod
三台服务器上,依次启动mongod程序
mongod --config /home/mongodb/app/mongodb-3.6/bin/mongod.conf
3.1.3 初始化"config server"副本集
任选一个节点,执行初始化命令
rs.initiate(
{
"_id" : "rs-config",
"members" : [
{"_id" : 0, "host" : "192.168.6.22:27017"},
{"_id" : 1, "host" : "192.168.6.23:27017"},
{"_id" : 2, "host" : "192.168.6.24:27017"}
]
}
)
3.2 搭建 "shard"分片服务器
一共有2个分片,每个分片由3台mongod服务组成副本集。配置过程相同。
3.2.1 配置 “shard” mongod.conf
分片1配置(三个节点配置相同):
dbpath = /home/mongodb/data/db
logpath = /home/mongodb/app/mongodb-3.6/mongodb.log
port = 27017
bind_ip = 0.0.0.0
fork = true # run background
#nohttpinterface = true
replSet = rs-shard1
oplogSize = 2048 #2G
shardsvr = true
#auth = true
#keyFile = /home/mongodb/app/mongodb-3.6/keyfile
分片2配置(三个节点配置相同):
dbpath = /home/mongodb/data/db
logpath = /home/mongodb/app/mongodb-3.6/mongodb.log
port = 27017
bind_ip = 0.0.0.0
fork = true # run background
#nohttpinterface = true
replSet = rs-shard2
oplogSize = 2048 #2G
shardsvr = true
#auth = true
#keyFile = /home/mongodb/app/mongodb-3.6/keyfile
注:
(1) 分片1和分片2,除了副本集名称不同外,其它配置相同。
replSet = rs-shard1
replSet = rs-shard2
(2) 必须配置:“shardsvr = true”
3.2.2 启动mongod
依次启动两个分片的mongod程序
mongod --config /home/mongodb/app/mongodb-3.6/bin/mongod.conf
3.2.3 初始化shard副本集
分片1副本集初始化:任选分片内的一个节点,执行初始化命令
rs.initiate(
{
"_id" : "rs-shard1",
"members" : [
{"_id" : 0, "host" : "192.168.6.25:27017"},
{"_id" : 1, "host" : "192.168.6.26:27017"},
{"_id" : 2, "host" : "192.168.6.27:27017"}
]
}
)
分片2副本集初始化:连接"primary"主节点,执行初始化命令
rs.initiate(
{
"_id" : "rs-shard2",
"members" : [
{"_id" : 0, "host" : "192.168.6.28:27017"},
{"_id" : 1, "host" : "192.168.6.29:27017"},
{"_id" : 2, "host" : "192.168.6.30:27017"}
]
}
)
3.3 搭建"mongos"
mongos可以为1个,也可以为多个。
每个mongos配置相对独立,配置过程及参数相同。
3.3.1 配置 “mongos.conf”
logpath = /home/mongodb/app/mongodb-3.6/mongos.log
logappend = true
bind_ip = 0.0.0.0
port = 27017
fork = true
#keyFile = /mongos/autokey
configdb = rs-config/192.168.6.22:27017,192.168.6.23:27017,192.168.6.24:27017
# max connections
maxConns=200
3.3.2 启动"mongos"
mongos --config /home/mongodb/app/mongodb-3.6/bin/mongos.conf
3.4 添加分片
连接任意一个"mongos",添加分片信息
use admin
sh.addShard("rs-shard1/192.168.6.25:27017,192.168.6.26:27017,192.168.6.27:27017")
sh.addShard("rs-shard2/192.168.6.28:27017,192.168.6.29:27017,192.168.6.30:27017")
查看集群分片状态
sh.status()
至此,一个基本的"sharded cluster",就已经搭建完成。
4. 使用分片
使用分片的基本步骤: 1. 开启数据库分片 -> 2. 开启集合分片
对数据库分片是对集合分片的先决条件。
4.1 开启数据库分片
以数据库:"testdb"为例,开启数据库分片命令为:
use admin
sh.enableSharding("testdb")
4.2 开启集合分片
以集合"testdb.coll1"为例,开启集合分片命令为:
sh.shardCollection("testdb.coll1", {"name" : "hashed"})
说明:
(1) 第一个参数为集合的完整namespace名称
(2) 第二个参数为片键,指定根据哪个字段进行分片。
具体参考官网"sh.shardCollection()"说明
4.3 插入数据验证数据分片
测试插入数据
use testdb
for (var i = 1; i <= 100000; i++){
db.coll1.insert({"id" : i, "name" : "name" + i});
}
验证是否分片
sh.status()
结果显示,数据已均匀分布在两个分片上。
5. 添加集群认证
上文已经成功创建一个分片集群,并验证数据分片可用。
但在部署生产环境时,还需添加认证,用以保障集群安全性。
认证分两种:
- 集群内部认证 (Internal Authentication)
用于集群内的各个组件(mongos, config server, shard)之间相互访问认证,
也就是所有的mongos进程和mongod进程之间相互访问认证。
内部认证通过keyfile密钥文件实现,即所有的monogs/mongod公用同一个keyfile文件来相互认证。
如果集群外随便来一个"mongod"进程,如果没有相同的keyfile,想加入集群,是不可能的。 - 外部用户访问集群所需的用户认证 (User Access Controls)
用于外部客户端访问mongos时,所需的用户认证。
5.1 生成并分发密钥文件keyfile
(1) 生成keyfile文件
openssl rand -base64 90 -out ./keyfile
(2) 更改"keyfile"密钥文件权限
chmod 600 keyfile
(3) 将"keyfile"密钥文件拷贝到集群每一个mongos/mongod服务器上
5.2 添加超级管理员用户
连接任意一个"mongos",创建超级管理员用户
use admin
db.createUser(
{
user: "root",
pwd: "root",
roles: [{role : "root", db : "admin"}]
}
)
在"mongos"上添加用户,用户信息实际保存在"config server"上,"mongos"本身不存储任何数据,包括用户信息。
然而,"mongos"上创建的用户,是不会自动添加到"shard"分片服务器上的。
为了以后方便维护shard分片服务器,分别登录到每个分片服务器的"primary"节点,添加管理员用户
use admin
db.createUser(
{
user: "useradmin",
pwd: "useradmin",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
5.3 开启认证
(1) 为所有"monogd"程序添加认证参数
auth = true
keyFile = /home/mongodb/app/mongodb-3.6/keyfile
(2) 为所有"mongos"程序添加认证参数
keyFile = /home/mongodb/app/mongodb-3.6/keyfile
(3) 停止集群内所有mongod/mongos程序
(4) 按照如下顺序启动所有程序:
1. “config server” -> 2. “shard” -> 3. “mongos”
(5) 验证用户访问
通过连接任意一个mongos,验证用户访问
附:开启用户认证后的最终配置文件
config server: mongod.conf
dbpath = /home/mongodb/data/db
logpath = /home/mongodb/app/mongodb-3.6/mongodb.log
port = 27017
bind_ip = 0.0.0.0
fork = true # run background
#nohttpinterface = true
replSet = rs-config
oplogSize = 2048 #2G
configsvr = true
auth = true
keyFile = /home/mongodb/app/mongodb-3.6/keyfile
shard1: mongod.conf
dbpath = /home/mongodb/data/db
logpath = /home/mongodb/app/mongodb-3.6/mongodb.log
port = 27017
bind_ip = 0.0.0.0
fork = true # run background
#nohttpinterface = true
replSet = rs-shard1
oplogSize = 2048 #2G
shardsvr = true
auth = true
keyFile = /home/mongodb/app/mongodb-3.6/keyfile
shard2: mongod.conf
dbpath = /home/mongodb/data/db
logpath = /home/mongodb/app/mongodb-3.6/mongodb.log
port = 27017
bind_ip = 0.0.0.0
fork = true # run background
#nohttpinterface = true
replSet = rs-shard2
oplogSize = 2048 #2G
shardsvr = true
auth = true
keyFile = /home/mongodb/app/mongodb-3.6/keyfile
mongos: mongos.conf
logpath = /home/mongodb/app/mongodb-3.6/mongos.log
logappend = true
bind_ip = 0.0.0.0
port = 27017
fork = true
keyFile = /home/mongodb/app/mongodb-3.6/keyfile
configdb = rs-config/192.168.6.22:27017,192.168.6.23:27017,192.168.6.24:27017
# max connections
maxConns=200