溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mongodb副本集實現

發布時間:2020-03-03 03:58:31 來源:網絡 閱讀:2841 作者:SoulMio 欄目:MongoDB數據庫

MongoDB副本集概述

以下圖片摘自MongoDB官方文檔:http://docs.mongodb.org/manual/core/replication-introduction/

Mongodb副本集實現

Primary節點接收客戶端所有的寫操作,整個副本集只會有一個primary節點。MongoDB副本集提供嚴格的一致性。主節點將所有的操作寫入一個叫oplog的capped collection(這個collection的大小一般為磁盤剩余空間的5%,不同的系統可能不一樣,詳見http://docs.mongodb.org/manual/core/replica-set-oplog/)中,secondary節點通過復制oplog并執行oplog中的所有操作,因為對oplog的執行是冪等的,所以secondary節點上的數據可以保持和primary節點一樣,當然這有一個“追趕”(catch up)的過程,會存在一定的落后(Lag)有時候因為網絡延遲或宕機導致從節點永遠趕不上主節點,這時候需要采取人為的干預了(后面會說到Resyncing Member of Replica Set)。

 

Mongodb副本集實現

默認所有的讀操作也是走的primary節點,當然客戶端可以選擇從secondary節點進行讀取操作以減小主節點的壓力(后面會對讀寫分離有詳細說明)。

各個節點之間是通過心跳機制來維持聯系的,當主節點無法和集群中其他節點通信超過10秒,集群會從剩下的節點中選擇一個secondary作為primary,這個過程叫做選舉(election),每個secondary節點都有一個優先級priority來參與投票(也可以有沒有投票權的secondary節點),priority值越大就越優先成為主節點(所有的節點可以有相同的優先級,默認值都是1)。election的策略不僅僅就是根據priority值來,會綜合很多其他的因素??傊甅ongoDB通過heartbeat和election機制實現了自動的Failover:

Mongodb副本集實現

 副本集要求參與選舉投票(vote)的節點數為奇數,這很容易理解。當我們實際環境中因為機器等原因限制只有兩個(或偶數)的節點,這時為了實現Automatic Failover引入另一類節點:仲裁者(arbiter),仲裁者只參與投票不擁有實際的數據,因此它對物理資源要求不嚴格。

Mongodb副本集實現

上面已經提到了primary,secondary和arbiter,整個MongoDB副本集群中除了這三種類型的節點還有其他幾種:

  • Secondary-Only:這種類型的節點和secondary節點一樣擁有數據副本,但是它們在任何情形下都成為不了primary節點。

  • Hidden:這種類型的節點對客戶端程序來說是不可見的,同樣也不能成為primary節點,但是Hidden成員能夠參與選舉投票。

  • Delayed:這種類型的成員通過人為的設置,可以指定一個時間來延遲從primary節點同步數據。Delayed成員的作用在于幫助集群從一些誤操作中恢復,比如管理員誤刪除了某個集合。不至于迅速擴散到整個集群中。因此Delayed節點必須不能成為primary節點(priority為0)并且是Hidden的。

  • Non-Voting:這就是上面提到了沒有選舉權的secondary節點。這種類型的節點一般當集群節點數超過12才會需要。

簡單副本集的搭建

主:192.168.1.100

從:192.168.1.101,192.168.1.102

1.首先已經安裝完mongodb(我們使用rpm安裝)。

mongodb默認端口為:27017 

2.修改兩個從節點配置文件

service mongod stop 
vim /etc/mongod.conf

取消注釋replSet,設置其名稱;并添加replIndexPrefetch項。如下:

Mongodb副本集實現

重啟服務:

service mongod start

3.登錄到主節點命令行中

mongo
>rs.status() 
{
    "startupStatus" : 3,
    "info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "can't get local.system.replset config from self or any seed (YCONFIG)"
}

啟動一個新的副本集

>rs.initiate()  
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "Centos:27017",
"info" : "Config now saved locally.  Should come online in about a minute
"ok" : 1
}

在Mongo客戶端使用命令rs.initiate()來啟動一個新的副本集。

