簡介
在生產環境中,爲了保證數據的安全性,我們通常要使用冗餘保存。MongoDB中我們提供了這個功能,也就是MongoDB的複製。
主從複製
主從是複製是MongoDB中最常見的複製方式,可以用於備份、故障恢復、讀擴展等方面。
這種方式一般設置有1個主節點1到多個從節點,每個從節點都要知道主節點的位置並且從節點從主節點複製數據。一般情況下,從節點不要超過12個,同時。主節點與從節點不同的地方在於主節點有oplog,但是從節點沒有。
MongoDB的主從設置方式和Hadoop不一樣,Hadoop是要在每個節點的hadoop配置文件中配置,而MongoDB是在啓動MongoDB實例的時候來指明當前實例是主節點還是從節點:
啓動主節點:
mongod --dbpath 主節點數據目錄 --port 端口號 --master
啓動從節點:
mongod --dbpath 從節點數據目錄 --port 端口號 --slave --source 主節點IP:port
主從複製的選項
--only
從節點使用,指明當前從節點只複製某個數據庫
--slavedelay
從節點使用,應用主節點的最新操作的延時時間。防止主節點的錯誤操作直接的應用到從節點上,起到防護數據作用。
--fastsync
以主節點的數據快照爲基礎啓動從節點,如果一開始就是使用數據庫快照,那麼以後的複製速度會較快。
--autoresync
如果主從節點不同步,則自動重新同步。
--oplogSize
主節點oplog的大小,單位是M。
添加、刪除主節點
當啓動從節點的時候,可以通過--source來指定主節點的網絡位置,也可以在啓動從節點時不指定--source,而是使用MongoDB給我們提供的命令添加或主節點:
use local//必須使用local數據庫
db.sources.insert({'host':'IP:PORT'})
從上邊的命令,我們可以看到MongoDB中從節點保存主節點信息的方式是在local數據庫的sources集合中,所以相應的,我們就可以通過對local數據庫中的sources集合修改實現從節點指向的主節點的變更,這個變更是熱變更不需要重啓從節點的MongoDB實例。
同時一個從節點可以複製多個主節點。
副本集
副本集就是有自動故障恢復功能的主從集羣。副本集和主從複製相同的地方是他們都是由一個主節點和多個從節點構成的,而不同之處在於主從複製中的主節點是固定不變的,而副本集中的主節點是會改變的。
副本集中主節點的變化是全自動的、透明的。
每個副本集都有一個唯一的名稱。
副本集操作
啓動方式
- 啓動副本集中的各個節點:
副本集節點1啓動:
mongod --dbpath 數據目錄--port 端口號 --replSet 副本集名稱/ip地址或hostname2:端口號2(雖然2還沒有啓動)
副本集節點2啓動
mongod --dbpath 數據目錄--port 端口號 --replSet 副本集名稱/ip地址或hostname2:端口號2
副本集節點N啓動
mongod --dbpath 數據目錄--port 端口號 --replSet 副本集名稱/ip地址或hostname1:端口號1
- 使用mongo shell初始化副本集(隨便連接一個副本集節點即可,只需要初始化一次)
useadmin//使用管理數據庫
db.runCommand({'replSetInitiate':
'_id':副本集名稱,
'members':[
{
'_id':節點編號,從1開始的數字,
'host':'IP地址或hostname:端口號'
},
{
'_id':節點編號,從1開始的數字,
'host':'IP地址或hostname:端口號'
}
]
})
向存在副本集中添加節點
- 首先,在要添加到副本集的節點上執行:
mongod --dbpath 數據目錄 --replSet 副本集名稱
- 然後,使用shell連接到副本集中的主節點,執行:
rs.add('IP;port',是否仲裁節點)
從存在的副本集中刪除節點
在主節點上調用rs.remove('ip:port')即可刪除節點。
查看副本集運行狀態
在主節點上調用rs.status(),返回的文檔就是當前節點所在的副本集運行的狀態。stateStr指明瞭所在members數組元素的狀態,primary爲活躍節點。
節點說明
任何時間,副本集中有且只有一個活躍節點,其他的都是備份節點。有幾種不同類型的節點可以存在於副本集中:
- standard
常規節點,存儲一份完整的數據副本,可以成爲活躍節點。
- passive
被動節點,存儲完整的數據副本,不能成爲活躍節點
- arbiter
仲裁者節點,不會保存數據,也不能成爲活躍節點。只能投票。
所有的節點信息都保存在local.system.replset集合中,我們可以通過修改該集合中某個節點的priority來設定該節點的優先級(0-1000),通過arbiterOnly設置該節點是否是仲裁節點。
對於節點的優先級,優先級高的節點成爲活躍節點的概率越高,當優先級相同時,數據越新那麼越會成爲活躍節點。
副本集功能
副本集不只是可以很好的冗餘保存數據,保證應用7*24運行。同意也可以做一些特殊的應用擴展,例如:
- 讀擴展
主節點執行寫入操作,而從節點執行查詢操作。但是一定要注意的是,從節點複製主節點數據時有一定延遲的,所以在使用讀擴展的時候,一定要考慮到從節點的數據同步延遲性。
- 利用從節點處理數據
可以利用從節點來處理數據,一定要保證從節點與主節點的數據同步性,以及數據拷貝延遲性。
工作原理
簡單的來說,MongoDB複製的工作原理很簡單,也就是由主節點負責與客戶端交互,記錄客戶端操作。從節點通過定期輪詢主節點,得到客戶端操作記錄,在從節點自身執行這些操作,從而保證數據的一致性。在同步的過程中,需要用到以下文件:
- Oplog
主節點的操作記錄就是oplog。oplog存儲在local(本地)數據庫中oplog.$main集合中。oplog中只記錄對數據庫數據變更的操作即曾刪改操作,查詢操作不會記錄,同時oplog記錄的操作會進過MongoDB處理後記錄,不一定和客戶端的原始操作完全一樣。存儲oplog的集合是一個固定集合,當集合滿的時候,新操作會自動替換舊操作,啓動MongoDB實例的時候使用--oplogSize指定存儲oplog集合的大小
特殊說明:
- 從節點第一次啓動,會全複製主節點的數據,然後去查詢oplog並執行oplog。如果oplog所在的固定集合太小或者複製數據時間太長,那麼從節點就會被主節點數據落下很遠,這個時候使用oplog的數據已經不能保證主從節點的數據一致性了。雖然可以通過命令:resync或啓動從節點的時候使用--autoresync命令自動重新同步,但是不能完全解決這個問題。最好的解決辦法是配置足夠大的oplog集合。即使用--oplogSize命令設置。
- MongoDB中local數據庫的內容是不會被複制的。
監控複製狀態
在主節點中,使用db.printReplicationInfo()函數,可以得到oplog的大小和oplog中可存儲數據的時間段。
在從節點中,使用db.printSlaveReplicationInfo()函數可以得到當前從節點的數據源列表,以及滯後時間。