mongodb 復制集 維護小結


副本集成員最多12個成員,其中只有7個成員擁有投票權。這是為了減少 心跳請求的網絡流量和選舉話費的時間。心跳每2秒發送一次。
 

一、新增副本集成員


1、登錄primary
2、use admin >rs.add("new_node:port") 或 rs.add({"_id":4,"host":"new_node:port","priority":1,"hidden":false})   
3、use admin>rs.addArb("new_node;port") 或 rs.addArb({"_id":5,"host":"new_node:port"})或rs.add({'_id':5,"host":"new_node:port","arbiterOnly":true})
仲裁者唯一的作用就是參與選舉,仲裁者並不保存數據,也不會為客戶端提供服務。成員一旦以仲裁者的身份加入副本集中,它就永遠只能是仲裁者,無法將仲裁者
重新配置為非仲裁者,反之亦然。最多只能有一個仲裁者每個副本集中。
注:如果 復制集中 priority=1 (默認),調用rs.add("new_node:port") 該命令 會產生 主從切換 即選舉操作;
      如果 復制集中 priority=1 (默認),直接調用rs.remove("new_node:port") 該命令 也會產生 主從切換 ;
 
二、刪除副本集成員
 
1、登錄要移除的目標mongodb實例;
2、利用shutdownServer()命令關閉實例;即 db.shutdownServer()
3、登錄復制集的primary;
4、primary>use admin
     primary>rs.remove("del_node:port");
 
三、修改成員的優先級及隱藏性
 
1、登錄primary
2、use admin >conf=rs.conf()
mongo>conf.members[1].priority=[0-1000]
mongo>conf.members[1].hidden=true #priority必須為0
mongo>conf.members[9].tags={"dc":"tags_name1"} 
mongo>rs.reconfig(conf);  # 強制重新配置 rs.reconfig(conf,{"force":true})
成員的屬性有下列選項
  [, arbiterOnly : true]
      [, buildIndexes : <bool>]
      [, hidden : true]
      [, priority: <priority>]
      [, tags: {loc1 : desc1, loc2 : desc2, ..., locN : descN}]
      [, slaveDelay : <n>]#秒為單位。
      [, votes : <n>]