我們可以使用rs.conf()來查看副本集的配置

查看副本集狀態使用 rs.status() 命令

副本集添加成員

添加副本集的成員,我們需要使用多條服務器來啟動mongo服務。進入Mongo客戶端,并使用rs.add()方法來添加副本集的成員。

語法

rs.add() 命令基本語法格式如下:

>rs.add(Host_NAME:PORT)

添加兩個從節點成員:

testSet:PRIMARY> rs.add("192.168.1.101") --默認27017不用指定
{ "ok" : 1 }
testSet:PRIMARY> rs.add("192.168.1.102")
{ "ok" : 1 }

此時,查看副本集狀態:

testSet:PRIMARY> rs.status()
{
"set" : "testSet",
"date" : ISODate("2017-03-22T07:58:26Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "Centos:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1293,
"optime" : Timestamp(1490168420, 1),
"optimeDate" : ISODate("2017-03-22T07:40:20Z"),
"electionTime" : Timestamp(1490168213, 11),
"electionDate" : ISODate("2017-03-22T07:36:53Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.1.101:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1146,
"optime" : Timestamp(1490168420, 1),
"optimeDate" : ISODate("2017-03-22T07:40:20Z"),
"lastHeartbeat" : ISODate("2017-03-22T07:58:25Z"),
"lastHeartbeatRecv" : ISODate("2017-03-22T07:58:25Z"),
"pingMs" : 1,
"syncingTo" : "Centos:27017"
},
{
"_id" : 2,
"name" : "192.168.1.102:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1086,
"optime" : Timestamp(1490168420, 1),
"optimeDate" : ISODate("2017-03-22T07:40:20Z"),
"lastHeartbeat" : ISODate("2017-03-22T07:58:25Z"),
"lastHeartbeatRecv" : ISODate("2017-03-22T07:58:24Z"),
"pingMs" : 1,
"lastHeartbeatMessage" : "syncing to: Centos:27017",
"syncingTo" : "Centos:27017"
}
],
"ok" : 1
}

測試:

在主節點創建新庫,并插入新數據:

testSet:PRIMARY> show dbs;
admin  (empty)
local  6.075GB
testSet:PRIMARY> use test
switched to db test
testSet:PRIMARY> show dbs
admin  (empty)
local  6.075GB
testSet:PRIMARY> db.test.insert({"name":"菜鳥教程"})
WriteResult({ "nInserted" : 1 })
testSet:PRIMARY> show dbs
admin  (empty)
local  6.075GB
test   0.078GB

查看從節點信息:

testSet:SECONDARY> show dbs;
admin  (empty)
local  6.075GB
test   0.078GB
testSet:SECONDARY> db.test.find()
{ "_id" : ObjectId("58d231485934aa983f070c99"), "name" : "菜鳥教程" }

問題及解決:
1.初始化副本集時報錯:

>rs.initialte()
{
    ....
     "errmsg" "couldn't initiate : can't find self in the replset config" ,"ok" : 0
    ....
}

解決:編輯hosts文件添加主機名稱解析,之后重新初始化副本集。

[root@Centos ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 Centos

2.添加副本集成員時報錯:

testSet:PRIMARY> rs.add("192.168.1.101:27017")
{
"errmsg" : "exception: need most members up to reconfigure, not ok : 192.1.101:27017",
"code" : 13144,
"ok" : 0
}

解決:由于從節點配置文件中bind綁定為127.0.0.1的ip信息,從而導致不能添加192端的ip,將其bind注釋掉。

Mongodb副本集實現

3.添加完成員,查看副本集狀態時,節點一直 顯示如:"stateStr" : "UNKNOWN"

Mongodb副本集實現

解決:問題的原因是rs.initiate()默認將primary的host鍵設置成機器的主機名,如下:

Mongodb副本集實現

1)可以編輯兩個從節點的hosts文件添加主節點主機名和Ip信息,如:

[root@RedHat-1 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.100 Centos

2)可以將primary的主機名改成IP地址:

cfg = rs.conf()
cfg.members[0].host = "192.168.1.100:27017"
rs.reconfig(cfg)


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女