MongoDB中副本集-Replication

之前的博文 MongoDB主从复制架构中 ,讲述了MongoDB用来实现数据冗余的一种方式,也提到了主从复制的缺点,当主节点出现故障时,数据库服务不可用,因此很多数据库也都选择了新的方式替代主从复制 , 比如MongoDB的复制集、redis的哨兵机制等,本文就是描述 MongoDB的复制集的相关特性。

1. MongoDB中副本集的特点

副本集(或者叫复制集,名字无所谓)是MongoDB用来实现数据冗余的另一个方式,基本架构和主从复制基本一致,如下图所示
在这里插入图片描述
不同之处是

  • 主从复制中,需要显示指定主服务器和从服务器,并且主服务器挂掉后,需要用户手动选择一个从服务器作为新的主服务器
  • 而 ”副本集“模式下,可以做到自动将其中一个成员升级为新的主服务器

总结一下,MongoDB中副本集,有如下的特点

N 个节点的集群
任何节点可作为主节点
所有写入操作都在主节点上
自动故障转移
自动恢复

当然为了实现自动讲一个成员升级为新的主服务器,副本集除了配置搭建过程和“主从复制”的过程不一样,还需要额外增加一些处理

  1. 正常运行中
    各个主从节点的状态 ,如下图 ,彼此之间,利用心跳协议相互检测,判断对方是不是还活着(还能连接到); 当进行写操作时,主节点将数据同步到各个secondary
    在这里插入图片描述
    此外,还有一种节点,不保存数据,只负责在主节点挂掉之后,投票从“从节点”中选择新的主节点,结构如下
    在这里插入图片描述
  2. 当节点发生了问题
    这种情况下, 投票节点,选举产生新的主节点,并形成新的主从结构,过程如下图 在这里插入图片描述
2 . 搭建的基本步骤

在MongoDB中,非常灵活的实现了副本集的功能,可以通过配置项指定副本集, 后期也可以通过命令动态添加节点。我们在配置好了副本集中的主节点之后,可以灵活的选择,通过配置项指定,或者是通过添加节点命令添加,在下边的步骤中,我们先配置一个主节点, 两个从节点,再利用添加节点的命令,动态添加第三个节点,基本步骤如下

