MongoDB Replica Set 副本集實踐

solution發表於2021-09-09

在自己的本機建立有三個節點的副本集 (一個主節點,兩個從節點),是基於MongoDB 3.6 版本

  • 建立資料儲存路徑

    mkdir r0
    mkdir r1
    mkdir r2
  • 建立log儲存路徑

    mkdir log
  • 啟動第一個節點

    mongod --replSet rs0 --port 27017 --bind_ip 127.0.0.1 --dbpath .r0 --logpath logr0.log --logappend
  • 啟動第二個節點

    mongod --replSet rs0 --port 27018 --bind_ip 127.0.0.1 --dbpath .r1 --logpath logr1.log --logappend
  • 啟動第三個節點

    mongod --replSet rs0 --port 27017 --bind_ip 127.0.0.1 --dbpath .r2 --logpath logr2.log --logappend
  • 連線到 mongod 例項

    mongo --port 27017
  • mongo shell中,使用 rs.initiate() 初始化副本集

rsconf = {
  _id: "rs0",
  members: [
    {
     _id: 0,
     host: "127.0.1:27017"
    },
    {
     _id: 1,
     host: "127.0.1:27018"
    },
    {
     _id: 2,
     host: "127.0.1:27019"
    }
   ]
}
rs.initiate(rsconf)

初始化成功

{        "ok" : 1,        "operationTime" : Timestamp(1524728214, 1),        "$clusterTime" : {                "clusterTime" : Timestamp(1524728214, 1),                "signature" : {                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),                        "keyId" : NumberLong(0)
                }
        }
}
  • 檢視副本集的狀態
    27017:是主節點
    27018 27019是從節點

    rs.status()
    {      "set" : "rs0",      "date" : ISODate("2018-04-26T08:15:11.241Z"),      "myState" : 1,
          ...      "members" : [
                  {                      "_id" : 0,                      "name" : "127.0.0.1:27017",                      "health" : 1,                      "state" : 1,                      "stateStr" : "PRIMARY",
                          ...
                  },
                  {                      "_id" : 1,                      "name" : "127.0.0.1:27018",                      "health" : 1,                      "state" : 2,                      "stateStr" : "SECONDARY",
                           ...
                  },
                  {                      "_id" : 2,                      "name" : "127.0.0.1:27019",                      "health" : 1,                      "state" : 2,                      "stateStr" : "SECONDARY",
                          ...
                  }
          ],      "ok" : 1,
          ...
      }
  • 檢視節點是否是主節點

rs.isMaster()
{                "hosts" : [                        "127.0.0.1:27017",                        "127.0.0.1:27018",                        "127.0.0.1:27019"
                ],                "setName" : "rs0",                "setVersion" : 1,                "ismaster" : true,                "secondary" : false,                "primary" : "127.0.0.1:27017",                "me" : "127.0.0.1:27017",                "electionId" : ObjectId("7fffffff0000000000000003"),
               ...
        }
  • 讀寫操作
    先在主節點建立一個資料庫並寫入資料

    use TestDB  
    db.createCollection("TestModel")  
    db.getCollection("TestModel").insert({"first_name":"Lorry","second_name":"kevin"})

使用從節點進行查詢

mongo --port 27019

無法進行查詢的操作 ,從節點無法進行查詢操作

rs0:SECONDARY> show dbs2018-04-26T16:20:35.769+0800 E QUERY    [thread1] Error: listDatabases failed:{      "operationTime" : Timestamp(1524730833, 1),      "ok" : 0,      "errmsg" : "not master and slaveOk=false",      "code" : 13435,      "codeName" : "NotMasterNoSlaveOk",
      ...
} :

配置從節點可以進行查詢

db.getMongo().setSlaveOk()
rs0:SECONDARY> show dbsTestDB  0.000GBadmin   0.000GBconfig  0.000GBlocal   0.000GB
  • 故障轉移

    把主節點埠停掉,再檢視對應的副本集的狀態
    rs.status()

  27017 : "stateStr" : "(not reachable/healthy)"  
  27018 : "stateStr" : "PRIMARY",  
  27019 : "stateStr" : "SECONDARY",  

  27018 變成了主節點  
 {        "set" : "rs0",        "date" : ISODate("2018-04-26T08:24:24.740Z"),        "myState" : 2,        "term" : NumberLong(4),
        ...        "members" : [
                {                        "_id" : 0,                        "name" : "127.0.0.1:27017",                        "health" : 0,                        "state" : 8,                        "stateStr" : "(not reachable/healthy)",
                        ...
                },
                {                        "_id" : 1,                        "name" : "127.0.0.1:27018",                        "health" : 1,                        "state" : 1,                        "stateStr" : "PRIMARY",
                        ...
                },
                {                        "_id" : 2,                        "name" : "127.0.0.1:27019",                        "health" : 1,                        "state" : 2,                        "stateStr" : "SECONDARY",
                       ...
                }
        ],        "ok" : 1,
        ...
}
  • 增加節點

    mkdir r3
  • 啟動新節點

    mongod --relpSet rs0 --port 27020 --bind_ip 127.0.0.1 --dbpath .r3

    增加節點

    rs.add("127.0.0.1:27020")
    {      "ok" : 1,      "operationTime" : Timestamp(1524731467, 1),      "$clusterTime" : {              "clusterTime" : Timestamp(1524731467, 1),              "signature" : {                      "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),                      "keyId" : NumberLong(0)
                  }
          }
    }

在檢視副本集的狀態,可以看到 27020的新節點, 連線到新的節點檢視,資料已經同步了

  • 刪除節點

rs.remove("127.0.0.1:27020")

  {          "ok" : 1,          "operationTime" : Timestamp(1524731753, 1),          "$clusterTime" : {                  "clusterTime" : Timestamp(1524731753, 1),                  "signature" : {                          "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),                          "keyId" : NumberLong(0)
                  }
          }
  }

再檢視一下當前副本集的狀態,可以看到 27020的節點已經被刪除了



作者:CoderMiner
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2459/viewspace-2820946/,如需轉載,請註明出處,否則將追究法律責任。

相關文章