MongoDB复制集搭建(3.4.17版)
==版本==
mongodb-linux-x86_64-rhel70-3.4.17.tgz
==准备==
3个节点,我这里的IP及hostname分别是:
10.11.2.52 dscn49 10.11.2.53 dscn50 10.11.2.54 dscn51
同时节点需要完成:
1、关闭防火墙
2、SSH互信
==节点规划==
dscn49:PRIMARY
dscn50:SECONDARY
dscn51:ARBITER
==安装步骤==
1、上传压缩包
使用ftp工具上传mongodb安装包并解压缩至
/home/hadmin/mongodb
2、创建文件夹
配置文件存放路径:mkdir /home/hadmin/mongodb/conf
数据文件存储目录:mkdir /home/hadmin/data/mongodb
日志文件存储路径:mkdir /home/hadmin/data/mongodb/log
3、创建MongoDB启动配置文件
配置文件:
/home/hadmin/mongodb/conf/mongo.conf
配置文件内容:
#端口号 port=27017 #数据文件存储路径 dbpath=/home/hadmin/data/mongodb #日志文件存储路径 logpath=/home/hadmin/data/mongodb/log/mongodb.log #使用追加的方式写日志 logappend=true #以守护进程的方式启动,即在后台运行 fork=true #最大连接数 maxConns=5000 #是否启用身份验证 auth=false #复制集名称 replSet=repl1
配置文件截图:
注意:复制名称的replSet的“S”需要大写。
4、配置Linux系统环境变量
vim /etc/profile
source /etc/profile
5、同样的配置在其他两个节点完成。
可以通过scp命令,把配置好的mongodb文件夹拷贝到其他两个节点。
scp -r /home/hadmin/mongodb dscn50:/home/hadmin
scp -r /home/hadmin/mongodb dscn51:/home/hadmin
==启动==
在dscn49上运行命令:mongod --config /home/hadmin/mongodb/conf/mongodb.conf
在dscn50上运行命令:mongod --config /home/hadmin/mongodb/conf/mongodb.conf
在dscn51上运行命令:mongod --config /home/hadmin/mongodb/conf/mongodb.conf
启动成功是可以看到如下日志:
about to fork child process, waiting until server is ready for connections. forked process: 220682 child process started successfully, parent exiting
可以用ps -ef | grep mongo来查看进程ID。
好,通过上面一顿猛如虎的操作之后,MongoDB集群就启动起来了。
==初始化复制集==
启动三个节点的mongodb服务后,开始把他们初始化为副本集。
在想设置primary的节点上运行客户端mongo
复制集初始化命令:
config_repl1={_id:"repl1", members:[{_id:0, host:"dscn49:27017", priority:1}, {_id:1, host:"dscn50:27017"}, {_id:2, host:"dscn51:27017", arbiterOnly:true}]} rs.initiate(config_repl1);
正常初始化复制集之后,可以看到
第一个节点变更为PRIMARY。
第二个节点变更为SECONDARY。
第三个节点变更为ARBITER。(仲裁几点)
==数据同步测试==
首先向PRIMRY(主节点)写入一条数据,
use qch db.say.insert({"text":"Hello World"})
插入后可以使用db.say.find()查看一下插入结果。
进入SECONDARY(副节点)查看数据是否同步。
默认情况下SECONDARY节点不能读写,要设定slaveOK为true才可以从SECONDARY节点读取数据。
(replSet里只能有一个Primary节点,只能在Primary写数据,不能在SECONDARY写数据)
如果为设置slaveOK为true,会看到报错信息:
repl1:SECONDARY> db.say.find() Error: error: { "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" } repl1:SECONDARY>
设置slaveOk之后,查看结果,可以看到数据已经正常同步。
==故障切换测试==
副本集还有个重要的功能就是故障切换,
如果把主节点关闭,看看副节点是否能接替主节点进行工作。
1、关闭主节点
命令:
use admin
db.shutdownServer()
2、去副节点查看状态
repl1:PRIMARY> rs.status() { "set" : "repl1", "date" : ISODate("2018-09-26T03:16:42.857Z"), "myState" : 1, "term" : NumberLong(2), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1537931731, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1537931793, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1537931793, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "dscn49:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2018-09-26T03:16:42.484Z"), "lastHeartbeatRecv" : ISODate("2018-09-26T03:15:32.439Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : -1 }, { "_id" : 1, "name" : "dscn50:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1105, "optime" : { "ts" : Timestamp(1537931793, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-09-26T03:16:33Z"), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1537931742, 1), "electionDate" : ISODate("2018-09-26T03:15:42Z"), "configVersion" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "dscn51:27017", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 941, "lastHeartbeat" : ISODate("2018-09-26T03:16:42.465Z"), "lastHeartbeatRecv" : ISODate("2018-09-26T03:16:40.992Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 1 } ], "ok" : 1 } repl1:PRIMARY>
可以看到
dscn49变为:not reachable/healthy
dscn50变为:PRIMARY
==Java程序连接MongoDB副本集测试==
程序如下:
public class TextMongoDBReplSet { public static void main(String[] args) { List<ServerAddress> addresses = new ArrayList<>(); ServerAddress address1 = new ServerAddress("10.11.2.52", 27017); ServerAddress address2 = new ServerAddress("10.11.2.53", 27017); ServerAddress address3 = new ServerAddress("10.11.2.54", 27017); addresses.add(address1); addresses.add(address2); addresses.add(address3); MongoClient client = new MongoClient(addresses); MongoDatabase db = client.getDatabase("qch"); MongoCollection<Document> coll = db.getCollection("say"); Document doc = new Document(); doc.append("morning", "Good Morning"); coll.insertOne(doc); FindIterable<Document> fi = coll.find(); for (Document rs : fi) { System.out.println(rs.toString()); } } }
运行代码,可以看到如下运行结果
进入数据库,查看插入结果,也可以看到正常插入。
==可能遇到的问题==
1、Connection refused
在初始化集群的时候,可能出现Connection refused的拒绝访问的错误,如下图:
解决办法
在配置文件中增加bind_ip=0.0.0.0
bind_ip标识允许连接的客户端IP地址,此处设为0.0.0.0,表示允许所有机器连接。也可设置特定机器的IP。
--END--