黑帽联盟

 找回密码
 会员注册
查看: 1222|回复: 0

[其它] mongodb副本集(主从同步、读写分离和高可用性)部署

[复制链接]

293

主题

18

听众

955

积分

管理员

Rank: 9Rank: 9Rank: 9

  • TA的每日心情
    奋斗
    2023-10-26 13:13
  • 签到天数: 358 天

    [LV.8]以坛为家I

    相关链接mongodb分片集群(Sharding Cluster)配置搭建


    mongodb的主从同步和读写分离是通过副本集(replica set)来实现的,其本身也自带高可用功能,当主节点挂了,其它从节点会通过选票机制进行选举出主节点,以实现高可用性

    原理图:
    16.png


    Mongodb官方推荐使用副本集模式,如下图所示,该模式不但实现了主从模式的读写分离,而且有自己的一套选举机制,选举出当前最优的节点作为主节点,一旦主节点宕机,选举出来的新的节点将成为主节点对外提供服务,其他节点则继续作为复制节点,当原先的主节点恢复,会自动作为备份节点。
    14.png


    而我们今天不设置Arbiter节点,我们按照如下图所示来部署:
    15.png


    Mongodb集群触发选举的条件:

    1.复制集初始化。

    2.主节点挂掉。

    3.主节点脱离副本集(可能是网络原因)。

    4.参与选举的节点数量必须大于副本集总节点数量的一半,如果已经小于一半了所有节点保持只读状态。

    11.jpg

    (IDC)


    mongodb的选举机制探究总结:

    1、副本集中的主节点选举必须满足“大多数”的原则,所谓“大多数”是指副本中一半以上的成员。副本集中成员只有在得到大多数成员投票支持时,才能成为主节点。例如:有N个副本集成员节点,必须有N/2+1个成员投票支持某个节点,此节点才能成为主节点。注意:副本集中若有成员节点处于不可用状态,并不会影响副本集中的“大多数”,“大多数”是以副本集的配置来计算的。

    2、仲裁节点(Arbiter)它并不保存数据,并且不能被选举为主节点,但是具有投票权。仲裁节点使用最小的资源,不能将Arbiter部署在同一个数据集节点中。

    3、副本集中最好是有奇数个成员节点,如果有偶数个节点,最好加一个仲裁节点。若副本集中有偶数个成员节点,如图(IDC)所示,IDC1网络连不通IDC2,IDC1和IDC2内的成员节点分别会发生选举主节点的行为,然而选举因都无法满足大多数的原则,都不能选出主节点;加入一个仲裁节点之后,则副本集就能满足大多数原则,从中选出主节点了。

    4.如果副本集成员节点数量是奇数,就不再需要仲裁者。但是如果在成员节点是奇数时,强行使用仲裁者,会导致选举耗时变长。由于添加了仲裁者就可能出现两个成员节点票数相同的情况,从而导致选举耗时变长。

    5.若在一轮投票中,副本集中成员节点被投了反对票,则本轮不能被选为主节点。例如,在一个10个成员节点的副本集,某轮投票中,成员节点A由于数据延迟较大被某个成员节点投了反对票,则A同时收到了9票赞成票,然而A仍然不能被选为主节点。

    6.集群中的优先级为0的节点不能成为主节点,并且不能触发选举,但是具有投票权,并且拥有与主节点一致的数据集。


    环境:(本文用mongodb2.6.5测试)
    172.31.225.243(centos7.3) 作为primary节点
    172.31.225.244(centos7.3) 作为secondary节点
    172.31.225.246(centos6.7) 作为secondary节点

    mongodb编译好的二进制文件下载:http://downloads.mongodb.org/linux/mongodb-linux-x86_64-2.6.5.tgz

    下面在三台服务器上执行如下操作:
    配置mongodb环境变量,使其命令全局生效
    1、wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-2.6.5.tgz
    2、tar xf mongodb-linux-x86_64-2.6.5.tgz -C /usr/local/
    3、cd /usr/local
    4、ln -sv mongodb-linux-x86_64-2.6.5 mongo
    5、vim /etc/profile.d/mongo.sh
    export MONGOD_HOME=/usr/local/mongo
    export PATH=$MONGOD_HOME/bin:$PATH
    6、. /etc/profile.d/mongo.sh
    编辑配置文件:
    vim /etc/mongod.conf

    dbpath=/mongodb/data/

    logpath=/var/log/mongodb/mongodb.log

    pidfilepath=/var/run/mongo.pid

    fork=true

    logappend=true

    directoryperdb=true

    httpinterface=true

    replSet=testSet

    replIndexPrefetch=_id_only
    编辑启动脚本:
    vim /etc/init.d/mongod

    #!/bin/sh

    # chkconfig: - 64 36

    # description:mongod

    case $1 in

    start)

    /usr/local/mongo/bin/mongod --maxConns 20000 --config /etc/mongod.conf

    ;;

    stop)

    /usr/local/mongo/bin/mongo 127.0.0.1:27017/admin --eval "db.shutdownServer()"

    #/usr/local/mongo/bin/mongo 127.0.0.1:27017/admin --eval "db.auth('system', '123456');db.shutdownServer()"

    ;;

    restart)

    /usr/local/mongo/bin/mongo 127.0.0.1:27017/admin --eval "db.shutdownServer()"

    /usr/local/mongo/bin/mongod --maxConns 20000 --config /etc/mongod.conf

    #/usr/local/mongo/bin/mongo 127.0.0.1:27017/admin --eval "db.auth('system', '123456');db.shutdownServer()"

    ;;

    status)

    /usr/local/mongo/bin/mongo 127.0.0.1:27017/admin --eval "db.stats()"

    #/usr/local/mongo/bin/mongo 127.0.0.1:27017/admin --eval "db.auth('system', '123456');db.stats()"

    ;;

    esac

    chmod +x /etc/init.d/mongod
    最后创建相关目录和用户以及用户组,即日志保存目录和数据保存目录
    mkdir /mongdb/data -pv
    mkdir /var/log/mongodb
    groupadd mongod
    useradd -g mongod mongod
    chown -R mongod:mongod /mongodb/data
    chown -R mongod:mongod /var/log/mongodb
    启动三台主机mongod服务
    service mongod start

    公共部分操作至此结束



    在172.31.225.243节点上操作
    查询副本集的配置和状态,如下图:
    21.png


    可知:副本集相关节点还没有配置,所以显示null,以及图中提示我们:"info" : "run rs.initiate(...) if not yet done for the set",即配置副本集之前,我们需要初始化:rs.initiate()

    初始化之后,查询副本集配置
    22.png


    当前节点只有一个副本集,即自己;其次初始化过后,自己成为了primary主节点,因为现在只有一个节点,所以默认为primary

    添加副本集其它节点:
    23.png


    我们可以看到172.31.225.244节点已经被添加进去了,以及172.31.225.244此时的状态是STARTUP2,再过几秒时间,就会变成SECONDARY,也就是变成了从节点

    我们再次执行rs.status()
    24.png


    再次添加节点172.31.225.246
    25.png


    26.png


    从图中可以看到,配置中多出来一些参数:
    "lastHeartbeat" : ISODate("2019-10-25T10:31:45Z"),
    "lastHeartbeatRecv" : ISODate("2019-10-25T10:31:46Z"),
    "pingMs" : 1,
    "syncingTo" : "node1.cnblackhat.com:27017"

    从节点向主节点的请求的ping,即心跳信息,还有数据同步源:syncingTo

    至此副本集配置就完成了



    主从同步测试:
    在主节点上添加测试数据
    27.png


    数据插入成功

    在从节点172.31.225.246上查询数据
    28.png


    默认查询不了数据,报错:error: { "$err" : "not master and slaveOk=false", "code" : 13435 }需要设置rs.slaveOk(),就可以进行查询操作了

    数据已经同步过来了,数据同步成功

    另外一个172.31.225.244节点,你们自己去查询操作一下,这里就不演示了

    主从同步至此就结束了



    读写分离测试:
    首先我们在主节点172.31.225.243上进行写操作:
    29.png


    由此可知:主节点默认是允许写操作的,也允许读操作

    接着在从节点172.31.225.246上进行写操作
    30.png


    有报错:"errmsg" : "not master",即当前节点不是主节点,所以不能执行写操作

    由此可知:从节点默认是不允许写操作的,可以进行读操作(前提需设置rs.slaveOk())

    读写分离操作至此结束



    高可用性测试:
    在测试高可用性之前,我们先分析一下“副本集重新选举的影响条件”
    1、心跳信息
    2、优先级
    3、optime (rs.printReplicationInfo()查询optime)
    4、网络连接
    5、网络分区

    原理图:
    17.png


    这里我们通过设置优先级高低来选举主节点,前提:其它影响因素都一致的情况下

    那么我们该如何设置优先级呢,操作如下:(这里我们有意选举172.31.225.246为主节点,设置优先级要高于其它两节点
    注意:设置优先级操作,需要在primary主节点进行操作,在从节点上操作无效

    操作如图:
    31.png


    设置172.31.225.243 priority为1
    设置172.31.225.244 priority为1
    设置172.31.225.246 priority为2

    可知当我们设置172.31.225.246优先级为2的时候,172.31.225.243这台机器自动变为SECONDARY从节点了

    查看副本集配置:
    32.png


    可以看到172.31.225.246节点里面多一个priority字段,其它两个节点我们也设置priority,但是没有出现该字段,原因是默认级别就是1,所以不显示

    我们在到172.31.225.246这个节点上看一下是否为primary主节点了,如图:
    33.png


    上图我们使用rs.isMaster(),结果显示"ismaster" : true,说明主节点已经转到此节点了



    正式测试高可用性:
    我们可以在主节点上使用rs.stepDown(),临时性的下线;或者直接使用service mongod stop,关闭mongod服务
    这里我们使用rs.stepDown()
    34.png


    执行操作后,立刻变成SECONGARY从节点了

    查看副本集配置:
    35.png


    可以看到主节点变成172.31.225.244了

    到172.31.225.244节点上验证是否为主节点:
    36.png


    高可用性至此结束
    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部