zoukankan      html  css  js  c++  java
  • mongodb学习笔记--集群配置(二)-副本集配置

    ## mongodb复制(副本集)
    mongodb副本集的好处:
    1. 保证数据的安全性
    2. 数据高可用
    3. 灾难恢复
    4. 无需停机维护
    5. 分布式读取数据
    ###副本集的配置
    需要准备至少三个节点来测试,本次为了方便使用同一台机器上的不同端口号启动三个节点:
    ~~~
    192.168.226.130:27017 node1
    192.168.226.130:27018 node2
    192.168.226.130:27019 node3
    ~~~
    在/data/文件夹下创建三个数据库node1,node2,node3
    ```shell script
    [root@moggledb data]# mkdir node1
    [root@moggledb data]# mkdir node2
    [root@moggledb data]# mkdir node3
    [root@moggledb data]# mkdir log
    [root@moggledb data]# ll
    total 16
    drwxr-xr-x. 2 root root 4096 May 5 20:12 log
    drwxr-xr-x. 2 root root 4096 May 5 20:12 node1
    drwxr-xr-x. 2 root root 4096 May 5 20:12 node2
    drwxr-xr-x. 2 root root 4096 May 5 20:12 node3
    ```
    使用配置文件启动方式,在node1下创建配置文件并复制到另外两个节点
    ```shell script
    [root@moggledb data]# cd node1
    [root@moggledb node1]# vi mongodb-node1.conf
    dbpath=/data/node1
    logpath=/data/log/mongodb-node1.log
    logappend=true
    fork=true
    bind_ip=192.168.226.130
    port=27017
    replSet=rs0
    ```
    保存退出,复制到另外连个节点中,并修改dbpath,logpath及port
    ```shell script
    [root@moggledb node1]# cp mongodb-node1.conf ../node2/mongodb-node2.conf
    [root@moggledb node1]# cp mongodb-node1.conf ../node3/mongodb-node3.conf
    [root@moggledb node1]# vi ../node2/mongodb-node2.conf
    dbpath=/data/node2
    logpath=/data/log/mongodb-node2.log
    logappend=true
    fork=true
    bind_ip=192.168.226.130
    port=27018
    replSet=rs0
    [root@moggledb node2]# vi ../node3/mongodb-node3.conf
    dbpath=/data/node3
    logpath=/data/log/mongodb-node3.log
    logappend=true
    fork=true
    bind_ip=192.168.226.130
    port=27019
    replSet=rs0
    ```
    replSet为副本集名称,同一个副本集内的节点,值要一样。
    配置完毕,启动三个节点:
    ```shell script
    [root@moggledb node2]# cd /usr/local/mongodb/bin/
    [root@moggledb bin]# ./mongod -f /data/node1/mongodb-node1.conf
    about to fork child process, waiting until server is ready for connections.
    forked process: 2633
    child process started successfully, parent exiting
    [root@moggledb bin]# ./mongod -f /data/node2/mongodb-node2.conf
    about to fork child process, waiting until server is ready for connections.
    forked process: 2649
    child process started successfully, parent exiting
    [root@moggledb bin]# ./mongod -f /data/node3/mongodb-node3.conf
    about to fork child process, waiting until server is ready for connections.
    forked process: 2665
    child process started successfully, parent exiting
    [root@moggledb bin]# ps -ef |grep mongod
    root 2633 1 1 20:23 ? 00:00:00 ./mongod -f /data/node1/mongodb-node1.conf
    root 2649 1 2 20:24 ? 00:00:00 ./mongod -f /data/node2/mongodb-node2.conf
    root 2665 1 3 20:24 ? 00:00:00 ./mongod -f /data/node3/mongodb-node3.conf
    root 2680 2581 0 20:24 pts/0 00:00:00 grep mongod
    [root@moggledb bin]#
    ```
    三台节点启动成功。下面配置三个节点为副本集:
    ```shell script
    [root@moggledb bin]# ./mongo --host 192.168.226.130 --port 27017
    ...
    2020-05-05T20:23:43.992-0700 I CONTROL [initandlisten]
    > conf = {"_id":"rs0","members":[{"_id":0,"host":"192.168.226.130:27017"},{"_id":1,"host":"192.168.226.130:27018"},{"_id":2,"host":"192.168.226.130:27019"}]}
    {
    "_id" : "rs0",
    "members" : [
    {
    "_id" : 0,
    "host" : "192.168.226.130:27017"
    },
    {
    "_id" : 1,
    "host" : "192.168.226.130:27018"
    },
    {
    "_id" : 2,
    "host" : "192.168.226.130:27019"
    }
    ]
    }
    > rs.initiate(conf)
    { "ok" : 1 }
    rs0:OTHER> rs.isMaster()
    {
    "setName" : "rs0",
    "setVersion" : 1,
    "ismaster" : true,
    "secondary" : false,
    "hosts" : [
    "192.168.226.130:27017",
    "192.168.226.130:27018",
    "192.168.226.130:27019"
    ],
    "primary" : "192.168.226.130:27017",
    "me" : "192.168.226.130:27017",
    "electionId" : ObjectId("5eb22f9c0520bca5e5033db3"),
    "maxBsonObjectSize" : 16777216,
    "maxMessageSizeBytes" : 48000000,
    "maxWriteBatchSize" : 1000,
    "localTime" : ISODate("2020-05-06T03:32:16.019Z"),
    "maxWireVersion" : 3,
    "minWireVersion" : 0,
    "ok" : 1
    }
    rs0:PRIMARY> rs.status()
    {
    "set" : "rs0",
    "date" : ISODate("2020-05-06T03:33:29.129Z"),
    "myState" : 1,
    "members" : [
    {
    "_id" : 0,
    "name" : "192.168.226.130:27017",
    "health" : 1,
    "state" : 1,
    "stateStr" : "PRIMARY",
    "uptime" : 586,
    "optime" : Timestamp(1588735898, 1),
    "optimeDate" : ISODate("2020-05-06T03:31:38Z"),
    "electionTime" : Timestamp(1588735900, 1),
    "electionDate" : ISODate("2020-05-06T03:31:40Z"),
    "configVersion" : 1,
    "self" : true
    },
    {
    "_id" : 1,
    "name" : "192.168.226.130:27018",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 110,
    "optime" : Timestamp(1588735898, 1),
    "optimeDate" : ISODate("2020-05-06T03:31:38Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:33:29.013Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:33:29.078Z"),
    "pingMs" : 0,
    "configVersion" : 1
    },
    {
    "_id" : 2,
    "name" : "192.168.226.130:27019",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 110,
    "optime" : Timestamp(1588735898, 1),
    "optimeDate" : ISODate("2020-05-06T03:31:38Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:33:29.013Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:33:29.078Z"),
    "pingMs" : 0,
    "configVersion" : 1
    }
    ],
    "ok" : 1
    }
    ```
    当前节点为主节点PRIMARY,上面可以看出节点的详细信息。
    副本集的主节点负责与客户端交互,进行读和写。从节点复制主机点数据,监听主节点 的心跳。
    ####副本集主从复制测试。
    在主节点插入数据
    ```shell script
    rs0:PRIMARY> show dbs
    local 1.078GB
    rs0:PRIMARY> use test
    switched to db test
    rs0:PRIMARY> db.coll.insert({"name":"zhangsan"})
    WriteResult({ "nInserted" : 1 })
    rs0:PRIMARY> db.coll.insert({"name":"lisi"})
    WriteResult({ "nInserted" : 1 })
    rs0:PRIMARY> db.coll.find()
    { "_id" : ObjectId("5eb230a80a6d7da784ff2c83"), "name" : "zhangsan" }
    { "_id" : ObjectId("5eb230ad0a6d7da784ff2c84"), "name" : "lisi" }
    ```
    连接从节点:
    ```shell script
    [root@moggledb bin]# ./mongo --host 192.168.226.130 --port 27018
    ...
    2020-05-05T20:24:21.584-0700 I CONTROL [initandlisten]
    rs0:SECONDARY> rs.slaveOk()
    rs0:SECONDARY> show dbs
    local 1.078GB
    test 0.078GB
    rs0:SECONDARY> use test
    switched to db test
    rs0:SECONDARY> db.coll.find()
    { "_id" : ObjectId("5eb230a80a6d7da784ff2c83"), "name" : "zhangsan" }
    { "_id" : ObjectId("5eb230ad0a6d7da784ff2c84"), "name" : "lisi" }
    rs0:SECONDARY> rs.status()
    {
    "set" : "rs0",
    "date" : ISODate("2020-05-06T03:45:56.163Z"),
    "myState" : 2,
    "syncingTo" : "192.168.226.130:27017",
    "members" : [
    {
    "_id" : 0,
    "name" : "192.168.226.130:27017",
    "health" : 1,
    "state" : 1,
    "stateStr" : "PRIMARY",
    "uptime" : 857,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:45:54.692Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:45:54.665Z"),
    "pingMs" : 0,
    "electionTime" : Timestamp(1588735900, 1),
    "electionDate" : ISODate("2020-05-06T03:31:40Z"),
    "configVersion" : 1
    },
    {
    "_id" : 1,
    "name" : "192.168.226.130:27018",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 1295,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "syncingTo" : "192.168.226.130:27017",
    "configVersion" : 1,
    "self" : true
    },
    {
    "_id" : 2,
    "name" : "192.168.226.130:27019",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 857,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:45:54.677Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:45:54.677Z"),
    "pingMs" : 0,
    "syncingTo" : "192.168.226.130:27017",
    "configVersion" : 1
    }
    ],
    "ok" : 1
    }
    rs0:SECONDARY>
    ```
    可以看出主节点插入数据,在从节点中也有数据,从节点只能读数据,不能写数据,主节点可以读写数据。
    ####故障转移
    模拟主节点宕机,关闭主节点服务:
    ```shell script
    [root@moggledb bin]# ./mongod --shutdown --dbpath=/data/node1
    killing process with pid: 2633
    [root@moggledb bin]#
    ```
    再次查看从节点状态:
    ```shell script
    [root@moggledb bin]# mongo --host 192.168.226.130 --port 27018
    ...
    2020-05-05T20:24:21.584-0700 I CONTROL [initandlisten]
    rs0:PRIMARY> rs.status()
    {
    "set" : "rs0",
    "date" : ISODate("2020-05-06T03:52:08.238Z"),
    "myState" : 1,
    "members" : [
    {
    "_id" : 0,
    "name" : "192.168.226.130:27017",
    "health" : 0,
    "state" : 8,
    "stateStr" : "(not reachable/healthy)",
    "uptime" : 0,
    "optime" : Timestamp(0, 0),
    "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:52:07.354Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:50:23.111Z"),
    "pingMs" : 0,
    "lastHeartbeatMessage" : "Failed attempt to connect to 192.168.226.130:27017; couldn't connect to server 192.168.226.130:27017 (192.168.226.130), connection attem
    pt failed",
    "configVersion" : -1
    },
    {
    "_id" : 1,
    "name" : "192.168.226.130:27018",
    "health" : 1,
    "state" : 1,
    "stateStr" : "PRIMARY",
    "uptime" : 1667,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "electionTime" : Timestamp(1588737026, 1),
    "electionDate" : ISODate("2020-05-06T03:50:26Z"),
    "configVersion" : 1,
    "self" : true
    },
    {
    "_id" : 2,
    "name" : "192.168.226.130:27019",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 1229,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:52:07.216Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:52:07.197Z"),
    "pingMs" : 0,
    "configVersion" : 1
    }
    ],
    "ok" : 1
    }
    ```
    从上面状态信息可以看出,27017节点无心跳,27018节点变为主节点:`{"stateStr":"PRIMARY"}`
    如果此时重启27017节点:
    ```shell script
    [root@moggledb bin]# ./mongod -f /data/node1/mongodb-node1.conf
    rs0:SECONDARY> rs.status()
    {
    "set" : "rs0",
    "date" : ISODate("2020-05-06T03:54:46.892Z"),
    "myState" : 1,
    "members" : [
    {
    "_id" : 0,
    "name" : "192.168.226.130:27017",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 17,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:54:45.678Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:54:45.725Z"),
    "pingMs" : 0,
    "configVersion" : 1
    },
    {
    "_id" : 1,
    "name" : "192.168.226.130:27018",
    "health" : 1,
    "state" : 1,
    "stateStr" : "PRIMARY",
    "uptime" : 1825,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "electionTime" : Timestamp(1588737026, 1),
    "electionDate" : ISODate("2020-05-06T03:50:26Z"),
    "configVersion" : 1,
    "self" : true
    },
    {
    "_id" : 2,
    "name" : "192.168.226.130:27019",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 1387,
    "optime" : Timestamp(1588736173, 1),
    "optimeDate" : ISODate("2020-05-06T03:36:13Z"),
    "lastHeartbeat" : ISODate("2020-05-06T03:54:45.517Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T03:54:45.517Z"),
    "pingMs" : 0,
    "configVersion" : 1
    }
    ],
    "ok" : 1
    }
    ```
    27017节点仍为从节点,27018为主节点。可以为节点配置优先级,这样主节点重启后仍是主节点。
    **只有主节点才可以设置副本集配置**
    所以先进入主节点的shell命令行:
    ```shell script
    rs0:PRIMARY> rs.conf()
    {
    "_id" : "rs0",
    "version" : 1,
    "members" : [
    {
    "_id" : 0,
    "host" : "192.168.226.130:27017",
    "arbiterOnly" : false,
    "buildIndexes" : true,
    "hidden" : false,
    "priority" : 1,
    "tags" : {

    },
    "slaveDelay" : 0,
    "votes" : 1
    },
    {
    "_id" : 1,
    "host" : "192.168.226.130:27018",
    "arbiterOnly" : false,
    "buildIndexes" : true,
    "hidden" : false,
    "priority" : 1,
    "tags" : {

    },
    "slaveDelay" : 0,
    "votes" : 1
    },
    {
    "_id" : 2,
    "host" : "192.168.226.130:27019",
    "arbiterOnly" : false,
    "buildIndexes" : true,
    "hidden" : false,
    "priority" : 1,
    "tags" : {

    },
    "slaveDelay" : 0,
    "votes" : 1
    }
    ],
    "settings" : {
    "chainingAllowed" : true,
    "heartbeatTimeoutSecs" : 10,
    "getLastErrorModes" : {

    },
    "getLastErrorDefaults" : {
    "w" : 1,
    "wtimeout" : 0
    }
    }
    }
    ```
    将27017优先级设为三个节点的最高值:
    ```shell script
    rs0:PRIMARY> var conf=rs.conf()
    rs0:PRIMARY> conf.members[0].priority=5
    5
    rs0:PRIMARY> rs.reconfig(conf)
    ```
    然后重新启动27017节点
    ```shell script
    [root@moggledb bin]# ./mongod --shutdown --dbpath=/data/node1
    killing process with pid: 4252
    [root@moggledb bin]# ./mongod -f /data/node1/mongodb-node1.conf
    about to fork child process, waiting until server is ready for connections.
    forked process: 5614
    child process started successfully, parent exiting
    [root@moggledb bin]# ./mongo --host 192.168.226.130 --port 27017
    ...
    rs0:SECONDARY> rs.isMaster()
    rs0:SECONDARY> rs.isMaster()
    {
    "setName" : "rs0",
    "setVersion" : 2,
    "ismaster" : true,
    "secondary" : false,
    "hosts" : [
    "192.168.226.130:27017",
    "192.168.226.130:27018",
    "192.168.226.130:27019"
    ],
    "primary" : "192.168.226.130:27017",
    "me" : "192.168.226.130:27017",
    "electionId" : ObjectId("5eb23de4b1aea8240124474b"),
    "maxBsonObjectSize" : 16777216,
    "maxMessageSizeBytes" : 48000000,
    "maxWriteBatchSize" : 1000,
    "localTime" : ISODate("2020-05-06T04:32:49.878Z"),
    "maxWireVersion" : 3,
    "minWireVersion" : 0,
    "ok" : 1
    }
    rs0:PRIMARY> rs.status()
    {
    "set" : "rs0",
    "date" : ISODate("2020-05-06T04:33:55.150Z"),
    "myState" : 1,
    "members" : [
    {
    "_id" : 0,
    "name" : "192.168.226.130:27017",
    "health" : 1,
    "state" : 1,
    "stateStr" : "PRIMARY",
    "uptime" : 106,
    "optime" : Timestamp(1588739463, 1),
    "optimeDate" : ISODate("2020-05-06T04:31:03Z"),
    "electionTime" : Timestamp(1588739556, 1),
    "electionDate" : ISODate("2020-05-06T04:32:36Z"),
    "configVersion" : 2,
    "self" : true
    },
    {
    "_id" : 1,
    "name" : "192.168.226.130:27018",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 105,
    "optime" : Timestamp(1588739463, 1),
    "optimeDate" : ISODate("2020-05-06T04:31:03Z"),
    "lastHeartbeat" : ISODate("2020-05-06T04:33:53.661Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T04:33:54.069Z"),
    "pingMs" : 23,
    "configVersion" : 2
    },
    {
    "_id" : 2,
    "name" : "192.168.226.130:27019",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 105,
    "optime" : Timestamp(1588739463, 1),
    "optimeDate" : ISODate("2020-05-06T04:31:03Z"),
    "lastHeartbeat" : ISODate("2020-05-06T04:33:53.661Z"),
    "lastHeartbeatRecv" : ISODate("2020-05-06T04:33:55.124Z"),
    "pingMs" : 23,
    "configVersion" : 2
    }
    ],
    "ok" : 1
    }
    ```
    可以看出27017重新成为主节点
  • 相关阅读:
    Leetcode: Summary Ranges
    Leetcode: Kth Smallest Element in a BST
    Leetcode: Basic Calculator II
    Leetcode: Basic Calculator
    Leetcode: Count Complete Tree Nodes
    Leetcode: Implement Stack using Queues
    Leetcode: Maximal Square
    Leetcode: Contains Duplicate III
    Leetcode: Invert Binary Tree
    Leetcode: The Skyline Problem
  • 原文地址:https://www.cnblogs.com/Zs-book1/p/12835665.html
Copyright © 2011-2022 走看看