mongodb 副本集搭建

mongodb是nosql的数据库,与mysql的关系型数据库在底层构造上面有差异。mogodb的的一个collection对于mysql的一个数据表。mongodb的数据表的格式是:_id: uuid,_id就是这条数据的key。 _id对于的数据内容是bson格式。对于代码里面的结构体。
golang代码中,一个结构体对于mongodb的一个collection文档(bson)。 bson编码是二进制编码的json,可以认为是压缩版本的json。

一、搭建mongodb 副本集(Replica Set):

mongodb的集群有3种方式:

  • (1)经典的主从模式 :适合小业务,单站服务
  • (2)副本集模式:适合常规公司的业务
  • (3)分片模式:超大规模的业务,例如互联网三巨头等公司的数据存储和索引。

性能对比:副本集是性能是最高的 > 主从模式 > 分片。

负载量对比:Sharding > 副本集 > 主从模式。

副本集结构图:

PSS
Primary + Secondary + Secondary模式,通过Primary和Secondary搭建的Replica Set
Diagram of a 3 member replica set that consists of a primary and two secondaries.

mongodb 副本集搭建

该模式下 Replica Set节点数必须为奇数,目的是选主投票的时候要出现大多数才能进行选主决策。

PSA
Primary + Secondary + Arbiter模式,使用Arbiter搭建Replica Set
mongodb 副本集搭建
偶数个数据节点,加一个Arbiter构成的Replica Set

本文采用PSA模式搭建副本集。

副本集特点:

集群当中包含了多份相同的数据,读可以分散到从节点,通过动态选举,保证主节点挂掉了之后,备节点能继续提供数据服务。

副本集原理:

主节点在日志文件中记录在其上的所有r/w请求的oplog(action and parameter),从节点定期轮询主节点获取这些操作w日志,然后对自己维护的数据副本执行这些操作,从而保证从节点的数据与主节点最终的一致性。

副本集角色:

  • Mongodb(M)表示主节点,

  • Mongodb(S)表示备节点,

  • Mongodb(A)表示仲裁节点。

主备节点存储数据,仲裁节点不存储数据,只作为主从切换的裁判角色。客户端同时连接主节点与备节点,不与仲裁节点发生网络连接。

mongodb 节点ip:

192.168.1.100   # 主节点(Master)
192.168.1.101   # 从节点(Slave)
192.168.1.102   # 仲裁节点(arbitration)

默认设置下,主节点提供所有增删查改服务,备节点不提供任何r/w服务。需要手工通过设置使备节点开启提供查询的服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做Read Preference Modes,配置可以通过客户端的sdk来实现,也可以通过mongodb集群cli实现。

仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别。我开始也不相信必须要有仲裁节点,但是自己也试过没仲裁节点的话,主节点挂了备节点还是备节点,所以咱们还是需要它的。

查看mongodb版本:

root@ubuntu:~# mongod --version
db version v3.6.8
git version: 8e540c0b6db93ce994cc548f000900bdc740f80a
OpenSSL version: OpenSSL 1.1.1f  31 Mar 2020
allocator: tcmalloc
modules: none
build environment:
    distarch: x86_64
    target_arch: x86_64
root@ubuntu:~#

在3个节点修改mongodb service配置文件为以下内容:

root@ubuntu:~# cat /lib/systemd/system/mongodb.service 
[Unit]
Description=An object/document-oriented database
Documentation=man:mongod(1)
After=network.target

[Service]
User=root
Group=root
RuntimeDirectory=mongodb
RuntimeDirectoryMode=0755
EnvironmentFile=-/etc/default/mongodb
Environment=CONF=/etc/mongodb.conf
Environment=SOCKETPATH=/run/mongodb
ExecStart=/usr/bin/mongod --unixSocketPrefix=${SOCKETPATH} --config ${CONF} $DAEMON_OPTS
LimitFSIZE=infinity
LimitCPU=infinity
LimitAS=infinity
LimitNOFILE=64000
LimitNPROC=64000

