复制的重要性不再多说,其主要就是提供数据保护,数据高可用和灾难恢复。

复制是跨多个mongodb服务器分布和维护的方法。mongodb可以把数据从一个节点复制到其他节点并在修改时进行同步。

mongodb的复制有两种方式: 副本集复制和主从架构复制。这两种方法类似,主节点接收所有的写请求,然后所有的从节点读取,并且异步同步所有的数据。

主从复制和副本集使用了相同的复制机制,但是副本集额外增加了自动化灾备机制,如果主节点宕机,无论什么原因,其中一个从节点会自动提升为主节点。除此之外副本集还提供了其他改进,比如更易于恢复和更复杂地部署网络拓扑。线上环境几乎全都是使用的副本集,因此这里只会有关于副本集的介绍。

下面会实际搭建一个最基本的副本集,然后会说明副本集的原理?

【MongoDB的启动必须从配置文件启动,不要用命令行】

第一步:配置文件中指定副本集的名称

#在三台服务器的配置文件中均要有如下设置
replication:
    oplogSizeMB: 20       #指定oplog的日志大小,注意这里大小只是为了测试
    replSetName: lianxi   #指定副本集的名称,在一个副本集中名称要保持一致  

第二步:配置文件启动MongoDB服务器:

[root@test1 ~]# cd /usr/local/mongodb/bin
[root@test1 bin]# ./mongod -f ../conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 2247
child process started successfully, parent exiting
[root@test1 bin]#

第三步:配置副本集

#选中其中一台MongoDB服务器作为primary.
[root@test2 bin]# ./mongo        #进入shell交互界面
MongoDB shell version v3.4.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.2
Server has startup warnings: 
2018-11-06T13:13:43.676+0800 I STORAGE  [initandlisten] 
2018-11-06T13:13:43.676+0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2018-11-06T13:13:43.676+0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2018-11-06T13:13:43.809+0800 I CONTROL  [initandlisten] 
2018-11-06T13:13:43.809+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-11-06T13:13:43.809+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-11-06T13:13:43.809+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-11-06T13:13:43.809+0800 I CONTROL  [initandlisten] 
> rs.initiate()                      #初始化操作
{
    "info2" : "no configuration specified. Using a default configuration for the set",
    "me" : "test2:27017",
    "ok" : 1
}
lianxi:SECONDARY>     #初始化成功之后,提示会变为SECONDARY
lianxi:PRIMARY>         #敲下回车,会变为PRIMARY
#初始化成功之后,添加副本集成员
lianxi:PRIMARY> rs.add("10.0.102.214:27017")   #添加从节点
{ "ok" : 1 }

#添加仲裁节点
lianxi:PRIMARY> rs.addArb("10.0.102.220:27017") 
{ "ok" : 1 }

若上面的步骤没有报错,说明副本集搭建成功。

说一个这里搭建遇见的一个问题:

> rs.initiate()
{
    "info2" : "no configuration specified. Using a default configuration for the set",
    "me" : "test3:27017",
    "ok" : 1
}                      #初始化成功
test_repl:SECONDARY> rs.add("10.0.102.181:27017")   #添加节点成功【但是日志会在等一会之后报错】
{ "ok" : 1 }
test_repl:PRIMARY> rs.addArb("10.0.102.204:27017")   #若不查看日志直接添加仲裁节点,会报如下错误!
2018-11-05T10:33:12.753+0800 E QUERY    [thread1] Error: error doing query: failed: network error while attempting to run command 'count' on host '127.0.0.1:27017'  :
DB.prototype.runCommand@src/mongo/shell/db.js:132:1
DB.prototype.runReadCommand@src/mongo/shell/db.js:109:16
DBQuery.prototype.count@src/mongo/shell/query.js:380:15
DBCollection.prototype.count@src/mongo/shell/collection.js:1700:12
rs.add@src/mongo/shell/utils.js:1213:1
rs.addArb@src/mongo/shell/utils.js:1253:12
@(shell):1:1
2018-11-05T10:33:12.756+0800 I NETWORK  [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2018-11-05T10:33:12.757+0800 I NETWORK  [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) ok

test_repl:SECONDARY>                              #这里的提示变为SECONDARY


这个问题查了好久,后来在日志文件中发现是第一步添加节点成功,日志就报错了意识是主节点连接不上从节点,但是在命令行指定host参数是可以连接的,于是就各种纠结!
最后无意中看了/etc/hosts文件,发现是hosts文件的域名解析指向错误。好吧,就是这里的问题!但是费了好长时间!
副本集搭建遇见的一个问题

这个副本集中含有一个主节点用来写入数据,一个从节点,和一个仲裁节点,整个结构如下:

mongodb-的副本集

这是MongoDB副本集的最小的节点数量,一旦主宕机,根据选举原则(一个服务器一票)从服务器会被提升为主服务器继续提供服务。MongoDB副本集为了防止出现脑裂的情况,副本集的个数应该为奇数。

测试副本集:

查看当前副本集的状态,可以使用如下命令:

rs.status()

members数组中有三个成员,分别表示这主节点,从节点,和仲裁节点。

#在主上面写入数据
lianxi:PRIMARY> use mydb
switched to db mydb
lianxi:PRIMARY> db.cityinfo.insert({name: "HongKong", country: "CHINA"})
WriteResult({ "nInserted" : 1 })
lianxi:PRIMARY>

#从上面查看数据
lianxi:SECONDARY> show dbs;     #从上面需要执行slaveOK命令才能查看数据
2018-11-06T14:06:47.696+0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not master and slaveOk=false",
    "code" : 13435,
    "codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:755:19
shellHelper@src/mongo/shell/utils.js:645:15
@(shellhelp2):1:1
lianxi:SECONDARY> rs.slaveOk()        #执行命令后
lianxi:SECONDARY> show dbs;
admin  0.000GB
local  0.000GB
mydb   0.000GB
lianxi:SECONDARY> use mydb
switched to db mydb
lianxi:SECONDARY> show collections;
cityinfo
lianxi:SECONDARY> db.cityinfo.find().pretty()   #数据已经同步到从上
{
    "_id" : ObjectId("5be12eb19efff2d99afed619"),
    "name" : "HongKong",
    "country" : "CHINA"
}
lianxi:SECONDARY>
副本集测试

相关文章: