mongodb-03 副本集

MongoDB副本集的角色

副本集中数据同步过程

Primary节点写入数据,Secondary通过读取Primaryoplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog

如果某个操作失败,则备份节点停止从当前数据源复制数据。

如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog。

由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。

简单的说就是:

当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步:

1:检查自己local库的oplog.rs集合找出最近的时间戳。

2:检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。

3:将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。

local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小可以在启动参数中设 定:--oplogSize 1000,单位是M。

注意:在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。

以下情况需要考虑oplog 的大小:

1.同时对多个文档进行更新:这些操作会转换成幂等操作

2.以相同速度发生的涉及等数据量的删除和插入

3.大量的就地更新

各种情况下的同步状态:

1.初始化同步与复制

1.节点首次启动(新节点无数据)
2.节点变得过时(主节点已经重写了oplog,该节点并没有复制数据)这种情况下,从库数据将被移除
# 同步的具体步骤为:
1.所有的数据库会被克隆
2.使用源节点的oplog,变更会被应用到其数据集
3.最后在所有的集合上创建索引

2.正常操作--同步

正常情况下,辅助节点会选择一个成员来同步其数据,然后从其源的oplog中拉取操作
1.先将其操作应用到副本集
2.将op写入本地oplog中
3.一旦op写入到oplog中,继续请求下个oplog。
如果1 和 2 步骤之间失败了,那么就重头执行这些步骤。它会假设该操作还没执行过。
由于oplog是幂等的因此相同的操作可以被应用任意次数。

3.节点刚启动

当一个节点被启动时,会检查本地集合的lastOpTimeWritten。在该辅助节点上的最后一个op的时间
如果一个成员启动并找到ts条目,将会选择一个目标来从其进行同步并作为一个正常的同步过程。
如果没有找到ts条目,该节点会进行初始化同步过程。

副本集架构详解

1. Primary --- > 默认情况下,读写都是在Primary上操作的。

2. Secondary  --> 通过oplog来重放Primary上的所有操作,拥有Primary节点数据的完整拷贝。默认情况下,不可写,也不可读。

根据不同的需求,Secondary又可配置为如下形式:

1> Priority 0 Replica Set Members

优先级为0的节点,优先级为0的成员永远不会被选举为primary。在mongoDB副本集中,允许给不同的节点设置不同的优先级。
优先级的取值范围为0
-1000,可设置为浮点数,默认为1。拥有最高优先级的成员会优先选举为primary。 譬如,在副本集中添加了一个优先级为2的成员node3:27020,而其它成员的优先级为1, 只要node3:27020拥有最新的数据,那么当前的primary就会自动降级,node3:27020将会被选举为新的primary节点,
但如果node3:27020中的数据不够新,则当前primary节点保持不变,直到node3:27020的数据更新到最新。

2> Hidden Replica Set Members-隐藏节点

隐藏节点的优先级同样为0,同时对客户端不可见

使用rs.status()和rs.config()可以看到隐藏节点,但是对于db.isMaster()不可见。客户端连接到副本集时,会调用db.isMaster()命令来查看可用成员信息。

所以,隐藏节点不会受到客户端的读请求。

隐藏节点常用于执行特定的任务,譬如报表,备份,选举。

3> Delayed Replica Set Members-延迟节点

延迟节点会比primary节点延迟指定的时间(通过slaveDelay参数来指定)延迟节点必须是隐藏节点。

4> Arbiter

仲裁节点,只是用来投票,且投票的权重只能为1,不复制数据,也不能提升为primary。

仲裁节点常用于节点数量是偶数的副本集中。

建议:通常将Arbiter部署在业务服务器上,切忌将其部署在Primary节点或Secondary节点服务器上。

注:一个副本集最多有50个成员节点,7个投票节点。

mongodb 副本集能解决的问题:

  • 主节点挂了能否自动切换连接?目前需要手工切换。
  • 主节点的读写压力过大如何解决?
  • 从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大?
  • 数据压力大到机器支撑不了的时候能否做到自动扩展?

设置一个成员的选票为0 来禁用该成员的投票功能。可以担当候选人,但是不能进行投票。

cfg_1 = rs.conf()

cfg_1.members[3].votes=0

 副本集搭建步骤

1.创建各种目录

sudo mkdir -p data/mongodb2.4/repl/{data,log}

2.配置文件:mongod.conf

dbpath=/data/mongodb2.4/repl/data

logpath=/data/mongodb2.4/repl/log/mongod.log

port=27091

logappend=true

fork=true

replSet=repset

maxConns=20000

3.启动mongo

sudo /usr/local/mongodb2.4/bin/mongod -f /data/mongodb2.4/repl/mongod.conf

4.、初始化副本集

在任意一台机器上登陆mongo

#定义副本集配置变量,这里的 _id:”repset” 和配置文件中replSet=repset要保持一样

use admin

> config={_id:'repset',members:[

... {_id:0,host:'10.1.3.67:27091'},

... {_id:1,host:'10.1.3.68:27091'},

... {_id:2,host:'10.1.3.69:27091'}]

... }

##输出内容

{"_id" : "repset",

"members" : [ {"_id" : 0,"host" : "10.1.3.67:27091"}, {"_id" : 1,"host" : "10.1.3.68:27091"}, {"_id" : 2,"host" : "10.1.3.69:27091"} ]} ##初始化副本集配置 rs.initiate(config) > rs.initiate(config) { "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 } #查看日志,确定没有问题 $ sudo tail -100 mongod.log

#查看各个节点状态:

rs.status()

#查看复制的情况

