1 Mongodb集群介绍
在官方文档的介绍中,MongoDB集群有三种形式:Replica Set(副本集),Sharding(分片集群),Master-Slaver(主从)。那么该如何选择某种集群应用
呢?其实可以从官方的文档介绍中可以得出结论,副本集和主从的模式仅是读写分离与容灾的体现,对于真正到达海量数据时,我们需要的是能将数据按照一定规
则分配至不同服务器进行存储和查询等,这就是分片集群要做的事情,聪明的你肯定已经猜到了,这种模式也囊括了副本集和主从,既然要做集群,那么我们就搭
最顶级的分片集群,本文主要介绍分片集群的搭建,以及分片集群模式下的安全认证处理配置。
2 分片集群的组件介绍
分片集群中主要有三个组件:
- Routers(前端路由器),mongos充当查询路由器,提供客户端应用程序和分片集群之间的接口。客户端通过驱动选择连接某一个mongs作为集群入口,执行
数据查询和写入。没错,它也是多个,当然官方要求至少一个,但为了防止单点故障,我们选择3台。 - Config Servers (配置服务器),config servers配置服务器存储群集的元数据和配置设置。从MongoDB 3.4开始,必须将配置服务器部署为副本集。它主要记录了
shard的配置信息,元信息,如数据存储目录,日志目录,端口号,chunk信息,是否开启了journal等信息,为了保证它的高可用,官方要求必须是副本集,如果
配置器一旦整体无法使用,则集群无法使用,所以,它也是3台。 - Shard (分片服务器),每个分片包含分片数据的子集。每个分片都可以部署为副本集。实际储存数据的载体服务,一个shard角色应该是一个ReaplicaSet组,本
此我们采用3个Shard,每个shard一个副本集,副本集中会有主节点,从节点,仲裁节点。
组件交互图:
3 集群搭建 环境准备:
mongo1(127.0.0.1) mongo2(127.0.0.1) mongo3(127.0.0.1)
config1(端口:27018) config2(端口:27018) config3(端口:27018)
mongos1(端口:27019) mongos2(端口:27029) mongos3(端口:27039)
Shard1(端口:27001) Shard1(端口:27021) Shard1(端口:27031)
Shard2(端口:27002) Shard2(端口:27022) Shard2(端口:27032)
Shard3(端口:27003) Shard3(端口:27023) Shard3(端口:27033)
实际当中,个人觉得mong1,mongo2 ,mongo3应当是在三台不同的服务器,mongos应当与config部署在不同的服务器,各shard组副本集应当部署在不同的服务器,
config可以与shard片部署在同一服务器,也就是说要达到性能最优,至少应当有6台服务器,mongos用3台,config和3组Shard用3台。本文中就以本地Windows7环境为例,
用不同的端口作为伪服务器演示搭建配置过程。MongoBD zip安装包下载地址:
Downloads for win32dl.mongodb.org注意,集群下不要使用msi安装。本文采用 mongodb-win32-x86_64-2012plus-v4.2-latest.zip
解压之后重命名为mongo,内部目录如下:
在此目录下创建伪服务器目录文件夹:
mongo1(服务器1),mongo2(服务器2),mongo3(服务器3)。如图:
然后在mongo1下分别创建文件夹data(用于存储数据),log(日志文件存放),conf(配置文件存放):
在data下再创建3个文件夹:
在conf下创建三个配置文件(config.conf、mongos.conf、shard1.conf、shard2.conf、shard3.conf):
在log下创建三个日志文件,(config.log、mongos.log、shard1.log、shard2.log、shard3.log),忽略图片中的mongos.diagnostic.data文件夹,这是服务运行时产生的。
好,至此,mong1中的环境准备工作已经结束,将mong1下的所有文件夹拷贝到mongo2和mongo3下。
集群配置编辑:
首先编辑mong1的config的配置文件:config.conf
net:
port: 27018 #config1的端口,mongo2下的为27028,mongo3下的为27038
bindIp: 0.0.0.0 #允许连接地址,这里统一设置为允许任何ip连接
systemLog:
destination: file
logAppend: true
path: D:toolmongodbmymongomongo1logconfig.log #config的日志存储地址,mongo2,mongo3下路径调整即可
storage:
dbPath: D:toolmongodbmymongomongo1dataconfig #config的数据存储地址,mongo2、mongo3下做相应的调整
journal:
enabled: true #数据故障恢复和持久化,肯定是开启
#processManagement:
# fork: true #linux下打开此设置,Windows环境下后台启动需要注册服务,
# pidFilePath: /mongo/config/run/mongod.pid
#副本集名称设置
replication:
replSetName: configs
#分片集群角色,配置服务器的固定值
sharding:
clusterRole: configsvr
#这里是集群安全认证配置,首次配置启动集群不打开此配置,先留着,后面再说
#security:
# keyFile: D:toolmongodbmymongomongodb-keyfile.file
# authorization: enabled
然后编辑shard1.conf:
net:
port: 27001 #mongo1下其他两个分片shard2为27002,shard3为27003,mongo2、mongo3下对应上面的服务编排表设置端口
bindIp: 0.0.0.0
systemLog:
destination: file
logAppend: true
path: D:toolmongodbmymongomongo1logshard1.log #mongo1下其他两个分片shard2为shard2.log,shard3为shard3.log,mongo2、mongo3下对应做调整
storage:
dbPath: D:toolmongodbmymongomongo1datashard1 #mongo1下其他两个分片shard2为shard2,shard3为shard3,mongo2、mongo3下对应做调整
journal:
enabled: true
#processManagement:
# fork: true
# pidFilePath: /mongo/shard1/run/mongod.pid
replication:
replSetName: shard1 #副本集名称,下其他两个分片对应调整shard2为shard2,shard3为shard3
sharding:
clusterRole: shardsvr #集群中角色归属
shard2.conf:
net:
port: 27002
bindIp: 0.0.0.0
systemLog:
destination: file
logAppend: true
path: D:toolmongodbmymongomongo1logshard2.log
storage:
dbPath: D:toolmongodbmymongomongo1datashard2
journal:
enabled: true
#processManagement:
# fork: true
# pidFilePath: /mongo/shard2/run/mongod.pid
replication:
replSetName: shard2
sharding:
clusterRole: shardsvr
shard3.conf:
net:
port: 27003
bindIp: 0.0.0.0
systemLog:
destination: file
logAppend: true
path: D:toolmongodbmymongomongo1logshard3.log
storage:
dbPath: D:toolmongodbmymongomongo1datashard3
journal:
enabled: true
#processManagement:
# fork: true
# pidFilePath: /mongo/shard3/run/mongod.pid
replication:
replSetName: shard3
sharding:
clusterRole: shardsvr
配置mongos.conf:
systemLog:
destination: file
logAppend: true
path: D:toolmongodbmymongomongo1logmongos.log #mongos没有数据存储地址,只有日志输出地址,mongo2、mongo3下做对应的地址调整
# network interfaces
net:
port: 27019 # mongos1的端口,mongos2为27029,mongos3为27039
bindIp: 0.0.0.0
setParameter:
enableLocalhostAuthBypass: false
#注意!此处配置的连接地址为配置服务器config Serve的副本集名称和所在服务器地址以及端口
sharding:
configDB: configs/127.0.0.1:27018,127.0.0.1:27028,127.0.0.1:27038
至此,mongo1下的配置结束,将上述配置文件内容拷贝到mongo2,mongo3对应的文件,根据服务编排内容做端口和路径的调整,切记!!一定要按照服务编排好的端口
去设置,路径一定要配置对应的文件!!!切记切记!!
启动服务,配置副本集
分片集群必须按照一定的顺序启动:config serve,Shard ,Mongos,
首先,启动三台服务器的config:在mongo安装目录bin目录下以管理员身份打开3个dos窗口分别执行下面三条dos命令,当然,如果你配置了mongo的环境变量,任意地方
开启dos窗口都可。
mongod -f D:toolmongodbmymongomongo1confconfig.conf
mongod -f D:toolmongodbmymongomongo2confconfig.conf
mongod -f D:toolmongodbmymongomongo3confconfig.conf
然后新开窗口连接到任意一台config server
mongo --port 27018
然后配置配置器的服务集:
config = { _id : "configs",
members : [
{_id : 0, host : "127.0.0.1:27018" },
{_id : 1, host : "127.0.0.1:27028" },
{_id : 2, host : "127.0.0.1:27038" }
] }
初始化副本集:
rs.initiate(config)
查看副本集状态:
rs.status()
启动3个分片副本集组:
分别开三个窗口启动执行下面三条dos命令启动shard1:
mongod -f D:toolmongodbmymongomongo1confshard1.conf
mongod -f D:toolmongodbmymongomongo2confshard1.conf
mongod -f D:toolmongodbmymongomongo3confshard1.conf
a)新开窗口连接到某一个shard1
mongo --port
27001
b)配置shard1的副本集:
config = { _id :
"shard1",
members : [
{_id :
0, host :
"127.0.0.1:27001"},
{_id :
1, host :
"127.0.0.1:27021"},
{_id :
2, host :
"127.0.0.1:27031"}
] }
c)初始化副本集:
rs.initiate(config);
按照shard1的a,b,c三步操作同样对shard2和sahrd3进行配置操作。注意,host指向的shard分片地址和端口一定要正确!!
分别启动前端路由器mongos1,mongos2,mongos3,
注意,这里启动是用mongos!!!!!
mongos -f D:toolmongodbmymongomongo1confmongos.conf
mongos -f D:toolmongodbmymongomongo2confmongos.conf
mongos -f D:toolmongodbmymongomongo3confmongos.conf
连接任意一个mongos,
mongo --port
27019
然后使用admin库,启用集群分片:
use admin;
sh.addShard("shard1/127.0.0.1:27001,127.0.0.1:27021,127.0.0.1:27031");
sh.addShard("shard2/127.0.0.1:27002,127.0.0.1:27022,127.0.0.1:27032");
sh.addShard("shard3/127.0.0.1:27003,127.0.0.1:27023,127.0.0.1:27033");
//创建管理员用户
db.createUser({user:
"admin", pwd:
"admin", roles: [{role:
"root", db:
"admin"
},{role:"root", db:"clusterAdmin"}]})
至此,分片集群搭建完成,那么,测试一下:
#设置一下chunk的大小:
use config;
db.setting.save({"_id":"chunksize","value":1}) # 设置块大小为1M是方便实验,不然需要插入海量数据
#模拟写入数据
use testdb;
#启用数据库分片
sh.enableSharding("testdb")
#创建集合
use testdb;
db.createCollection("user");
db.user.createIndex({"name":"hased"}) # 以"name"作哈希索引分片键
sh.shardCollection(
"testdb.user", {
"name"
:
"hashed"
} ) #对user集合启用分片
for(i=1;i<=50000;i++){db.user.insert({"id":i,"name":"zzx"+i})} #模拟往mytest数据库的user表写入5万数据
sh.status() # 查看分片情况
如果看到数据平均分布于shard1,shard2,shard3,那么说明我们搭建成功,启用分片成功。
4 分片集群下的安全认证实现:
MongoDB支持许多客户端可用于验证其身份的身份验证机制。这些机制允许MongoDB集成到您现有的身份验证系统中。除了验证客户端的身份之外,MongoDB还
可以要求副本集和分片集群的成员对其各自的副本集或分片集群的成员身份进行身份验证。有关 更多信息,请参阅内部验证。
首先,生成集群成员内部认证的秘钥文件,密钥文件的内容充当成员的共享密码。密钥长度必须介于6到1024个字符之间,并且只能包含base64集中的字符。如果是
生产环境,将生成后的秘钥文件拷贝到存在集群成员的每一台服务器,注意,生产环境下各节点的秘钥文件内容必须一致。
然后在所有config.conf和shard.conf中增加两项安全认证配置:
security:
keyFile: D:toolmongodbmymongomongodb-keyfile.file #秘钥文件路径
authorization: enabled #开启客户端认证
在所有mongos.conf添加:
security:
keyFile: D:toolmongodbmymongomongodb-keyfile.file #秘钥文件路径
至此配置结束,那么客户端的身份认证是通过用户名和密码进行认证,我们还需要创建用户和用户名,假设我们给testdb库创建用户,连接某一个mongos,为其创建用户:
mongos --port
27019;
use admin;//注意,一定要使用admin库去创建用户
db.createUser({user:
"testdb", pwd:
"testdb", roles: [{role:
"readWrite", db:
"testdb"
}]})
用户创建完毕。重启集群使安全认证配置生效。