[Install]
WantedBy=multi-user.target
root@ubuntu:~#

在192.168.2.123、192.168.1.101、192.168.2.125节点 vim 编辑/etc/mongodb.conf,添加副本集名称:

# mongodb.conf

# Where to store the data.
dbpath=/var/lib/mongodb

#where to log
logpath=/var/log/mongodb/mongodb.log

logappend=true

#bind_ip = 127.0.0.1
bind_ip = 0.0.0.0
#port = 27017

# Enable journaling, http://www.mongodb.org/display/DOCS/Journaling
journal=true

# 副本集名称
replSet=ReplicaSet_test

#keyFile默认会开启auth=true
#auth=true
#keyFile=/var/lib/mongodb/key/myKey.txt

初始化副本集:

  • 在3个节点,清空一下目录的历史数据,因为可能以前是用的单机节点,集群部署会有不可预知问题,所以先清空历史数据。
rm -rf   /var/lib/mongodb/*
rm -rf   /var/log/mongodb/mongodb.log
  • 在192.168.2.123、192.168.1.101、192.168.2.125节点,重启动mongodb服务
systemctl restart mongodb
  • 创建副本集:

在mongodb主节点(192.168.1.100)执行命令:

root@ubuntu:~# mongo
MongoDB shell version v3.6.8
connecting to: mongodb://127.0.0.1:27017
Implicit session: session { "id" : UUID("e05fdb96-e520-11eb-a4c8-1bb8ded94398") }
MongoDB server version: 3.6.8
Server has startup warnings: 
2020-04-6T20:46:21.572+0800 I STORAGE  [initandlisten] 
2020-04-6T20:46:21.572+0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2020-04-6T20:46:21.572+0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2020-04-6T20:46:21.843+0800 I CONTROL  [initandlisten] 
2020-04-6T20:46:21.843+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-04-6T20:46:21.843+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2020-04-6T20:46:21.843+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2020-04-6T20:46:21.843+0800 I CONTROL  [initandlisten] 
> use admin
switched to db admin
> config = {_id: "ReplicaSet_test", members: [{_id: 0, host:"192.168.1.100:27017",priority:2}, {_id: 1, host:"192.168.1.101:27017",priority:1}, {_id: 2, host:"192.168.1.102:27017", arbiterOnly : true}]}
{
	"_id" : "ReplicaSet_test",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.1.100:27017",
			"priority" : 2
		},
		{
			"_id" : 1,
			"host" : "192.168.1.101:27017",
			"priority" : 1
		},
		{
			"_id" : 2,
			"host" : "192.168.1.102:27017",
			"arbiterOnly" : true
		}
	]
}
> rs.initiate(config)
{
	"ok" : 1,
	"operationTime" : Timestamp(1626258006, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1626258006, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
ReplicaSet_test:SECONDARY> 
ReplicaSet_test:PRIMARY> 
  • 观察副本集配置:
ReplicaSet_test:PRIMARY> rs.conf()
{
	"_id" : "ReplicaSet_test",
	"version" : 1,
	"protocolVersion" : NumberLong(1),
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.1.100:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 2,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "192.168.1.101:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "192.168.1.102:27017",
			"arbiterOnly" : true,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 0,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		}
	],
	"settings" : {
		"chainingAllowed" : true,
		"heartbeatIntervalMillis" : 2000,
		"heartbeatTimeoutSecs" : 10,
		"electionTimeoutMillis" : 10000,
		"catchUpTimeoutMillis" : -1,
		"catchUpTakeoverDelayMillis" : 30000,
		"getLastErrorModes" : {
			
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"wtimeout" : 0
		},
		"replicaSetId" : ObjectId("60eeba56ae31d40af9119e3f")
	}
}
ReplicaSet_test:PRIMARY>
  • 观察副本集状态:
ReplicaSet_test:PRIMARY> rs.status() 
{
	"set" : "ReplicaSet_test",
	"date" : ISODate("2020-04-6T21:21:51.385Z"),
	"myState" : 1,
	"term" : NumberLong(1),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1626258109, 1),
			"t" : NumberLong(1)
		},
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp(1626258109, 1),
			"t" : NumberLong(1)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1626258109, 1),
			"t" : NumberLong(1)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1626258109, 1),
			"t" : NumberLong(1)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.1.100:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 393,
			"optime" : {
				"ts" : Timestamp(1626258109, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2020-04-6T21:21:49Z"),
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "could not find member to sync from",
			"electionTime" : Timestamp(1626258017, 1),
			"electionDate" : ISODate("2020-04-6T21:20:17Z"),
			"configVersion" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
		{
			"_id" : 1,
			"name" : "192.168.1.101:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 105,
			"optime" : {
				"ts" : Timestamp(1626258109, 1),
				"t" : NumberLong(1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1626258109, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2020-04-6T21:21:49Z"),
			"optimeDurableDate" : ISODate("2020-04-6T21:21:49Z"),
			"lastHeartbeat" : ISODate("2020-04-6T21:21:49.867Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:21:50.613Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "192.168.1.100:27017",
			"syncSourceHost" : "192.168.1.100:27017",
			"syncSourceId" : 0,
			"infoMessage" : "",
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "192.168.1.102:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 105,
			"lastHeartbeat" : ISODate("2020-04-6T21:21:49.863Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:21:50.398Z"),
			"pingMs" : NumberLong(1),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : 1
		}
	],
	"ok" : 1,
	"operationTime" : Timestamp(1626258109, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1626258109, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
ReplicaSet_test:PRIMARY>
  • 在192.168.2.123节点,创建超级管理员账户:
root@ubuntu:~# mongo
MongoDB shell version v3.6.8
connecting to: mongodb://127.0.0.1:27017
Implicit session: session { "id" : UUID("1d3523da-d76f-4c83-af81-36d6128a4eed") }
MongoDB server version: 3.6.8
Server has startup warnings: 
2020-04-6T21:02:04.187+0800 I STORAGE  [initandlisten] 
2020-04-6T21:02:04.187+0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2020-04-6T21:02:04.187+0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2020-04-6T21:04:01.455+0800 I CONTROL  [initandlisten] 
2020-04-6T21:04:01.455+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-04-6T21:04:01.455+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2020-04-6T21:04:01.455+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2020-04-6T21:04:01.455+0800 I CONTROL  [initandlisten] 
ReplicaSet_test:PRIMARY> use admin
switched to db admin
ReplicaSet_test:PRIMARY> db.createUser(
... {
... user: "admin",
... pwd: "123456",
... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
... }
... )
Successfully added user: {
	"user" : "admin",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		}
	]
}
ReplicaSet_test:PRIMARY> db.auth("admin", "123456")
1
ReplicaSet_test:PRIMARY> 
ReplicaSet_test:PRIMARY> db.createUser(
... {
... user: "test",
... pwd: "123456",
... roles: [ { role: "readWrite", db: "test" } ]
... }
... )
Successfully added user: {
	"user" : "test",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "test"
		}
	]
}
ReplicaSet_test:PRIMARY> db.auth("test","123456")
1
ReplicaSet_test:PRIMARY>
  • 副本集初始化后,需要给整个副本集创建帐户、密码, 在192.168.2.123、192.168.1.101、192.168.2.125节点执行命令:

(必须修改/var/lib/mongodb/key/myKey.txt文件权限为600权限,否则无法启动(报错信息是文件权限过大:ACCESS [main] permissions on /var/lib/mongodb/key/myKey.txt are too open))。

root@ubuntu:~# mkdir -p /var/lib/mongodb/key
root@ubuntu:~# chmod 600 /var/lib/mongodb/key
root@ubuntu:~# echo "123456" > /var/lib/mongodb/key/myKey.txt
root@ubuntu:~# chmod 600 /var/lib/mongodb/key/myKey.txt                        
root@ubuntu:~# 

在192.168.2.123、192.168.1.101、192.168.2.125节点,vim 编辑/etc/mongodb.conf文件内容如下:

# mongodb.conf

# Where to store the data.
dbpath=/var/lib/mongodb

#where to log
logpath=/var/log/mongodb/mongodb.log

logappend=true

#bind_ip = 127.0.0.1
bind_ip = 0.0.0.0
#port = 27017

# Enable journaling, http://www.mongodb.org/display/DOCS/Journaling
journal=true

# 副本集名称
replSet=ReplicaSet_test

#keyFile默认会开启auth=true
auth=true
keyFile=/var/lib/mongodb/key/myKey.txt

在192.168.2.123、192.168.1.101、192.168.2.125节点执行命令:

root@ubuntu:~# systemctl restart mongodb
  • 使用key文件加载mongodb副本集后,进入mongo cli,查看集群状态:
    注意:要开启权限:db.grantRolesToUser(“admin”, [“clusterAdmin”])
ReplicaSet_test:PRIMARY> db.auth("admin","123456")
1
ReplicaSet_test:PRIMARY> rs.status()
{
	"operationTime" : Timestamp(1626258754, 1),
	"ok" : 0,
	"errmsg" : "not authorized on admin to execute command { replSetGetStatus: 1.0, lsid: { id: UUID(\"b888bb8c-e521-11eb-a50a-8fb2db155462\") }, $clusterTime: { clusterTime: Timestamp(1626258754, 1), signature: { hash: BinData(0, 3A4FB4B97511C70B6A0585762A4E9D060E64766E), keyId: 15472389856/4174109 } }, $db: \"admin\" }",
	"code" : 13,
	"codeName" : "Unauthorized",
	"$clusterTime" : {
		"clusterTime" : Timestamp(1626258754, 1),
		"signature" : {
			"hash" : BinData(0,"Ok+0uXURxwtqBYV2Kk6dBg5kdm4="),
			"keyId" : NumberLong("15472389856/4174109")
		}
	}
}

报错原因分析:

因为admin用户没有执行这个命令的权限,给admin用户赋予集群管理的权限,将admin用户和test用户添加副本集管理员权限:db.grantRolesToUser(“admin”, [“clusterAdmin”])


root@ubuntu:~# mongo
MongoDB shell version v3.6.8
connecting to: mongodb://127.0.0.1:27017
Implicit session: session { "id" : UUID("6b38a8a0-e522-11eb-a163-333897329773") }
MongoDB server version: 3.6.8
ReplicaSet_test:PRIMARY> use admin
switched to db admin
ReplicaSet_test:PRIMARY> db.auth("admin","123456")
1
ReplicaSet_test:PRIMARY> db.grantRolesToUser("admin", ["clusterAdmin"])
ReplicaSet_test:PRIMARY> rs.status()
{
	"set" : "ReplicaSet_test",
	"date" : ISODate("2020-04-6T21:35:05.209Z"),
	"myState" : 1,
	"term" : NumberLong(3),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1626198192, 1),
			"t" : NumberLong(3)
		},
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp(1626198192, 1),
			"t" : NumberLong(3)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1626198192, 1),
			"t" : NumberLong(3)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1626198192, 1),
			"t" : NumberLong(3)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.1.100:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 279,
			"optime" : {
				"ts" : Timestamp(1626198192, 1),
				"t" : NumberLong(3)
			},
			"optimeDate" : ISODate("2020-04-6T21:34:57Z"),
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"electionTime" : Timestamp(1626198192, 1),
			"electionDate" : ISODate("2020-04-6T21:31:53Z"),
			"configVersion" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
		{
			"_id" : 1,
			"name" : "192.168.1.101:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 202,
			"optime" : {
				"ts" : Timestamp(1626198192, 1),
				"t" : NumberLong(3)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1626198192, 1),
				"t" : NumberLong(3)
			},
			"optimeDate" : ISODate("2020-04-6T21:34:57Z"),
			"optimeDurableDate" : ISODate("2020-04-6T21:34:57Z"),
			"lastHeartbeat" : ISODate("2020-04-6T21:35:03.541Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:35:04.157Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "192.168.1.100:27017",
			"syncSourceHost" : "192.168.1.100:27017",
			"syncSourceId" : 0,
			"infoMessage" : "",
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "192.168.1.102:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 181,
			"lastHeartbeat" : ISODate("2020-04-6T21:35:03.640Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:35:04.681Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : 1
		}
	],
	"ok" : 1,
	"operationTime" : Timestamp(1626198192, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1626198192, 1),
		"signature" : {
			"hash" : BinData(0,"qP60+nBufcFpMn5bA6hYqFgn4JU="),
			"keyId" : NumberLong("15472389856/4174109")
		}
	}
}
ReplicaSet_test:PRIMARY>

二、测试mongodb副本集

1 查看mongodb副本集角色:

ReplicaSet_test:PRIMARY> rs.status()
{
	"set" : "ReplicaSet_test",
	"date" : ISODate("2020-04-6T21:49:49.750Z"),
	"myState" : 1,
	"term" : NumberLong(3),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1626259784, 1),
			"t" : NumberLong(3)
		},
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp(1626259784, 1),
			"t" : NumberLong(3)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1626259784, 1),
			"t" : NumberLong(3)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1626259784, 1),
			"t" : NumberLong(3)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.1.100:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 1163,
			"optime" : {
				"ts" : Timestamp(1626259784, 1),
				"t" : NumberLong(3)
			},
			"optimeDate" : ISODate("2020-04-6T21:49:44Z"),
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"electionTime" : Timestamp(1626258713, 1),
			"electionDate" : ISODate("2020-04-6T21:31:53Z"),
			"configVersion" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
		{
			"_id" : 1,
			"name" : "192.168.1.101:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 1086,
			"optime" : {
				"ts" : Timestamp(1626259784, 1),
				"t" : NumberLong(3)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1626259784, 1),
				"t" : NumberLong(3)
			},
			"optimeDate" : ISODate("2020-04-6T21:49:44Z"),
			"optimeDurableDate" : ISODate("2020-04-6T21:49:44Z"),
			"lastHeartbeat" : ISODate("2020-04-6T21:49:48.469Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:49:49.084Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "192.168.1.100:27017",
			"syncSourceHost" : "192.168.1.100:27017",
			"syncSourceId" : 0,
			"infoMessage" : "",
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "192.168.1.102:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 1066,
			"lastHeartbeat" : ISODate("2020-04-6T21:49:48.514Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:49:49.684Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : 1
		}
	],
	"ok" : 1,
	"operationTime" : Timestamp(1626259784, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1626259784, 1),
		"signature" : {
			"hash" : BinData(0,"zcoriua7yyetYyg3PZCDp6+53sM="),
			"keyId" : NumberLong("15472389856/4174109")
		}
	}
}
ReplicaSet_test:PRIMARY> 
ReplicaSet_test:PRIMARY> quit()
root@ubuntu:~#

2 关闭master节点(192.168.1.100),查看主节点切换:

在192.168.2.123节点执行命令,关掉master的mongodb服务:

root@ubuntu:~# systemctl stop mongodb

在192.168.2.124节点(slave节点)查看副本当前状态,发现master挂掉后,slave成为了副本集的主节点:

root@ubuntu:~# mongo
MongoDB shell version v3.6.8
connecting to: mongodb://127.0.0.1:27017
Implicit session: session { "id" : UUID("d669714a-e522-11eb-bd07-bb29e6d39677") }
MongoDB server version: 3.6.8
ReplicaSet_test:PRIMARY> use admin
switched to db admin
ReplicaSet_test:PRIMARY> db.auth("admin","123456")
1
ReplicaSet_test:PRIMARY> rs.status()
{
	"set" : "ReplicaSet_test",
	"date" : ISODate("2020-04-6T21:53:02.479Z"),
	"myState" : 1,
	"term" : NumberLong(4),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1626259924, 1),
			"t" : NumberLong(3)
		},
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp(1626259924, 1),
			"t" : NumberLong(3)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1626259975, 1),
			"t" : NumberLong(4)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1626259975, 1),
			"t" : NumberLong(4)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.1.100: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("2020-04-6T21:53:01.916Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:52:12.626Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "Connection refused",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : -1
		},
		{
			"_id" : 1,
			"name" : "192.168.1.101:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 1283,
			"optime" : {
				"ts" : Timestamp(1626259975, 1),
				"t" : NumberLong(4)
			},
			"optimeDate" : ISODate("2020-04-6T21:52:55Z"),
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "could not find member to sync from",
			"electionTime" : Timestamp(1626259943, 1),
			"electionDate" : ISODate("2020-04-6T21:52:23Z"),
			"configVersion" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
		{
			"_id" : 2,
			"name" : "192.168.1.102:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 1259,
			"lastHeartbeat" : ISODate("2020-04-6T21:53:01.861Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:53:01.888Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : 1
		}
	],
	"ok" : 1,
	"operationTime" : Timestamp(1626259975, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1626259975, 1),
		"signature" : {
			"hash" : BinData(0,"RznptKOp1H535+y+ki/UZqoOhTY="),
			"keyId" : NumberLong("15472389856/4174109")
		}
	}
}
ReplicaSet_test:PRIMARY> 

3 关闭master节点(192.168.1.100),查看主节点恢复:

打开192.168.2.123节点的mongodb服务:

systemctl start mongodb

查看当前mongodb副集的状态,发现192.168.2.123已经恢复成了主节点的身份:

ReplicaSet_test:SECONDARY> rs.status()
{
	"set" : "ReplicaSet_test",
	"date" : ISODate("2020-04-6T21:55:52.681Z"),
	"myState" : 2,
	"term" : NumberLong(5),
	"syncingTo" : "192.168.1.100:27017",
	"syncSourceHost" : "192.168.1.100:27017",
	"syncSourceId" : 0,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1626260145, 1),
			"t" : NumberLong(5)
		},
		"readConcernMajorityOpTime" : {
			"ts" : Timestamp(1626260145, 1),
			"t" : NumberLong(5)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1626260145, 1),
			"t" : NumberLong(5)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1626260145, 1),
			"t" : NumberLong(5)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.1.100:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 28,
			"optime" : {
				"ts" : Timestamp(1626260145, 1),
				"t" : NumberLong(5)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1626260145, 1),
				"t" : NumberLong(5)
			},
			"optimeDate" : ISODate("2020-04-6T21:55:45Z"),
			"optimeDurableDate" : ISODate("2020-04-6T21:55:45Z"),
			"lastHeartbeat" : ISODate("2020-04-6T21:55:51.380Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:55:52.438Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"electionTime" : Timestamp(1626260134, 1),
			"electionDate" : ISODate("2020-04-6T21:55:34Z"),
			"configVersion" : 1
		},
		{
			"_id" : 1,
			"name" : "192.168.1.101:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 1453,
			"optime" : {
				"ts" : Timestamp(1626260145, 1),
				"t" : NumberLong(5)
			},
			"optimeDate" : ISODate("2020-04-6T21:55:45Z"),
			"syncingTo" : "192.168.1.100:27017",
			"syncSourceHost" : "192.168.1.100:27017",
			"syncSourceId" : 0,
			"infoMessage" : "",
			"configVersion" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
		{
			"_id" : 2,
			"name" : "192.168.1.102:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 1429,
			"lastHeartbeat" : ISODate("2020-04-6T21:55:51.541Z"),
			"lastHeartbeatRecv" : ISODate("2020-04-6T21:55:52.046Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncingTo" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : 1
		}
	],
	"ok" : 1,
	"operationTime" : Timestamp(1626260145, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1626260145, 1),
		"signature" : {
			"hash" : BinData(0,"3+5Uill5sMmjXikoz+aZ4Ky4hqY="),
			"keyId" : NumberLong("15472389856/4174109")
		}
	}
}
ReplicaSet_test:SECONDARY> 
上一篇:理解ProcessFunction的Timer逻辑


下一篇:LC981-基于时间的键值存储