一、主从集群
MongoDB支持在多个机器中通过异步复制达到故障转移和实现冗余。多机器中同一个时刻只有一台是用于写操作。正是由于这个情况,为MongoDB提供了数据一致性的保障。担当Primary角色的机器能把读操作分发给slave。
MongoDB的主从集群分为两种:
Master-Slave复制(主从) ---------不建议使用了!!!
Replica Sets复制(副本集)
Master-Slave复制
只需要在某一个服务启动时加上-master参数,而另一个服务加上-slave与-source参数,即可实现同步。
MongoDB的最新版本已经不推荐使用这种方法了。因为主服务器宕机了,从服务器不会自动变成主!
主:端口为20000
[root@localhost mongodb]# mkdir data1 data2
[root@localhost mongodb]# touch dblog1.log
[root@localhost mongodb]# touch dblog2.log
[root@localhost mongodb]# /usr/local/mongodb/bin/mongod --master --dbpath=/usr/local/mongodb/data1/ --logpath=/usr/local/mongodb/dblog1.log --fork --port 20000
about to fork child process, waiting until server is ready for connections.
forked process: 4837
child process started successfully, parent exiting
[root@localhost mongodb]# netstat -tunpl |grep 20000 【查看端口】
tcp 0 0 127.0.0.1:20000 0.0.0.0:* LISTEN 4837/mongod
[root@localhost mongodb]#
连接Mongo客户端:
[root@localhost mongodb]# /usr/local/mongodb/bin/mongo --port 20000
#在master插入一条数据,在slave中是可以看到的
> db.c1.insert({name:"user1",age:1});
从:端口为20001 (可以在另一窗口中处理)
[root@localhost mongodb]# /usr/local/mongodb/bin/mongod --slave --source 127.0.0.1:20000 --dbpath=/usr/local/mongodb/data2/ --logpath=/usr/local/mongodb/dblog2.log --fork --port 20001
about to fork child process, waiting until server is ready for connections.
forked process: 4868
child process started successfully, parent exiting
[root@localhost mongodb]# netstat -tunpl |grep :20001
tcp 0 0 127.0.0.1:20001 0.0.0.0:* LISTEN 4868/mongod
[root@localhost mongodb]#
连接Mongo客户端:
一个错误的解决:
[root@localhost mongodb]# /usr/local/mongodb/bin/mongo --port 20001
>rs.slaveOk(); ###确认一下自己是从!!
>db.c1.find(); ##可以看到master中刚才插入的数据!
##在slave中插入式不会成功的!
> db.c1.insert({name:"user2"});
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })
###在从上备份貌似不太好使!!注意一下!!!
[root@localhost bin]# ./mongodump --port 20001 -d test
2018-05-27T06:04:15.672-0400 Failed: error connecting to db server: no reachable servers
[root@localhost bin]# ./mongodump --port 20000 -d test
2018-05-27T06:04:25.309-0400 writing test.c1 to
2018-05-27T06:04:25.310-0400 done dumping test.c1 (1 document)
[root@localhost bin]#
Replica Sets复制(副本集)
MongoDB在1.6版本开发了replica set,主要增加了故障自动切换和自动修复成员节点,各个DB之间数据完全一致,最为显著的区别在于,副本集没有固定的主节点,它是整个集群选举得一个主节点,当其不工作时变更为其他节点!
mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
MongoDB复制结构图如下所示:
以上结构图中,客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。
副本集特征:
- N 个节点的集群
- 任何节点可作为主节点
- 所有写入操作都在主节点上
- 自动故障转移
- 自动恢复
#《1.》创建数据文件存储路径
[root@localhost mongodb]# mkdir -p data/data1
[root@localhost mongodb]# mkdir -p data/data2
#《2.》创建日志文件
[root@localhost mongodb]# mkdir log
[root@localhost mongodb]# touch log/dblog1.log
[root@localhost mongodb]# touch log/dblog2.log
#《3.》创建主从key文件用于标识集群的私钥的完整路径
#如果各个实例的key file的内容不一致,将不能正常通信!
[root@localhost mongodb]# mkdir key
[root@localhost mongodb]# touch key/key1
[root@localhost mongodb]# touch key/key2
[root@localhost mongodb]# echo "123456">key/key1
[root@localhost mongodb]# echo "123456">key/key2
[root@localhost mongodb]# chmod 600 key/*
#《4.》####启动实例1#####
[root@localhost mongodb]# /usr/local/mongodb/bin/mongod --replSet rs1 --keyFile=/usr/local/mongodb/key/key1 --port=20001 --dbpath=/usr/local/mongodb/data/data1/ --logpath=/usr/local/mongodb/log/dblog1.log --fork
about to fork child process, waiting until server is ready for connections.
forked process: 5062
child process started successfully, parent exiting
[root@localhost mongodb]# netstat -tunpl |grep :20001
tcp 0 0 127.0.0.1:20001 0.0.0.0:* LISTEN 5062/mongod
#《5》######启动实例2##########
[root@localhost mongodb]# /usr/local/mongodb/bin/mongod --replSet rs1 --keyFile=/usr/local/mongodb/key/key2 --port=20002 --dbpath=/usr/local/mongodb/data/data2/ --logpath=/usr/local/mongodb/log/dblog2.log --fork
about to fork child process, waiting until server is ready for connections.
forked process: 5093
child process started successfully, parent exiting
[root@localhost mongodb]# netstat -tunpl |
> grep 2000
tcp 0 0 127.0.0.1:20001 0.0.0.0:* LISTEN 5062/mongod
tcp 0 0 127.0.0.1:20002 0.0.0.0:* LISTEN 5093/mongod
#《6.》配置Replica Sets####
[root@localhost mongodb]# /usr/local/mongodb/bin/mongo --port 20001
> config_rs1={
... _id:"rs1",
... members:[
... {_id:0,host:"127.0.0.1:20001",priority:1},
... {_id:1,host:"127.0.0.1:20002",priority:2}
... ]}
{
"_id" : "rs1",
"members" : [
{
"_id" : 0,
"host" : "127.0.0.1:20001",
"priority" : 1
},
{
"_id" : 1,
"host" : "127.0.0.1:20002",
"priority" : 2
}
]
}
>
##《7.》初始化Replica Sets#####
> rs.initiate(config_rs1);
{
"ok" : 1,
"operationTime" : Timestamp(1527418399, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1527418399, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
>
客户端登录情况:
主:
#如果插入数据或show tables:没有权限,要加权限!此处要再看看!!3.0以后的版本权限控制更严格了!!
rs1:PRIMARY> db.createUser({user:"dba",pwd:"dba",roles:["userAdminAnyDatabase","readWriteAnyDatabase","dbAdminAnyDatabase"]});
rs1:PRIMARY> db.auth("dba","dba");
##插入值
rs1:PRIMARY> db.c1.insert({name:"user1"});
从:
##从库可以查到
>rs.slaveOk(); ##需要的!!!
rs1:SECONDARY> db.c1.find();
{ "_id" : ObjectId("5b0a914f0a5056c858949b1b"), "name" : "user1" }
###从库并不能插入成功
rs1:SECONDARY> db.c1.insert({name:"user2"});
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })