MongoDB主从复制

介绍了Mongodb的安装使用,在 MongoDB 中,有两种数据冗余方式,一种 是 Master-Slave 模式(主从复制),一种是 Replica Sets 模式(副本集)。

Mongodb一共有三种集群搭建的方式:
Replica Set(副本集)、
Sharding(切片)
Master-Slaver(主从)【目前已不推荐使用了!!!】
 
其中,Sharding集群也是三种集群中最复杂的。
副本集比起主从可以实现故障转移!!非常使用!
 
mongoDB目前已不推荐使用主从模式,取而代之的是副本集模式。副本集其实一种互为主从的关系,可理解为主主。
副本集指将数据复制,多份保存,不同服务器保存同一份数据,在出现故障时自动切换。对应的是数据冗余、备份、镜像、读写分离、高可用性等关键词;
而分片则指为处理大量数据,将数据分开存储,不同服务器保存不同的数据,它们的数据总和即为整个数据集。追求的是高性能。
 
在生产环境中,通常是这两种技术结合使用,分片+副本集。

mongodb主从复制配置

有些版本已经不支持主从复制(本人环境为mongodb4.0版本,已经不支持主从复制)

主从复制是MongoDB最常用的复制方式,也是一个简单的数据库同步备份的集群技术,这种方式很灵活.可用于备份,故障恢复,读扩展等. 
最基本的设置方式就是建立一个主节点和一个或多个从节点,每个从节点要知道主节点的地址。采用双机备份后主节点挂掉了后从节点可以接替主机继续服务。所以这种模式比单节点的高可用性要好很多。

  配置主从复制的注意点

1)在数据库集群中要明确的知道谁是主服务器,主服务器只有一台.
2)从服务器要知道自己的数据源也就是对应的主服务是谁.
3)--master用来确定主服务器,--slave 和 --source 来控制从服务器

可以在mongodb.conf配置文件里指明主从关系,这样启动mongodb的时候只要跟上配置文件就行,就不需要通过--master和--slave来指明主从了。

下面简单记录下Mongodb主从复制的部署过程

1)机器环境
182.48.115.238    master-node
182.48.115.236    slave-node
 
两台机器都关闭防火墙和selinux
mongodb的安装参考:http://www.cnblogs.com/kevingrace/p/5752382.html
 
2)主从配置
.............master-node节点配置.............
[root@master-node ~]# vim /usr/local/mongodb/mongodb.conf
port=27017
bind_ip = 182.48.115.238
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongo.log
logappend=true
journal = true
fork = true
master = true        //确定自己是主服务器
 
[root@master-node ~]# nohup /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf &
 
[root@master-node ~]# ps -ef|grep mongodb
root     15707 15514 23 16:45 pts/2    00:00:00 /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf
root     15736 15514  0 16:45 pts/2    00:00:00 grep mongodb
[root@master-node ~]# lsof -i:27017
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  15707 root    7u  IPv4 153114      0t0  TCP 182.48.115.238:27017 (LISTEN)
 
由于mongodb.conf里绑定了本机的ip地址182.48.115.238,所以连接mongodb的时候必须用这个ip地址,不能使用默认的127.0.0.1,也就是说:
[root@master-node ~]# mongo 182.48.115.238:27017     //这样才能连接mongodb
[root@master-node ~]# mongo 或者 mongodb 127.0.0.1:27017    // 这样不能连接mongodb
 
.............slave-node节点配置.............
[root@slave-node ~]# vim /usr/local/mongodb/mongodb.conf
port=27017
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongo.log
logappend=true
journal = true
fork = true
bind_ip = 182.48.115.236            //确定主数据库端口
source = 182.48.115.238:27017      //确定主数据库端口
slave = true               //确定自己是从服务器
 
[root@slave-node ~]# nohup /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf &
 