mongotag:SECONDARY> db.printReplicationInfo()
configured oplog size:   10000MB
log length start to end: 11216395secs (3115.67hrs)
oplog first event time:  Sun Dec 03 2017 15:54:02 GMT+0800 (CST)
oplog last event time:   Thu Apr 12 2018 11:33:57 GMT+0800 (CST)
now:                     Thu Apr 12 2018 11:33:57 GMT+0800 (CST)

db.printSlaveReplicationInfo()

mongotag:SECONDARY> db.printSlaveReplicationInfo()
source:   10.1.5.112:27017
         syncedTo: Thu Apr 12 2018 11:34:12 GMT+0800 (CST)
                 = 1 secs ago (0hrs)
source:   10.1.5.112:27018
         no replication info, yet.  State: ARBITER

source:从库的ip和端口。

syncedTo:目前的同步情况,以及最后一次同步的时间。

#查看副本集的配置

rs.conf()/rs.config()

mongotag:PRIMARY> rs.config()
{
  "_id" : "mongotag",
  "version" : 163950,
  "members" : [
{
  "_id" : 2,
  "host" : "10.1.5.112:27017",
  "priority" : 6
},
{
  "_id" : 3,
  "host" : "10.1.5.111:27017",
  "priority" : 10
},
{
  "_id" : 4,
  "host" : "10.1.5.112:27018",
  "arbiterOnly" : true
}]
}

#增加/删除节点

repset:PRIMARY> rs.add('10.1.3.68:27091')

repset:PRIMARY> rs.remove('10.1.3.68:27091')

#mongodb默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读。

repset:SECONDARY> db.getMongo().setSlaveOk() #此操作只对当前连接有效

repset:SECONDARY> show tables
col
system.indexes

repset:SECONDARY> db.col.find()

{ "_id" : ObjectId("5a0b9f9646d897f6484a6719"), "name" : "repset" }

副本集的实际应用场景

(1).手动切换Primary节点到自己给定的节点

优先级priority,因为默认的都是1,所以只需要把给定的服务器的priority加到最大即可

#修改新master的优先级

cfg=rs.conf()

repset:PRIMARY> cfg.members[0].priority=2

2

#重载配置,强制了副本集进行一次选举,优先级高的成为Primary

repset:PRIMARY> re.reconfig(cfg)

(2) 添加仲裁节点

#删除一个节点并重启

repset:PRIMARY> rs.remove('10.1.3.69:27091')

#添加删除的节点使其成为arbiter

repset:PRIMARY> rs.addArb('10.1.3.69:27091')此操作会导致关机。。。。。

#查看副本集的状态

rs.status() / rs.conf()

当所有的Secondary都宕机、或则副本集中只剩下一个节点,则该节点只能为Secondary节点,也就意味着整个集群智能进行读操作而不能进行写操作,当其他的恢复时,

之前的primary节点仍然是primary节点。

当某个节点宕机后重新启动该节点会有一段的时间(时间长短视集群的数据量和宕机时间而定)导致整个集群中所有节点都成为secondary而无法进行写操作(如果应用程序没有设置相应的ReadReference也可能不能进行读取操作)。

副本集要求参与选举投票(vote)的节点数为奇数,当我们实际环境中因为机器等原因限制只有两个(或偶数)的节点,这时为了实现 Automatic Failover引入另一类节点:仲裁者(arbiter,仲裁者只参与投票不拥有实际的数据,并且不提供任何服务,因此它对物理资源要求不严格。

通过实际测试发现,当整个副本集集群中达到50%的节点(包括仲裁节点)不可用的时候,剩下的节点只能成为secondary节点,整个集群只能读不能 写。

比如集群中有1个primary节点,2个secondary节点,加1个arbit节点时:当两个secondary节点挂掉了,那么剩下的原来的 primary节点也只能降级为secondary节点;

当集群中有1个primary节点,1个secondary节点和1个arbit节点,这时即使 primary节点挂了,剩下的secondary节点也会自动成为primary节点。因为仲裁节点不复制数据,因此利用仲裁节点可以实现最少的机器开 销达到两个节点热备的效果。

(3) 添加隐藏节点

hidden(成员用于支持专用功能):这样设置后此机器在读写中都不可见,并且不会被选举为Primary,但是可以投票,一般用于备份数据。

本实验将hidden节点和arbiter放在一个机器上

#添加节点

repset:PRIMARY> rs.add({_id:1,host:'10.1.3.69:27092',priority:0,hidden:true})

#查看

repset:PRIMARY> rs.conf()

{

"_id" : "repset",

"version" : 7,

"members" : [

{

"_id" : 0,

"host" : "10.1.3.67:27091",

"priority" : 2

},

{

"_id" : 3,

"host" : "10.1.3.68:27091"

},

{

"_id" : 4,

"host" : "10.1.3.69:27091",

"arbiterOnly" : true

},

{

"_id" : 1,

"host" : "10.1.3.69:27092",

"priority" : 0,

"hidden" : true

}]}

(4)添加延迟节点

Delayed(成员用于支持专用功能):可以指定一个时间延迟从primary节点同步数据。主要用于处理误删除数据马上同步到从节点导致的不一致问题。

rs.add({"_id":3,"host":"192.168.200.25:27017","priority":0,"hidden":true,"slaveDelay":60})

Secondary-Only:不能成为primary节点,只能作为secondary副本节点,防止一些性能不高的节点成为主节点。

Non-Voting:没有选举权的secondary节点,纯粹的备份数据节点。

 

posted @ 2018-04-13 11:13  Sin-是我的海  阅读(161)  评论(0)    收藏  举报