为了是程序建的条理,我们对每一个MongoDB实例,都会建立单独的目录

  1. 为每个实例建立单独的文件夹

    mkdir mongo_repli_set_master
    mkdir mongo_repli_set_slave1
    mkdir mongo_repli_set_slave2
    mkdir mongo_repli_set_avater
    

    bin 目录可以共用一个,也可以直接把一个实例的bin也copy出多份,每个实例的目录如下

    cd mongo_repli_set_master
    mkdir bin # 保存包含一些mongod mongo命令等
    mkdir data # 保存数据文件
    mkdir log # 保存日志文件
    sudo vi mongod.config # 配置文件,启动时需要带上
    

    查看文件夹是否有权限,没有读、写、可执行权限的话,需要修改权限

    ls -l data
    
  2. 编辑配置文件
    配置文件中,只需要指定配置集的名字即可 (第五步时,会用到),如下

    replSet=myRepl #复制集的名称	
    oplogSize=1024 #Select the replication log size
    

    简单的配置文件(完整的),如下

    #一些基本的配置
    dbpath = data/db # 用的相对bin目录的 “相对目录”,建议用绝对目录
    logpath =  log/mongodb/mongo.log
    logappend = true
    # 绑定id后,只可以利用ip访问 ,并且只可以利用这个ip访问 
    bind_ip =  192.168.0.126
    port=27110 # 指定主服务器的端口
    maxConns=100 #最大同时连接数 
    journal=true #每次写入会记录一条操作日志(通过journal可以重新构造出写入的数据)
    replSet=myRepl #复制集的名称	
    oplogSize=1024 #Select the replication log size
    

    不同的实例,通过修改端口,模拟,其他选项可以不用修改 (因为本文中每个实例的基本目录都是一样的)

  3. 分别启动三个实例
    通过shell命令启动,进入各自的目录中,直接mongod

    cd mongo_repli_set_master
    bin/mongod --config mongod.conf
    

    查看日志文件,确定是否启动成功。

  4. 连接到一个用作主节点的MongoDB数据库,进行复制集节点配置
    比如本文中,想把27110端口的MongoDB实例,作为primary (主节点),可以连接到27110, 进行配置,如下

     > mongo 192.168.0.126:27110
     > cfg = {"_id" : "myRepl", "members" : [
        {"_id" : 0,"host" : "192.168.0.126:27110"},
        {"_id" : 1,"host" : "192.168.0.126:27111"}
        ]}
      > rs.initiate(cfg);
    

    简单说一下,上边的initiate命令 。 通过配置项初始化复制集的节点信息,各个配置项的意思 (上边cfg中各个数据的意思)

    cfg = {"_id" : "复制集的名称", "members" : [ {"_id" : 0,"host" : "主节点ip:主节点端口号"}]}
    

    _id 就是复制集的名称,需要和配置文件中的名称一致。 members 是复制集中的成员,是一个数组,可以配置一到多个, 每个成员配置中,需要指定host ,_id是自增的整数。
    如果执行成功,会有如下提示信息,并且进入primary的命令行,如下

    {
       "ok" : 1,
       "operationTime" : Timestamp(1571392081, 1),
       "$clusterTime" : {
       	"clusterTime" : Timestamp(1571392081, 1),
       	"signature" : {
       		"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
       		"keyId" : NumberLong(0)
       	}
       }
    }
    myRepl:SECONDARY> 
    
  5. 运行之后,一些动态修改节点命令,查看节点状态
    上边指定了两个节点,如果需要继续添加节点,或者删除不想要的节点,可以用下边的命令

    rs.add("192.168.0.126:27112")
    rs.remove("192.168.100.201:27019")
    

    添加投票节点:

    rs.addArb("192.168.0.126:27113")
    

    查看节点的状态,查看是否是主节点

    rs.status() #查看复制集结果
    rs.isMaster() # 查看是否是主节点
    
  6. 模拟测试
    上边的复制集搭建成功之后,可以进行一些测试,比如
    主节点插入数据,查看从节点是否用数据

    # 连接到主节点,新建数据库,插入数据
    mongo 192.168.0.126:27110
    use schdb  db.teacher.insert({a:1})
    #连接到从节点,查看是否存在数据
    mongo 192.168.0.126:27110
    rs.slaveOk() # 默认情况下,从节点无法读取数据,需要执行该命令
    use schdb 
    db.teacher.find()
    

    主节点挂掉,是否会自动选举新的主节点,通过kill杀进程的方式,模拟测试, 这里有个小技巧,就是在启动每个MongoDB进程的时候,都记录一下其进程信息(包括进程Id等),这样可以在杀进程的时候,知道哪个是主节点 ,哪个是从节点,哪个是投票节点

    kill 10604  #杀掉主节点
    

    连接到剩余的从节点, 查看结果, 发现一个从节点变成了主节点

    mongo 192.168.0.126 :27112  # 发现变成了主节点
    
