1.副本集的原理和安装
1.1MongoDB单台服务器的缺点
1.2MongoDB副本集的优点:
1.3副本集功原理介绍:
1.4副本集集群安装
2.副本集验证写入和同步操作:
3.mongodb副本集的优先级
4.mongodb副本集的伸缩
1.副本集的原理和安装
1.1MongoDB单台服务器的缺点
数据会丢失的风险
单台服务器无法做到高可用
1.2MongoDB副本集的优点:
MongoDB副本集能够预防数据丢失,多台MongoDB数据一致。
MongoDB副本集能够在出问题的时候自动切换primary节点,保证服务的一个正常运行。
1.3副本集功原理介绍:
副本集就是mongoDB副本所组成的一个集群。原理是,写操作发生在主库,从库同步主库的OpLog日志,根据日志将数据同步到自己机器上。
集群中没有特定的主库,主库是选举产生,如果主库down了,会再选举出一台主库。
1.4副本集集群安装
实际情况:MongoDB副本集最少是三台集群。
机器 | 172.18.1.23 | 172.18.1.24 | 172.18.1.25 |
角色 | 副本集 | 副本集 | 副本集 |
端口 | 27017 | 27017 | 27017 |
部署方案和单节点部署方案大体一致,副本集配置文件在config.conf中的内容如下,配置完后发送到其他两台机器。
vim /opt/mongodb/conf/config.conf #添加一下内容
## 配置文件内容
systemLog:
logAppend: true
path: "/opt/mongodb/log/mongodb.log" #存放日志的地方
destination: file
processManagement:
fork: true
pidFilePath: "/opt/mongodb/mongod.pid"
net:
port: 27017 #端口,为安全起见,可以使用其他端口
bindIp: "0.0.0.0" #生产环境使用127.0.0.1
storage:
dbPath: "/opt/mongodb/data" #存放数据的地方
journal:
enabled: true
#副本集名称 #比单点部署多的地方,设定副本集
replication:
replSetName: bfd
启动三台MongoDB服务器:(三台机器均要启动),至于加上numactl是因为在单节点部署的时候,有一个警告,需要加上。
numactl --interleave=all mongod -f /opt/mongodb/conf/config.conf
MongoDB副本集初始化及其状态查看
#连接,选择任意一台进入
mongo --port 27017
#定义config变量,下面的操作是在admin数据库进行的
> use admin
> config = {
... _id : "bfd", #这里和前面配置文件中副本集是一样的。
... members : [
... {_id : 0, host : "172.18.1.23:27017" },
... {_id : 1, host : "172.18.1.24:27017" },
... {_id : 2, host : "172.18.1.25:27017" }
... ]
... }
#初始化副本集
> rs.initiate(config)
{
"ok" : 1,
"operationTime" : Timestamp(1543312919, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1543312919, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
查看副本集状态,一个primary节点,两个secondary节点才对。
#查看副本集状态,部分不重要的内容省略了。
bfd:SECONDARY> rs.status()
{
"set" : "bfd",
"date" : ISODate("2018-11-27T10:03:48.772Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
... #省略了
},
"lastStableCheckpointTimestamp" : Timestamp(1543312984, 4),
"members" : [
{
"_id" : 0,
"name" : "172.18.1.23:27017", #第一个节点
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY", #主节点
"uptime" : 345,
"optime" : {
"ts" : Timestamp(1543313021, 1),
"t" : NumberLong(1)
},
...... #省略了
},
{
"_id" : 1,
"name" : "172.18.1.24:27017", #第二个节点
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY", #secondary节点
"uptime" : 109,
"optime" : {
"ts" : Timestamp(1543313021, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1543313021, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-11-27T10:03:41Z"),
...... #省略了
"configVersion" : 1
},
{
"_id" : 2,
"name" : "172.18.1.25:27017", #第三个节点
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY", #secondary节点
"uptime" : 109,
"optime" : {
"ts" : Timestamp(1543313021, 1),
"t" : NumberLong(1)
},
.... #省略了
}
],
"ok" : 1,
"operationTime" : Timestamp(1543313021, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1543313021, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
bfd:PRIMARY> #这时候23机器就变成主节点了,通过选举产生了主节点。
总结:
其中,"_id" : "bfd"应与配置文件中配置的 replicaction.replSetName 一致,"members" 中的 "host" 为三个节点的 ip 和 port 。rs.status() #查看副本集状态,一个primary,其他的都是secondary,primary是主,并且只有primary才可以写入数据,secondary可以读取数据。
2.副本集验证写入和同步操作:
在primary上写入数据,在secondary角色上进行查看数据是否同步到该机器上
#目前机器是23,主节点
bfd:PRIMARY> use student;
switched to db student
bfd:PRIMARY> db.people.insert({'name':'张三','age':18})
WriteResult({ "nInserted" : 1 })
bfd:PRIMARY> db.people.find()
{ "_id" : ObjectId("5bfd225ced5be3d813de55c6"), "name" : "张三", "age" : 18 }
#我们到24机器上查看,记得要执行rs.slaveOk(),否则show dbs,会报一下面的错误 "errmsg" : "not master and slaveOk=false",
[root@bfd-yiz-1p24 mongodb]# mongo --port 27017
bfd:SECONDARY> rs.slaveOk()
bfd:SECONDARY> show dbs;
admin 0.000GB
config 0.000GB
local 0.000GB
student 0.000GB
bfd:SECONDARY> use student;
switched to db student
bfd:SECONDARY> db.people.find()
{ "_id" : ObjectId("5bfd225ced5be3d813de55c6"), "name" : "张三", "age" : 18 } #我们看到数据已经自动被同步到24机器上了,同理25机器上也同步到该数据了。
bfd:SECONDARY> db.people.insert({'name':'李四','age':20}) #我们在24机器上也就当前角色下,进行写入操作,发现只有master也就是primary才可以写入。
WriteCommandError({
"operationTime" : Timestamp(1543316491, 1),
"ok" : 0,
"errmsg" : "not master",
"code" : 10107,
"codeName" : "NotMaster",
"$clusterTime" : {
"clusterTime" : Timestamp(1543316491, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
})
MongoDB的副本集的自动切换
当MongoDB的副本集primary挂了,会挑选其中的一台secondar升为主。
当我们关闭掉23上的primary节点时,发现第二张图中的24节点上升为primary节点。
当我们停掉23机器上的primary节点时候,我们发现24机器就上升为primary节点。
通过rs.status(),发现只有2个节点了。其中一个为主,一个为从。
bfd:PRIMARY> rs.status() #此时应该就剩下2个节点,因为23服务已经停了。
{
"set" : "bfd",
"date" : ISODate("2018-11-27T11:07:55.330Z"),
"myState" : 1,
"term" : NumberLong(2),
{
"_id" : 1,
"name" : "172.18.1.24:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY", #24变成主节点
"uptime" : 4135,
"optime" : {
"ts" : Timestamp(1543316874, 1),
"t" : NumberLong(2)
},
{
"_id" : 2,
"name" : "172.18.1.25:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY", #25还是secondary节点
"uptime" : 3953,
"optime" : {
"ts" : Timestamp(1543316874, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1543316874, 1),
"t" : NumberLong(2)
},
}
],
}
至此,mongodb的副本集部署已经完成,停掉的节点记得要恢复。
3.mongodb副本集的优先级
mongodb副本集的主的选举原理:
primary的选举依赖于各个实例的优先权重,默认权重都是1
可以分配各个实例的优先权重,挑选自己喜欢的实例为主,注意只有primary可以更改权重配置,首先我们看一下默认的权重是多少。
bfd:PRIMARY> rs.config() #可以看到下面各个节点权重都为1
{
"_id" : "bfd",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "172.18.1.23:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1, #权重为1
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "172.18.1.24:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1, #权重为1
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "172.18.1.25:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1, #权重为1
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
..... #部分内容已经省略。
}
设定权重值,23权重为10,24为5,25为2,当我们把23上的节点给停掉后,默认24为primary节点,在24上进行下面的操作。当我们能把23上服务给起起来,不过此时23为secondary角色。
bfd:PRIMARY> conf=rs.config()
bfd:PRIMARY> conf.members[0].priority = 10
10
bfd:PRIMARY> conf.members[1].priority = 5
5
bfd:PRIMARY> conf.members[2].priority = 2
2
bfd:PRIMARY> conf #查看发现权重已经发生了变化
{
"_id" : "bfd",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "172.18.1.23:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 10, #变成了10
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "172.18.1.24:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 5, #变成了5
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "172.18.1.25:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2, #变成了2
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
}
修改完权重后还要更新mongodb的副本集的配置,更新完后优先级高的提供为主,关闭后再启动也可以。这里使用刷新配置操作。
由于上面的操作,目前primary是24机器,刷新后,primary应该变成23机器。
bfd:PRIMARY>rs.reconfig(conf)
{
"ok" : 1,
"operationTime" : Timestamp(1543318182, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1543318182, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
24机器上的变化:(一直按enter键即可),发现连接失败,紧接着primary又变回了secondary角色了。
发现23从secondary角色变成了primary角色,因为它的权重最大,如下所示:23机器上的变化:(一直按enter键即可)
4.mongodb副本集的伸缩
mongodb副本集伸缩说明:
mongodb副本集的扩展非常好,往副本集群里添加和删除实例都非常方便
mongodb副本集添加实例,数据能够自动同步到新的实例中,无需人工干预。
往现有的mongodb副本中添加实例
比如创建一个新的实例,172.18.1.26:27017,注意副本集名称要和之前的副本集名称一致。
use admin
rs.add("172.18.1.26:27017") #添加进来的新的实例,过一会就会有数据同步过来,这里不做演示了。
#rs.add添加进来的新实例的默认权重为1
往现有的mongodb副本中移除实例,注意不可移除primary节点。
use admin
rs.remove("172.18.1.26:27017") #添加进来的新的实例,过一会就会有数据同步过来,这里不做演示了。
#副本集通过添加和删除后顺序可能会乱,就是上面的members[0]对应的节点信息可能就不是之前的节点信息了.设置权重的时候要注意一下。