如果該成員要設置為 隱藏(hidden:true) 或延遲(slaveDelay:30) 則其優先級priority必須設置為 0;
也就是說 隱藏成員和延遲成員及buildIndexs:false的成員 的優先級別一定必須是0 即priority=0.
優先級為0的成員不能發起選舉操作。
只要優先級>0即使該成員不具有投票資格,也可以成為主節點。
如果某個節點的索引結構和其他節點上的索引結構不一致,則該節點就永遠不會變為主節點。
優先級用於表示一個成員渴望成為主節點的程度。優先級的取值范圍是[0-100],默認為1。優先級為0的成員永遠不能成為主節點。
使用rs.status()和rs.config()能夠看到隱藏成員,隱藏成員只對rs.isMaster()不可見。客戶端連接到副本集時,會調用rs.isMaster()
來查看可用成員。將隱藏成員設定為非隱藏成員,只需將配置中的hidden設定為false,或刪除hidden選項。
每個成員可以擁有多個標簽tags {“dc":"tags_name2",qty:"tag_name3"}
votes:0 代表阻止這些成員在選舉中投主動票,但是他們仍然可以投否決票。
 
修改副本集成員配置時的限制:
1、不能修改_id;
2、不能講接收rs.reconfig命令的成員的優先級設置為 0;
3、不能將仲裁者成員變為非仲裁者成員,反正亦然;
4、不能講 buildIndexes:false 改為 true;
 
 
四、查看副本集成員數據同步(延遲)情況
 
mongo>db.printReplicationInfo();
mongo>db.printSlaveReplicationInfo();#最好在secondary上執行
mongo>rs.printReplicationInfo()
mongo>rs.printSlaveReplicationInfo()
mongo>use local>db.slaves.find()
在主節點上跟蹤延遲:
local.slaves該集合保存着所有正從當前成員進行數據同步的成員,以及每個成員的數據新舊程度。
登錄主節點
>use local
>db.slaves.find()、
查看其中每個成員對應的"syncedTo":{"t":9999999,"i":32} 部分即可知道數據的同步程度。
"_id"字段的值是每個當前成員服務器標識符。可以到每個成員的local.me.find()查看本服務器標識符。
1、
如果多台服務器擁有相同的_id標識符,則依次登錄每台服務器成員,刪除local.me集合(local.me.dorp()),然后重啟mongodb,
重啟mongod后,mongod會使用新的“_id”重新生成local.me集合。
 
2、如果服務器的地址改變但_id沒有變,主機名變了,該情況會在本地數據庫的日志中看到重復鍵異常(duplicate key exception)。
解決方法是:刪除local.slaves集合即可,不需要重啟mongod。
 
因為mongod不會清理local.slaves集合,故里面的數據可能不准確或過於老舊,可將整個集合刪除。當有新的服務器將當前成員作為
復制源時,該集合會重新生成。如果在主節點中看到了某個特定的服務器在該集合中有多個文檔,即表示備份節點之間發生了復制鏈,
該情況不影響數據同步,只是把每個備份節點的同步源告訴主節點。
 
 
刪除local.me集合,需要重新啟動mongod,mongod啟動時會使用新的 _id重新生成local.me集合。
 
刪除local.slaves集合,不用重啟mongod。該集合中的數據是記錄該成員被作為同步源的服務器的數據。該集合用於報告副本集狀態。
刪除后不久如果有新的節點成員將該服務器節點作為復制源,該集合就會重新生成。
 
五、主節點降為secondary
mongo>use admin
mongo>rs.stepDown(60)#單位為 秒
 
六、鎖定指定節點在指定時間內不能成為主節點(阻止選舉)
mongo>rs.freeze(120)#單位為 秒
釋放阻止
mongo>rs.freeze(0)
 
七、強制節點進入維護模式(recovering)
可以通過執行replSetMaintenanceMode命令強制一個成員進入維護模式。
例如自動檢測成員落后主節點指定時間,則將其轉入維護模式:
function maybeMaintenanceMode(){
var local=db.getSisterDB("local");
if (!local.isMaster().secondary)
{return;
)
var last=local.oplog.rs.find().sort({"$natural":-1}).next();
var lasttime=last['ts']['t'];
if (lasttime<(new date()).getTime()-30)
{db.adminCommand({"replSetMaintenanceMode":true});
}
};
將成員從維護模式轉入正常模式。即恢復:
db.adminCommand({"replSetMaintenanceMode":false});
 
八、阻止創建索引(不可再修改為可以創建索引,故慎重考慮)
通常會在備份節點的延遲節點上設置阻止創建索引。因為該節點通常只是起到備份數據作用。設置選項 buildIndexs:false即可。該選項是永久性的。如果要將不創建索引的成員修改為可以創建索引的成員,那么必須將這個成員從副本集中移除,再刪除它上的所有數據,最后再將其重新添加到副本集中。並且允許其重新進行數據同步。該選項也要求成員的優先級為 0.
 
九、指定復制源(復制鏈) 查看復制圖譜
使用db.adminCommand({"replSetGetStatus":1})['syncingTo'] 可以查看復制圖譜(每個節點的同步源);
在備份節點上執行 rs.status()['sysncingTo'] 同樣可以查看復制圖譜(同步源);
mongodb是根據ping時間來選擇同步源的,會選擇一個離自己最近而且數據比自己新的成員作為同步源。
可以使用replSetSyncFrom 命令來指定復制源或使用輔助函數rs.sysncFrom()來修改復制源。
db.adminCommand({"replSetSyncFrom":"server_name:port"});
 
副本集默認情況下是允許復制鏈存在的,因為這樣可以減少網絡流量。但也有可能
花費是時間更長,因為復制鏈越長,將數據同步到全部服務器的時間有可能就越長(比如每個備份節點都比前一個備份節點稍微舊點,這樣就得
從主節點復制數據)。
解決方法:
1、手動改變復制源
登錄備份節點:use admin
db.adminCommand({"replSetSyncFrom":"新復制源"})
rs.syncFrom("新復制源")
副本集中的成員會自動選擇其他成員作為復制源。這樣就會產生復制鏈。
如果一個備份節點從另一個備份節點(而非主節點)復制數據時,就會形成復制鏈。
復制鏈是可以被禁用的,這樣就可以強制要求所有備份節點都從主節點復制數據。
 
禁用復制鏈:即禁止備份節點從另一個備份節點復制數據。
var config=rs.config()
config.settings=config.settings ||{}
config.settings.chainingAllowed=false
rs.reconfig(config);
 
十、強制修改副本集成員
var config=rs.config()
config.member[n].host=...
config.member[n].priority=...
.....
rs.reconfig(config,{"force":true})
 
十一、修改Oplog集合的大小
 
如果是主節點,則先將primary 降為 secondary。最后確保沒有其他secondary 從該節點復制數據。rs.status()
1、關閉該mongod服務 use admin >db.adminCommand({shutdownServer:1});
2、以單機方式重啟該mongod(注釋掉 配置文件中的 replSet    shardsvr ,修改端口號)
3、將local.oplog.rs中的最后一條 insert 操作記錄保存到臨時集合中
mongo> use local
mongo>var cursor=db.oplog.rs.find({"op":"i"});
mongo>var lastinsert=cursor.sort({$natural:-1}).limit(1).next();
mongo>db.templastop.save(lastinsert);
mongo>db.templastop.findOne()#確保寫入
4、將oplog.rs 刪除: db.oplog.rs.drop();
5、創建一個新的oplog.rs集合: db.createCollection("oplog.rs":{"capped":true,"size":10240});
6、將臨時集合中的最后一條insert操作記錄寫回新創建的oplog.rs:
var temp=db.templastop.findOne();
db.oplog.rs.insert(temp);
db.oplog.rs.findOne()#確保寫回,否則 該節點重新加入副本集后會刪除該節點上所有數據,然后重新同步所有數據。
7、最后將該節點以副本集成員的身份重新啟動即可。
 
十二、為復制集成員設置選項
 
即當運行rs.initiate(replSetcfg) 或運行 rs.add(membercfg)選項時,需要提供描述復制集成員的特定配置結構:
{
_id:replSetName,
members:
[
{_id:<number>,host:<hostname|ip[:port]>,
[priority:<priority>,]#默認值為1.0.即選項的值是浮點型
[hidden:true,]#該元素將從db.isMaster()的輸出中隱藏該節點。
[arbiterOnly:true,]#默認值為 false
[votes:<n>,]#默認值為1 。改選項的值為整形
[tags:{documents},]
[slaveDelay:<seconds>,]
[buildIndexes:true,]#默認值為 false。該選項用於禁止創建索引。
}],
settings:{
[chainingAllowed:<boolen>,]#指定該成員是否允許從其他輔助服務器復制數據。默認值為 true
[getLastErrorModes:<modes>,]#模式:用於自定義寫顧慮設置
[getLastErrorDefaults:<lasterrdefaults>,]#默認值:用於自定義寫顧慮設置。
}
}
以上是復制集的完整的配置結構。最高級的配置結構包括3級:
_id、members、settings。
_id是復制集的名稱,與創建復制集成員時時候用的 --replSet命令選項時提供的名稱一樣。
members是數組,由一個描述每個成員的集合組成;這是添加單個服務器到集合中時,應該在rs.add()命令中提供的成員機構;
settings也是數組,該settings數組包含應用到整個復制集的選項。這些選項可以設置復制集成員間如何通信。
 
 
十三、 Rollback
mongodb只支持小於300M的數據量回滾,如果大於300M的數據需要回滾或要回滾的操作在30分鍾以上,只能是手動去回滾。會在mongodb日志中報以下錯誤:[replica set sync] replSet syncThread: 13410 replSet too much data to roll back
經量避免讓rollback發生。方法是:使用 復制的 寫顧慮(Write Concern)規則來阻止回滾的發生。
如果發生了回滾操作,則會在mongodb數據文件目錄下產生一個以database.collection.timestamp.bson的文件。查看該文件的內容用 bsondump 工具來查看。
 
十四 、讀偏好設置(ReadPreferred)
讀取偏好是指選擇從哪個復制集成員讀取數據的方式。可以為驅動指定5中模式來設置讀取偏好。
readPreference=primary|primaryPreferred|secondary|secondaryPreferred|nearest
setReadPreferred()命令設置讀取偏好。
 
primary:只從主服務器上讀取數據。如果用戶顯式指定使用標簽讀取偏好,該讀取偏好將被阻塞。這也是默認的讀取偏好。
primaryPreferred:讀取將被重定向至主服務器;如果沒有可用的主服務器,那么讀取將被重定向至某個輔助服務器;
secondary:讀取將被重定向至輔助服務器節點。如果沒有輔助服務器節點,該選項將會產生異常;
secondaryPreferred:讀取將被重定向至輔助服務器;如果沒有輔助服務器,那么讀取將被重定向至主服務器。該選項對應舊的“slaveOK”方法;
nearest:從最近的節點讀取數據,不論它是主服務器還是輔助服務器。該選項通過網絡延遲決定使用哪個節點服務器。
 
十五 、寫顧慮設置(Write Concern)
寫顧慮類似讀取偏好,通過寫顧慮選項可以指定在寫操作被確認完成前,數據必須被安全提交到多少個節點。
寫顧慮的模式決定了寫操作時如何持久化數據。參數“w”會強制 getLastError等待,一直到給定數據的成員都執行完了最后的寫入操作。w的值是包含主節點的。
寫顧慮的5中模式:
w=0或不確定:單向寫操作。寫操作執行后,不需要確認提交狀態。 
w=1或確認:寫操作必須等到主服務器的確認。這是默認行為。
w=n或復制集確認:主服務器必須確認該寫操作。並且n-1個成員必須從主服務器復制該寫入操作。該選項更強大,但是會引起延遲。
w=majority:寫操作必須被主服務器確認,同時也需要集合中的大多數成員都確認該操作。而w=n可能會因為系統中斷或復制延遲引起問題。
j=true日志:可以與w=寫顧慮一起共同指定寫入操作必須被寫入到日志中,只有這樣才算是確認完成。
wtimeout:避免getLastError一直等待下去,該值是命令的超時時間值,如果超過這個時間還沒有返回,就會返回失敗。該值的單位是毫秒。如果返回失敗,值在規定的時間內沒有將寫入操作復制到"w"個成員。
該操作只對該連接起作用,其他連接不受該連接的"w"值限制。
db.products.insert(
{ item : "envelopes" , qty : 100 , type : "Clasp" },
{ writeConcern : { w : 2 , wtimeout : 5000 } }
)
wtimeout#代表5秒超時
 
修改默認寫顧慮
cfg = rs.conf()
cfg.settings = {}
cfg.settings.getLastErrorDefaults = { w: "majority" , wtimeout: 5000 }
rs.reconfig(cfg)
 
設置寫等待
db.runCommand({"getLastError":1,w:"majority"})
db.runCommand({"getLastError":1,"w":"majority","wtimeout":10000})
即,表示寫入操作被復制到了多數個節點上(majority 或 數字),這時的 w會強制 getLastError等待,一直到給定數量的成員執行完了最后的寫入操作。而wtimeout是指超過這個時間沒有返回則返回失敗提示(即無法在指定時間內將寫入操作復制到w個成員中),getLastError並不代表寫操作失敗了,而是代表在指定給定wtimeout時間內沒有將寫入操作復制到指定的w個成員中。w是限制(控制)寫入 速度,只會阻塞這個連接上的操作,其他連接上的操作不受影響。
 
十六、讀取偏好和寫顧慮中使用標簽(tags)
 
十七、選舉機制
1、自身是否能夠與主節點連通;
2、希望被選件為主節點的備份節點的數據是否最新;
3、有沒有其他更高優先級的成員可以被選舉為主節點;
4、如果被選舉為主節點的成員能夠得到副本集中“大多數”成員的投票,則它會成為主節點,如果“大多數”成員中只有一個否決了本次選舉,則本次選舉失敗即就會取消。一張否決票相當於10000張贊成票。
5、希望成為主節點的成員必須使用復制將自己的數據更新為最新;
 
十八、數據初始化過程
1、首先做一些記錄前的准備工作:選擇一個成員作為同步源,在local.me集合中為自己創建一個標識符,刪除索引已存在的數據庫,以一個全新的狀態開始進行同步;該過程中,所有的數據都會被刪除。
2、然后克隆,就是將同步源的所有記錄全部復制到本地。
3、然后就進入oplog同步的第一步,克隆過程中的所有操作都會被記錄到oplog中。
4、接下來就是oplog同步過程的第二步,用於將第一個oplog同步中的操作記錄下來。
5、截止當前,本地的數據應該與主節點在某個時間點的數據集完全一致了,可以開始創建索引了。
6、若當前節點的數據仍然落后同步源,那么oplog同步過程的最后一步就是將創建索引期間的所有操作全部同步過出來,防止該成員成為備份節點。
7、現在當前成員已經完成了初始化數據的同步,切換到普通狀態,這時該節點就可以成為備份節點了。
 
十九、mongodb3.0 建議開啟的設置
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
執行上面兩命令后只是當前起作用。如果重啟mongod服務后 就失效。永久起效則
寫入到 /etc/rc.local
即 
 
二十、修改服務器hostname名
1、首先修改 secondary 服務器的 hostname;然后 stop secondary;
2、重啟 secondary 以修改后的新hostname;
3、登錄 primary ;
4、用rs.reconfig()命令修改 復制集的配置信息;
conf=rs.conf()
conf.members[x].host='new_address:27017'
rs.reconfig(conf);
 
二十一、生成 keyfile文件
 
openssl rand -base64 666 > /opt/mongo/conf/MongoReplSet_KeyFile
chown mongod.mongod /opt/mongo/conf/MongoReplSet_KeyFile
chmod 600 /opt/mongo/conf/MongoReplSet_KeyFile


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM