美文网首页程序员我爱编程
MongoDB 复制集(Replica Set)搭建

MongoDB 复制集(Replica Set)搭建

作者: 非典型程序员 | 来源:发表于2017-06-28 11:17 被阅读1159次

    通常,为了防止单点故障应用程序需要做集群。然而在数据库中除了防止单点故障,还需要做到数据库备份,读写分离,故障转移等。而 MongoDB 的 Replica Set 恰恰都能满足这些要求。

    复制集成员

    Replica Set 的成员是一堆有着同样的数据内容 mongod 的实例集合,包含以下三类角色:

    1. 主节点(Primary)
      是 Replica Set 中唯一的接收写请求的节点,并将写入指令记录到 oplog 上。副本节点通过复制 oplog 的写入指令同步主节点的数据。Secondary。一个 Replica Set 有且只有Primary 节点,当Primar挂掉后,其他 Secondary 或者 Arbiter 节点会重新选举出来一个主节点。应用程序的默认读取请求也是发到 Primary节点处理的。

    2. 副本节点(Secondary)
      通过复制主节点 oplog 中的指令与主节点保持同样的数据集,当主节点挂掉的时候,参与主节点选举。

    3. 仲裁者(Arbiter)
      不存储实际应用数据,只投票参与选取主节点,但不会被选举成为主节点。

    复制集搭建(3个成员)

    1. 节点目录结构说明


      节点目录结构

      其中,instance 、instance_1、instance_2 分别代表3个节点。每个节点都有相同的目录结构,包含了数据目录 data ,日志目录 logs , JavaScript 文件目录 js, 启停脚本 mongod-server.sh,节点配置文件 mongod.conf 等

    2. 节点配置文件 mongod.conf

    # syslog配置
    logpath=/mnt/mongodb/instance/logs/mongod.log #日志目录
    logappend=true
    timeStampFormat=iso8601-utc
    # storage 存储配置
    dbpath=/mnt/mongodb/instance/data/db #数据存储目录
    directoryperdb=true
    # processManagement 进程管理配置
    fork=true
    pidfilepath=/mnt/mongodb/instance/var/run/mongod.pid # 进程 PID 文件保存目录
    # net 网络配置
    bind_ip=127.0.0.1
    port=27017 
    # security 配置
    #auth=true
    # 复制集
    replSet=test-set    # 复制集 name         
    

    其中 logpath 、dbpath、 pidfilepath 需要根据节点修改到对应目录(路径中的instance 改为 instance_1或 instance_2)。此外还需要修改每个节点的 port,在我的配置当中,instance 、instance_1、instance_2 的端口分别为 27017、27018、27019。

    1. 启动三个节点
      这里启动需要用到上面提到的 mongod-server.sh 服务启停脚本(这个脚本是我自己编写的用于管理 mongod 进程启停,详细了解猛戳这里
      分别在 instance、instance_1、 instance_2 目录中执行一下命令./mongod-server.sh start
    [root@iZu1qhttxe5Z instance]# ls
    data  dump  js  logs  mongod.conf  mongod-server.sh  var
    [root@iZu1qhttxe5Z instance]# ./mongod-server.sh start
    about to fork child process, waiting until server is ready for connections.
    forked process: 680
    child process started successfully, parent exiting
    Started [680]
    [root@iZu1qhttxe5Z instance]# 
    

    这个时候3个节点已经启动了,接下来需要初始化复制集。

    1. 初始化复制集
      选择任意的节点,进入 js 目录:
    [root@iZu1qhttxe5Z js]$ ls
    initiate_rs.js  user.js
    [root@iZu1qhttxe5Z js]# cat initiate_rs.js 
    rs.initiate()
    rs.add("iZu1qhttxe5Z:27017")
    rs.add("iZu1qhttxe5Z:27019")
    rs.conf()
    [root@iZu1qhttxe5Z js]# 
    

    这里的 initiate_rs.js 文件适用于初始化复制集的js文件,其实这些操作可以在 mongo shell中操作,但是为了方便运维管理,所以将此操作提取到 js 文件(如何将 mongo shell 命令提出到 js 文件猛戳这里)。

    执行初始化,这里选取端口 27018 的节点。

    [root@iZu1qhttxe5Z instance_1]# mongo --port 27018 ./js/initiate_rs.js 
    MongoDB shell version v3.4.5
    connecting to: mongodb://127.0.0.1:27018/
    MongoDB server version: 3.4.5
    [root@iZu1qhttxe5Z instance_1]# 
    

    连接到其中一个节点,查看是否初始化成功

    test-set:SECONDARY> rs.status()
    {
        "set" : "test-set",
        "date" : ISODate("2017-06-28T02:57:33.424Z"),
        ......
        },
        "members" : [
            {
                "_id" : 0,
                "name" : "10.117.225.127:27018",
                ...........
                "stateStr" : "SECONDARY",
                ...........
            },
            {
                "_id" : 1,
                "name" : "iZu1qhttxe5Z:27017",
                .............
                "stateStr" : "PRIMARY",
                ..............
            },
            {
                "_id" : 2,
                "name" : "iZu1qhttxe5Z:27019",
                .........
                "stateStr" : "SECONDARY",
                .........
            }
        ],
        "ok" : 1
    }
    test-set:SECONDARY> 
    

    可以看出复制集已经初始化成功。

    1. 连接Primary节点,写入数据。
    test-set:PRIMARY> use test
    switched to db test
    test-set:PRIMARY> show collections
    test-set:PRIMARY> db.test.insert({"name":"knight"});
    WriteResult({ "nInserted" : 1 })
    test-set:PRIMARY> show collections
    test
    test-set:PRIMARY> db.test.find()
    { "_id" : ObjectId("59531cd6000e29eae22a2f83"), "name" : "knight" }
    test-set:PRIMARY> 
    

    数据插入成功,验证 SECONDARY 是否同步数据

    # 27018 节点
    [root@iZu1qhttxe5Z js]# mongo --port 27018
    MongoDB shell version v3.4.5
    connecting to: mongodb://127.0.0.1:27018/
    MongoDB server version: 3.4.5
    ....
    test-set:SECONDARY>
    test-set:SECONDARY> rs.slaveOk()
    test-set:SECONDARY> use test
    switched to db test
    test-set:SECONDARY> show collections
    test
    test-set:SECONDARY> db.test.find()
    { "_id" : ObjectId("59531cd6000e29eae22a2f83"), "name" : "knight" }
    test-set:SECONDARY> 
    [root@iZu1qhttxe5Z js]#
    [root@iZu1qhttxe5Z js]#
    [root@iZu1qhttxe5Z js]#
    # 27019 节点
    [root@iZu1qhttxe5Z js]# mongo --port 27019
    MongoDB shell version v3.4.5
    connecting to: mongodb://127.0.0.1:27019/
    MongoDB server version: 3.4.5
    ....
    test-set:SECONDARY> rs.slaveOk()
    test-set:SECONDARY> use test
    switched to db test
    test-set:SECONDARY> db.test.find()
    { "_id" : ObjectId("59531cd6000e29eae22a2f83"), "name" : "knight" }
    test-set:SECONDARY> 
    
    1. 默认情况下,Secondary不能读和写, 需要执行 rs.slaveOk()(或者执行db.getMongo().setSlaveOk())。
    test-set:SECONDARY> use test
    switched to db test
    test-set:SECONDARY> db.test.find()
    Error: error: {
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotMasterNoSlaveOk"
    }
    test-set:SECONDARY> 
    

    References:

    MongoDB 执行 js 文件
    MongoDB 启停脚本

    相关文章

      网友评论

        本文标题:MongoDB 复制集(Replica Set)搭建

        本文链接:https://www.haomeiwen.com/subject/ftojcxtx.html