3. 投票选举规则
  • 投票的原则

    在进行投票的时候, 如果 某一节点投票数占当前架构中多数,那么该节点就会成为新的主节点。 比如一个副本集架构中, 存在着四个节点, 分别是一个主节点,两个从节点, 一个投票节点,设有一个节点出现故障,那么只要有是三个节点投票选择一个节点的话,就能把对应节点切换为主节点,但是如果再有一台节点出现故障,那么只剩下两台,无论怎么选举,都不能选出一个(因为此时,最高才2/4),换句话说,四个节点的复制集架构,最多可以有一台出现故障

    但是如果是五个节点呢,则可以保证坏两台的情况下,还可以选出主节点,这实际上是比上边的四台要健壮一些的,

    所以呢,如果可能的话,尽可能在副本集中使用奇数个数据成员,不使用投票节点。

  • 选举的误区
    复制集架构中,可以不使用投票节点 。之前,我错误的认为,投票节点是必须的,有投票节点负责进行选举,但实际上是每个节点都会进行选举,它们每时每刻都会进行心跳检测检查是否连接,
    在我杀掉当前的主节点(模拟主节点崩溃),其他节点(包括备份节点和投票节点)日志如下

    2019-10-21T11:48:44.098+0800 I ASIO     [Replication] Connecting to 192.168.0.126:27110
    2019-10-21T11:48:44.098+0800 I ASIO     [Replication] Failed to connect to 192.168.0.126:27110 - HostUnreachable: Error connecting to 192.168.0.126:27110 :: caused by :: Connection refused
    2019-10-21T11:48:44.098+0800 I CONNPOOL [Replication] Dropping all pooled connections to 192.168.0.126:27110 due to HostUnreachable: Error connecting to 192.168.0.126:27110 :: caused by :: Connection refused
    2019-10-21T11:48:44.098+0800 I REPL_HB  [replexec-1] Error in heartbeat (requestId: 3548) to 192.168.0.126:27110, response status: HostUnreachable: Error connecting to 192.168.0.126:27110 :: caused by :: Connection refused
    
    
  • 节点的优先级

    在上边测试的例子中,我们不确定剩下的健在节点中,哪一个会被选为主节点,但实际上可以设置一个成员节点的优先级,表示这个成员渴望成为主节点的程度,

    默认的是1 ,比如备份节点的优先级是1,主节点的优先级是1 。优先级为0的成员永远不能成为主节点,这种节点称为被动节点。

    拥有高优先级的成员会优先选举为主节点,比如在添加一个优先级高一点的节点,测试

    rs.add({"_id":4,"host":"127.0.0.1:27114","priority":1.5})
    

    发现 27114端口对应的节点,成为新的主节点

  • 查看config中其他属性说明
    当我们在利用辅助函数 rs查看复制集结构时,还有一些其他属性,如下

    	"members" : [
    	 {
    		"_id" : 0,
    		"host" : "192.168.0.126:27110",
    		"arbiterOnly" : false,
    		"buildIndexes" : true,
    		"hidden" : false,
    		"priority" : 1,
    		"tags" : {
    			
    		},
    		"slaveDelay" : NumberLong(0),
    		"votes" : 1
    	},
    	...
     ]
    
_id成员的整数标识符。值必须介于0到255之间, 设置后无法更改。需要注意的是,在更新副本集对象时,可以用数组索引访问Members数组中副本集成员,从0开始, 但是和Members[n]._id没有任何关系,不要混了
host该节点的host地址,需要注意的是,不能用"localhost", 除非所有节点在一台机器上(但这样没有任何实际意义,说崩溃,就全崩溃了)
arbiterOnly是否为投票节点, true表示是仲裁节点
buildIndexes建立索引,表示mongod是否可以在此成员上建立索引,只能在添加的时候设置该属性, 添加到集合之后,不能通过rs.add() 或者rs.reconfig()修改。 需要注意 , 如果将buildIndexes设为false, 也需要将该节点的priority设置为0
hidden是否为隐藏节点,true时isMaster()中看不到该节点
votes服务器将在副本集选择中投票的票数。每个成员的票数是1或0,而仲裁员始终只有1票。优先级大于0的不能此属性必须大于0。一个复制集最高可以有50个节点,但只有七个投票节点,其他节点均无表决权,请将其设置为0
priority优先级 , 仲裁节点优先级为0 ,
slaveDelay是否为延迟节点,延迟节点的数据会比主节点延迟指定的时间(单位是秒),目的是当主节点数据被删除之后,可以将数据从先前的备份中恢复。 该属性要求成员的优先级是0 。 如果在应用会将读请求路由到备份节点,应该将延迟备份节点隐藏掉,避免读请求被路由到延迟备份节点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值