搭建MongoDB集群
搭建一个简单的MongoDB副本集的过程
准备过程
服务器信息
三台服务器信息如下:
- 系统版本: CentOS 7 7.6.1810
- IP和主机信息:
- mongodb_1 : 192.168.187.209
- mongodb_2 : 192.168.187.210
- mongodb_3 : 192.168.187.211
- 安装MongoDB版本: 4.2
设置主机名
设置主机名, 根据预先的规划,分别登陆机器设置主机名字。
设置主机名,添加如下信息到三台机器的/etc/hosts
中。
SeLinux配置
如果要使用自定义的mongodb数据或日志路径,建议关闭SELinux。
在配置文件/etc/selinux/config
中,将SELINUX=enforcing改为SELINUX=disabled
如果确定需要启动SeLinux, 并且需要使用自定义的数据路径,则可以参考官网设置。install-mongodb-on-red-hat/#configure-selinux
安装MongoDB
在三台服务器上分别安装MongoDB 4.2。完全4.2的安装步骤可参见官网Install MongoDB Community Edition on Red Hat or CentOS
三台服务器上,添加mongodb的yum源
三台服务器上, 安装MongoDB
三台服务器上,开启防火墙,允许27017端口访问
三台服务器上,在/opt
目录下创建mongodb相关的目录
三台服务器上,修改mongodb配置文件/etc/mongod.conf
, 修改数据路径,日志路径和服务绑定IP等信息。
- 数据路径: 设置
storage.dbPath
为/opt/mongodb/data
- 日志路径: 设置
systemLog.path
为/opt/mongodb/log/mongod.log
- 服务绑定IP: 设置
net.bindIp
为各个机器的内网地址,192.168.187.209
,192.168.187.210
和192.168.187.211
- 设置副本集名称: 设置
replication.replSetName
为replicasetTest0
,replicasetTest0
是副本集名称,可以根据实际进行修改,同一副本集所有实例,name需要一致。 - 认证信息暂时先不设置,配置完集群设置的时候一起设置。
以服务器mongodb_1
为例,此处的bindIp
就应该是192.168.187.209
, 对应的修改项如下。
设置之前先备份,永远是一个好习惯sudo cp /etc/mongod.conf /etc/mongod.conf.bak
|
|
三台服务器上,启动mongodb服务。
配置Replicaset
建立集群
登录任意一台服务器的mongo, 执行如下命令配置副本集。
|
|
执行结果:
协商阶段,提示符会变成副本集名字:SECONDARY
,协商结束后,Primary的机器的提示符会变成副本集名字:SECONDARY
。在我们的例子中就是replicasetTest0:SECONDARY
和replicasetTest0:PRIMARY
。
可以使用rs.status()
来查看哪个服务器是PRIMARY
,哪些服务器是SECONDARY
。
创建root用户
在启动认证之前,需要先创建登录用户。
在PRIMARY
节点上,执行mongo
登录节点, 执行如下命令创建root用户。
执行结果如下:
生成authKey
authKey用于实例认证,用于主从或者副本集直接验证,同副本集的文件内容需要一致
在mongodb_1
上生成keyFile.
在mongodb_2
和mongodb_3
上创建对应的目录和文件,将mongodb_1
生成的key拷贝到mongodb_2
和mongodb_3
上。
启用集群服务器的认证功能
三台服务器中启用认证功能。在/etc/mongod.conf
中设置keyFile
和authorization
。
- 开启认证: 设置
security.authorization
为enabled
,启动登录认证。 - 配置认证key文件,设置
security.keyFile
为上个步骤设置的文件/etc/mongod/keyFiles/mongo-key
.
|
|
配置过后,sudo systemctl restart mongod
重启三台服务器。
验证是否启用了账号登录。
|
|
数据测试
此时,集群状态:mongodb_1
为PRIMARY,mongodb_2
和mongodb_3
为SECONDARY。
登录Primary数据库,插入如下数据
执行mongo mongodb://my_root:mypassword@mongodb_1:27017
登录Primary数据库。1234567use replicatestdatadb.createCollection("replicatestCollection01")db.replicatestCollection01.insertMany([{name: "test_record_one", description: "testing replica set", record: 1},{name: "test_record_two", description: "testing replica set", record: 2},{name: "test_record_three", description: "testing replica set", record: 3}])在
mongodb_2
上查看数据
执行mongo mongodb://my_root:mypassword@mongodb_2:27017
登录mongodb_2数据库。12345678replicasetTest0:SECONDARY> db.getMongo().setSecondaryOk();replicasetTest0:SECONDARY> use replicatestdataswitched to db replicatestdatareplicasetTest0:SECONDARY> db.replicatestCollection01.find(){ "_id" : ObjectId("60ec094a7f37fee5e1bc1980"), "name" : "test_record_one", "description" : "testing replica set", "record" : 1 }{ "_id" : ObjectId("60ec094a7f37fee5e1bc1981"), "name" : "test_record_two", "description" : "testing replica set", "record" : 2 }{ "_id" : ObjectId("60ec094a7f37fee5e1bc1982"), "name" : "test_record_three", "description" : "testing replica set", "record" : 3 }replicasetTest0:SECONDARY>在
mongodb_3
上查看数据
执行mongo mongodb://my_root:mypassword@mongodb_3:27017
登录mongodb_3数据库。12345678replicasetTest0:SECONDARY> db.getMongo().setSecondaryOk();replicasetTest0:SECONDARY> use replicatestdataswitched to db replicatestdatareplicasetTest0:SECONDARY> db.replicatestCollection01.find(){ "_id" : ObjectId("60ec094a7f37fee5e1bc1980"), "name" : "test_record_one", "description" : "testing replica set", "record" : 1 }{ "_id" : ObjectId("60ec094a7f37fee5e1bc1982"), "name" : "test_record_three", "description" : "testing replica set", "record" : 3 }{ "_id" : ObjectId("60ec094a7f37fee5e1bc1981"), "name" : "test_record_two", "description" : "testing replica set", "record" : 2 }replicasetTest0:SECONDARY>
可以看到在PRIMARY mongodb_1
中的数据,被复制到了mongodb_2
和mongodb_3
中。
一些Tips
启动mongod,报 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=1/FAILURE)
stauts=1, 一般是文件权限问题,除了常规的用户组权限以外,如果CentOS开启了SELinux,注意还需要进行SELinux权限设置。参见官网文档install-mongodb-on-red-hat/#configure-selinux
集群配置
集群配置中,可以通过priority设置节点的优先级,还可以通过votes字段来设置节点是否加入投票。
例子:
|
|
SECONDARY上开启查询
默认情况下,不能直接使用mongo
命令在SECONDARY的节点上进行查询。如果要查询,需要先执行db.getMongo().setSecondaryOk();
打开查询功能,然后再查询。
集群命令
rs.status()
: 查看集群状态rs.conf()
: 查看集群配置rs.add()
: 添加集群节点rs.initiate(cfg)
: 使用配置信息初始化集群- cfg例子:
config = { _id:"rs", members:[{_id:0,host:"192.168.83.131:27017", priority : 100, votes: 1 },{_id:1,host:"192.168.83.33:27017", priority : 0, votes: 0}]}
- cfg例子:
rs.reconfig(cfg)
: 指定配置信息重置副本集;指定第二个参数{force:true},来强制更新- 例子: 剔除mongodb_3的节点,重置为两个节点:
rs.reconfig({ _id:"replicasetTest0", members:[{_id:0,host:"192.168.187.209:27017" },{_id:1,host:"192.168.187.210:27017"}]})
- 例子: 剔除mongodb_3的节点,重置为两个节点:
rs.add(membercfgobj)
: 使用指定配置,给副本集添加新成员- 例子: 重新添加
mongodb_3
节点。rs.add( { host: "192.168.187.211:27017", priority: 1, votes: 1 } )
- 例子: 重新添加
rs.remove(hostportstr)
: 从副本集删除指定节点- 例子: 删除
mongodb_3
节点。rs.remove("192.168.187.211:27017")
- 例子: 删除
rs.printReplicationInfo()
: 查看操作日志以及日志时间rs.printSecondaryReplicationInfo()
: 查看各个SECONDARY节点和PRIMARY之间的延迟情况