mongodb的主从复制。

一:mongodb的主从架构:

简介:mongodb的主从模型分为两种:一种为副本集形式,另一种为heartbeat,
oplog:大小固定的文件,存储在local数据库
初始同步(initial sync)
回滚后追赶(post-rollback catch-up)
切分块迁移(sharding chunk migrations)
local:存放了副本集的所有元数据和oplog,用于存储oplog的是一个名为oplog.rs的collection;
oplog.rs的大小依赖于OS及文件系统,但可以自定义其大小oplogsize
[root@node1 ~]# mongod --help
Replication options:   默认大小为磁盘空间的5%
  --oplogSize arg       size to use (in MB) for replication op log. default is 
                        5% of disk space (i.e. large is good)

二:mongodb的复制功能:


```cpp
两种类型:
master/slave
replica set:复制集,副本集
服务于同一个数据集的多个mongodb实列
主节点将数据修改操作保存至oplog中

三:复制集的中节点分类:

0优先级的节点;冷备节点,不会被选举成为主节点,但可以参与选举;
被隐藏的从节点:首先是一个0优先级的从节点,且对客户端不可见
延迟复制的从节点:首先是一个0优先级的从节点,且复制时间落后于主节点一个固定时长

四:主从复制的准备架构:三个节点。

节点ip
node1192.168.178.128
node2192.168.178.129
node3192.168.178.130

(1)在三个节点同时安装mongodb。修改配置文件,启动mongodb

[root@node1 ~]# yum install mongodb mongodb-server -y
[root@node2~]# yum install mongodb mongodb-server -y
[root@node3~]# yum install mongodb mongodb-server -y
[root@node1 ~]# vim /etc/mongodb.conf
bind_ip = 127.0.0.1,192.168.178.128 填写需要坚听的地址
replSet=testSet    给副本集起个名称。
replIndexPrefetch=_id_only    我们根据id为全索引

[root@node1 ~]# mongod --help  通过这个查看,相关参数。
Replica set options:
--replSet arg           arg is <setname>[/<optionalseedhostlist>]
--replIndexPrefetch arg specify index prefetching behavior (if secondary) 
                          [none|_id_only|all]
[root@node1 ~]# service mongod start 启动mongodb
[root@node1 ~]# ss -tnl
State      Recv-Q Send-Q                                   Local Address:Port                                     Peer Address:Port 
LISTEN     0      128                                                 :::22                                                 :::*     
LISTEN     0      128                                                  *:22                                                  *:*     
LISTEN     0      128                                          127.0.0.1:631                                                 *:*     
LISTEN     0      128                                                ::1:631                                                :::*     
LISTEN     0      100                                                ::1:25                                                 :::*     
LISTEN     0      100                                          127.0.0.1:25                                                  *:*     
LISTEN     0      128                                          127.0.0.1:6011                                                *:*     
LISTEN     0      128                                                ::1:6011                                               :::*     
LISTEN     0      128                                    192.168.178.128:27017                                               *:*     
LISTEN     0      128                                          127.0.0.1:27017                                               *:*     
[root@node1 ~]# 
其余两个节点与上面操作一致。

(2)开始主从复制初始化,加入相关集群节点。

[root@node1 ~]# mongo   在node1上连入数据库。
MongoDB shell version: 2.4.14
connecting to: test
> help
	db.help()                    help on db methods
	db.mycoll.help()             help on collection methods
	sh.help()                    sharding helpers
	rs.help()                    replica set helpers  相关副本集帮助。
	help admin                   administrative help
	help connect                 connecting to a db help
	help keys                    key shortcuts
	help misc                    misc things to know
	help mr                      mapreduce

	show dbs                     show database names
	show collections             show collections in current database
	show users                   show users in current database
	show profile                 show most recent system.profile entries with time >= 1ms
	show logs                    show the accessible logger names
	show log [name]              prints out the last segment of log in memory, 'global' is default
	use <db_name>                set current database
	db.foo.find()                list objects in collection foo
	db.foo.find( { a : 1 } )     list objects in foo where a == 1
	it                           result of the last line evaluated; use to further iterate
	DBQuery.shellBatchSize = x   set default number of items to display on shell
	exit                         quit the mongo shell
> 
> rs.help()
	rs.status()                     { replSetGetStatus : 1 } checks repl set status
	rs.initiate()                   { replSetInitiate : null } initiates set with default settings
	rs.initiate(cfg)                { replSetInitiate : cfg } initiates set with configuration cfg
	rs.conf()                       get the current configuration object from local.system.replset
	rs.reconfig(cfg)                updates the configuration of a running replica set with cfg (disconnects)
	rs.add(hostportstr)             add a new member to the set with default attributes (disconnects)
	rs.add(membercfgobj)            add a new member to the set with extra attributes (disconnects)
	rs.addArb(hostportstr)          add a new member which is arbiterOnly:true (disconnects)
	rs.stepDown([secs])             step down as primary (momentarily) (disconnects)
	rs.syncFrom(hostportstr)        make a secondary to sync from the given member
	rs.freeze(secs)                 make a node ineligible to become primary for the time specified
	rs.remove(hostportstr)          remove a host from the replica set (disconnects)
	rs.slaveOk()                    shorthand for db.getMongo().setSlaveOk()

	db.isMaster()                   check who is primary
	db.printReplicationInfo()       check oplog size and time range

	reconfiguration helpers disconnect from the database so the shell will display
	an error, even if the command succeeds.
	see also http://<mongod_host>:28017/_replSet for additional diagnostic info
> 
> rs.status() 查看副本集相关状态。
{
	"startupStatus" : 3,
	"info" : "run rs.initiate(...) if not yet done for the set",  这项说明需要我们进行初始化。
	"ok" : 0,
	"errmsg" : "can't get local.system.replset config from self or any seed (EMPTYCONFIG)"
}
> 
> rs.initiate() 进行rs初始化。
{
	"info2" : "no configuration explicitly specified -- making one",
	"me" : "192.168.178.128:27017",
	"info" : "Config now saved locally.  Should come online in about a minute.",
	"ok" : 1
}
> rs.status()  再次查看副本集状态。
{
	"set" : "testSet",   这是副本集名称。
	"date" : ISODate("2020-08-09T08:31:07Z"),
	"myState" : 1,
	"members" : [    这表示副本集成员列表,
		{
			"_id" : 0,   这是节点标识符。
			"name" : "192.168.178.128:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",  这表示主节点
			"uptime" : 17126,  这表示最后更改oplog的时间。
			"optime" : Timestamp(1596961858, 1),
			"optimeDate" : ISODate("2020-08-09T08:30:58Z"),
			"self" : true  这说明这是不是此节点。
		}
	],
	"ok" : 1
}
testSet:PRIMARY> rs.add("192.168.178.130")  加入两个节点。
{ "ok" : 1 }
testSet:PRIMARY> rs.add("192.168.178.129")
{ "ok" : 1 }
testSet:PRIMARY> 
加入节点遇到的错误,原因是因为没有关闭防火墙。
testSet:PRIMARY> rs.add("192.168.178.130")
{
	"errmsg" : "exception: need most members up to reconfigure, not ok : 192.168.178.130:27017",
	"code" : 13144,
	"ok" : 0

testSet:PRIMARY> rs.status()
{
	"set" : "testSet",
	"date" : ISODate("2020-08-09T08:51:19Z"),
	"myState" : 1,
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.178.128:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 18338,
			"optime" : Timestamp(1596962851, 1),
			"optimeDate" : ISODate("2020-08-09T08:47:31Z"),
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "192.168.178.130:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 275,
			"optime" : Timestamp(1596962851, 1),
			"optimeDate" : ISODate("2020-08-09T08:47:31Z"),
			"lastHeartbeat" : ISODate("2020-08-09T08:51:18Z"),
			"lastHeartbeatRecv" : ISODate("2020-08-09T08:51:18Z"),
			"pingMs" : 0,
			"syncingTo" : "192.168.178.128:27017"
		},
		{
			"_id" : 2,
			"name" : "192.168.178.129:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 228,
			"optime" : Timestamp(1596962851, 1),
			"optimeDate" : ISODate("2020-08-09T08:47:31Z"),
			"lastHeartbeat" : ISODate("2020-08-09T08:51:19Z"),
			"lastHeartbeatRecv" : ISODate("2020-08-09T08:51:18Z"),
			"pingMs" : 0,
			"syncingTo" : "192.168.178.128:27017"
		}
	],
	"ok" : 1
}
testSet:PRIMARY> use testdb
switched to db testdb
testSet:PRIMARY> show dbs
local	6.0751953125GB
testdb	(empty)
testSet:PRIMARY> use testdb
switched to db testdb
testSet:PRIMARY> db.students.insert({name:"guo jing",Age:40,Course:"xiangchong shibazhang"})
testSet:PRIMARY> db.students.find()
{ "_id" : ObjectId("5f2fc2f0898f2546c9ce15f0"), "name" : "guo jing", "Age" : 40, "Course" : "xiangchong shibazhang" }
testSet:PRIMARY> show dbs;
local	6.0751953125GB
testdb	0.203125GB
在主库中插入一些数据,看从数据库的同步状态。noed2节点。
testSet:SECONDARY> show dbs
local	6.0751953125GB
testdb	0.203125GB
testSet:SECONDARY> 
testSet:SECONDARY> db.students.find()  查询相关数据报错,这表示我们需要在从库中开启查询功能
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
testSet:SECONDARY> 
testSet:PRIMARY> rs.slaveOk()
testSet:SECONDARY> rs.slaveOk()
testSet:SECONDARY> db.students.find()
{ "_id" : ObjectId("5f2fc2f0898f2546c9ce15f0"), "name" : "guo jing", "Age" : 40, "Course" : "xiangchong shibazhang" }
testSet:SECONDARY> 

判断哪个节点是主节点。
testSet:PRIMARY> rs.isMaster()
{
	"setName" : "testSet",
	"ismaster" : true,
	"secondary" : false,
	"hosts" : [
		"192.168.178.128:27017",
		"192.168.178.129:27017",
		"192.168.178.130:27017"
	],
	"primary" : "192.168.178.128:27017",
	"me" : "192.168.178.128:27017",
	"maxBsonObjectSize" : 16777216,
	"maxMessageSizeBytes" : 48000000,
	"localTime" : ISODate("2020-08-09T10:14:30.739Z"),
	"ok" : 1
}
testSet:PRIMARY> 

testSet:PRIMARY> db.printReplicationInfo() 这表示查看oplog的大小及时间范围
configured oplog size:   4532.2263671875MB
log length start to end: 3758secs (1.04hrs)
oplog first event time:  Sun Aug 09 2020 01:30:58 GMT-0700 (PDT)
oplog last event time:   Sun Aug 09 2020 02:33:36 GMT-0700 (PDT)
now:                     Sun Aug 09 2020 03:16:29 GMT-0700 (PDT)
testSet:PRIMARY> 

rs.stepDown([secs]) :这个表示将主节点强制成从节点。默认让它下线的。

(3)副本集重新选定的条件。

(1)心跳信息,优先级(高者优先,0是不可成为主节点的),uptime:必须与所有节点都一样,如果落后是不能成为主节点的,网络链接,网络分区

选举机制:
触发选举的事件:
新副本集初始化时
从节点联系不到主节点时
主节点下台时。:某主节点收到stepDown()命令时,某从节点有更高的优先级且已经满足成主节点其他所有条件。

修改配置文件,设置优先级,注意:必须在主节点进行操作。
testSet:PRIMARY> rs.conf() 默认的配置文件信息。
{
	"_id" : "testSet",
	"version" : 3,
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.178.128:27017"
		},
		{
			"_id" : 1,
			"host" : "192.168.178.130:27017"
		},
		{
			"_id" : 2,
			"host" : "192.168.178.129:27017"
		}
	]
}
接下来我们自定义优先级,使得从成为主节点。
testSet:PRIMARY> cfg.members[1].priority=2
2
testSet:PRIMARY> rs.reconfig(cfg)   重新载入配置信息
Sun Aug  9 03:38:12.036 DBClientCursor::init call() failed
Sun Aug  9 03:38:12.039 trying reconnect to 127.0.0.1:27017
Sun Aug  9 03:38:12.040 reconnect 127.0.0.1:27017 ok
reconnected to server after rs command (which is normal)
testSet:SECONDARY> rs.conf()
{
	"_id" : "testSet",
	"version" : 4,
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.178.128:27017"
		},
		{
			"_id" : 1,
			"host" : "192.168.178.130:27017",
			"priority" : 2    看到从节点node2优先级变为了2
		},
		{
			"_id" : 2,
			"host" : "192.168.178.129:27017"
		}
	]
}
testSet:SECONDARY> rs.status()   查看状态信息可以看到node2成为了主节点。
{
	"set" : "testSet",
	"date" : ISODate("2020-08-09T10:39:53Z"),
	"myState" : 2,
	"syncingTo" : "192.168.178.130:27017",
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.178.128:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 24852,
			"optime" : Timestamp(1596969492, 1),
			"optimeDate" : ISODate("2020-08-09T10:38:12Z"),
			"errmsg" : "syncing to: 192.168.178.130:27017",
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "192.168.178.130:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 101,
			"optime" : Timestamp(1596969492, 1),
			"optimeDate" : ISODate("2020-08-09T10:38:12Z"),
			"lastHeartbeat" : ISODate("2020-08-09T10:39:52Z"),
			"lastHeartbeatRecv" : ISODate("2020-08-09T10:39:52Z"),
			"pingMs" : 0,
			"syncingTo" : "192.168.178.128:27017"
		},
		{
			"_id" : 2,
			"name" : "192.168.178.129:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 101,
			"optime" : Timestamp(1596969492, 1),
			"optimeDate" : ISODate("2020-08-09T10:38:12Z"),
			"lastHeartbeat" : ISODate("2020-08-09T10:39:52Z"),
			"lastHeartbeatRecv" : ISODate("2020-08-09T10:39:52Z"),
			"pingMs" : 0,
			"lastHeartbeatMessage" : "syncing to: 192.168.178.130:27017",
			"syncingTo" : "192.168.178.130:27017"
		}
	],
	"ok" : 1
}
如何设置仲裁节点:
testSet:PRIMARY> cfg.members[0].arbiterOnly=true   设置仲裁节点。
true
testSet:PRIMARY> rs.reconfig(cfg)
{
	"errmsg" : "exception: arbiterOnly may not change for members",
	"code" : 13510,
	"ok" : 0
}
总结:主从复制架构一些相关操作基本完成。我们了解主从复制其实复制的是oplog中的数据。
初始同步的步骤:
1,克隆所有数据库
2,应用数据集的所有改变,复制oplog并应用于本地
3,为所有collection构建索引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值