[root@slave-node ~]# ps -ef|grep mongo
root     26290 26126  8 16:47 pts/0    00:00:00 /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf
root     26316 26126  0 16:47 pts/0    00:00:00 grep mongo
[root@slave-node ~]# lsof -i:27017
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  26290 root    7u  IPv4 663904      0t0  TCP slave-node1:27017 (LISTEN)
mongod  26290 root   25u  IPv4 663917      0t0  TCP slave-node1:51060->slave-node2:27017 (ESTABLISHED)
 
在slave-node测试连接master-node的mongodb数据库是否正常
[root@slave-node ~]# mongo 182.48.115.236:27017
MongoDB shell version v3.4.4
connecting to: 182.48.115.236:27017
MongoDB server version: 3.4.4
Server has startup warnings:
2017-06-03T16:47:31.200+0800 I STORAGE  [initandlisten]
2017-06-03T16:47:31.200+0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2017-06-03T16:47:31.200+0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2017-06-03T16:47:32.472+0800 I CONTROL  [initandlisten]
2017-06-03T16:47:32.472+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-06-03T16:47:32.472+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-06-03T16:47:32.472+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-06-03T16:47:32.472+0800 I CONTROL  [initandlisten]
2017-06-03T16:47:32.473+0800 I CONTROL  [initandlisten]
2017-06-03T16:47:32.473+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-06-03T16:47:32.473+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-06-03T16:47:32.473+0800 I CONTROL  [initandlisten]
2017-06-03T16:47:32.473+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-06-03T16:47:32.473+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-06-03T16:47:32.473+0800 I CONTROL  [initandlisten]
>
 
3)主从数据同步测试
在master-node节点数据库里创建master_slave库,并插入20条数据
[root@master-node ~]# mongo 182.48.115.238:27017
MongoDB shell version v3.4.4
connecting to: 182.48.115.238:27017
MongoDB server version: 3.4.4
Server has startup warnings:
2017-06-03T16:45:07.406+0800 I STORAGE  [initandlisten]
2017-06-03T16:45:07.407+0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2017-06-03T16:45:07.407+0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2017-06-03T16:45:08.373+0800 I CONTROL  [initandlisten]
2017-06-03T16:45:08.373+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-06-03T16:45:08.373+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-06-03T16:45:08.373+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-06-03T16:45:08.373+0800 I CONTROL  [initandlisten]
2017-06-03T16:45:08.374+0800 I CONTROL  [initandlisten]
2017-06-03T16:45:08.374+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-06-03T16:45:08.374+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-06-03T16:45:08.374+0800 I CONTROL  [initandlisten]
2017-06-03T16:45:08.374+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-06-03T16:45:08.374+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-06-03T16:45:08.374+0800 I CONTROL  [initandlisten]
> use master_slave
switched to db master_slave
> function add(){var i = 0;for(;i<20;i++){db.persons.insert({"name":"wang"+i})}}
> add()
> db.persons.find()
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbb"), "name" : "wang0" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbc"), "name" : "wang1" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbd"), "name" : "wang2" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbe"), "name" : "wang3" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbf"), "name" : "wang4" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc0"), "name" : "wang5" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc1"), "name" : "wang6" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc2"), "name" : "wang7" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc3"), "name" : "wang8" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc4"), "name" : "wang9" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc5"), "name" : "wang10" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc6"), "name" : "wang11" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc7"), "name" : "wang12" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc8"), "name" : "wang13" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc9"), "name" : "wang14" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dca"), "name" : "wang15" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dcb"), "name" : "wang16" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dcc"), "name" : "wang17" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dcd"), "name" : "wang18" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dce"), "name" : "wang19" }
Type "it" for more
 
然后在slave-node节点数据库里查看,是否将master-node写入的新数据同步过来了
[root@slave-node log]# mongo 182.48.115.236:27017
MongoDB shell version v3.4.4
connecting to: 182.48.115.236:27017
MongoDB server version: 3.4.4
Server has startup warnings:
2017-06-03T16:56:28.928+0800 I STORAGE  [initandlisten]
2017-06-03T16:56:28.928+0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2017-06-03T16:56:28.928+0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2017-06-03T16:56:29.883+0800 I CONTROL  [initandlisten]
2017-06-03T16:56:29.883+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-06-03T16:56:29.883+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-06-03T16:56:29.883+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-06-03T16:56:29.883+0800 I CONTROL  [initandlisten]
2017-06-03T16:56:29.884+0800 I CONTROL  [initandlisten]
2017-06-03T16:56:29.884+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-06-03T16:56:29.884+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-06-03T16:56:29.884+0800 I CONTROL  [initandlisten]
2017-06-03T16:56:29.884+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-06-03T16:56:29.884+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-06-03T16:56:29.884+0800 I CONTROL  [initandlisten]
> show dbs
2017-06-03T17:10:32.136+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:769:19
shellHelper@src/mongo/shell/utils.js:659:15
@(shellhelp2):1:1
> rs.slaveOk();
> show dbs
admin         0.000GB
local         0.000GB
master_slave  0.000GB
wangshibo     0.000GB
> use master_slave
switched to db master_slave
> db.persons.find()
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbb"), "name" : "wang0" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbc"), "name" : "wang1" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbd"), "name" : "wang2" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbe"), "name" : "wang3" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dbf"), "name" : "wang4" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc0"), "name" : "wang5" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc1"), "name" : "wang6" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc2"), "name" : "wang7" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc3"), "name" : "wang8" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc4"), "name" : "wang9" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc5"), "name" : "wang10" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc6"), "name" : "wang11" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc7"), "name" : "wang12" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc8"), "name" : "wang13" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dc9"), "name" : "wang14" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dca"), "name" : "wang15" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dcb"), "name" : "wang16" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dcc"), "name" : "wang17" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dcd"), "name" : "wang18" }
{ "_id" : ObjectId("593278699a9e2e9f37ac4dce"), "name" : "wang19" }
Type "it" for more
........................................................................................
如果在slave-node节点上的数据库中查看,有报错:"errmsg" : "not master and slaveOk=false"!!!
首先这是正常的,因为SECONDARY是不允许读写的, 在写多读少的应用中,使用Replica Sets来实现读写分离。
通过在连接时指定或者在主库指定slaveOk,由Secondary来分担读的压力,Primary只承担写操作。
对于replica set 中的secondary 节点默认是不可读的。
 
解决办法:
在slave-node节点数据库中执行"rs.slaveOk();"命令即可
........................................................................................
 
在slave-node节点数据库中发现已经同步过来了master_slave库的20条数据,说明mongodb的主从复制环境已经成功了!当配置完主从服务器后,一但主服务器上的数据发生变化,从服务器也会发生变化

主从复制的原理

在主从结构中,主节点的操作记录成为oplog(operation log)。oplog存储在一个系统数据库local的集合oplog.$main中,这个集合的每个文档都代表主节点上执行的一个操作。
从服务器会定期从主服务器中获取oplog记录,然后在本机上执行!对于存储oplog的集合,MongoDB采用的是固定集合,也就是说随着操作过多,新的操作会覆盖旧的操作!
 
主从复制的其他设置项
--only             从节点指定复制某个数据库,默认是复制全部数据库
--slavedelay       从节点设置主数据库同步数据的延迟(单位是秒)
--fastsync         从节点以主数据库的节点快照为节点启动从数据库
--autoresync       从节点如果不同步则从新同步数据库(即选择当通过热添加了一台从服务器之后,从服务器选择是否更新主服务器之间的数据)
--oplogSize        主节点设置oplog的大小(主节点操作记录存储到local的oplog中)

在上面slave-node从节点的local数据库中,存在一个集合sources。这个集合就保存了这个服务器的主服务器是谁

[root@slave-node mongodb]# mongo 182.48.115.236:27017
......
> show dbs
admin         0.000GB
local         0.000GB
master_slave  0.000GB
wangshibo     0.000GB
> use local
switched to db local
> show collections
me
sources
startup_log
> db.sources.find()
{ "_id" : ObjectId("593277a5105051e5648605a3"), "host" : "182.48.115.238:27017", "source" : "main", "syncedTo" : Timestamp(1496481652, 1) }
>
原文地址:https://www.cnblogs.com/fat-girl-spring/p/13410504.html