一、工作原理
1. MongoDB 2.6版本開始推薦使用複本集,對主從複製已經不再推薦.
2. 複本集至少需要3個, 可以3個全部做複本集, 也可以讓其中一個做仲裁.
3. 複本集中只有1台主才能進行寫,其餘的只能讀.
4. 複本集之間的複製是通過oplog日誌現實的.備份節點通過查詢這個集合就可以知道需要進行複製的操作.
5. oplog是節點中local庫中的一個固定的集合,在預設情況下oplog初始化大小為空白閑磁碟的5%.oplog是capped collection,所以當oplog的空間被佔滿時,會覆蓋最初寫入的日誌.
6. 通過改變oplog文檔的大小直接改變local所佔磁碟空間的大小.可以在設定檔中設定oplogSize參數來指定oplog文檔的大小,例如oplogSize=1024單位預設為M 每個local文檔在磁碟空間的空間都為2G,設定不足2G的,初始化依然為2G大小,例如上面oplogSize=1024,但建立的local.01大小依然為2G.
7. 如果備份節點不幸掛掉,由於複製過程中是先寫資料,再寫oplog,這樣重新啟動時,可能會重複復制操作.但MongoDB在設計過程中已經考慮過這個問題.當 oplog中同一個操作執行多次的時候,只執行一次.
8. 初始化工作.
a) 備份找到一個同步的主節點,然後再到local.me中建立一個標識符.開始同步的過程中,需要清空備節點的所有資料庫(版本:2.6.7).
b) 通過oplog中的操作記錄,把資料複製在備份節點.
c) 完全同步時開始建立索引.
9. 如果備節點的同步速度遠遠跟不上主節點的oplog寫入的資料,並且主節點的oplog被覆蓋.這樣,可能就無法同步那些被覆蓋的資料(出現這種情況,暫時還無法解決,只能通過備份主節點的資料,然後再重新同步).
10. 每個成員通過心跳去查看其他節點的狀態,每隔2秒鐘就有一次心跳檢測.
11. 當主節點宕機之後,各個節點通過選舉的方式來選擇下一個主節點.
二、安裝方法
1. 3台機器上分別裝上MongDB 服務.
192.168.10.21:27017 (備)
192.168.10.26:27017 (備)
192.168.10.27:27018 (主)
2. 設定密碼認證檔案.
可以使用grub-md5-crypt產生加密檔案.
把產生的密文放到一個檔案中.並且3台機器要有相同的密文.
這裡把密文放到mongodb主目錄下的mongod_key檔案中.
3. 3個mongo分別設定自己admin庫的登入許可權.
這個具體方法可以略掉.
4. 配置mongo.conf檔案.
192.168.10.27 (主)的設定檔
192.168.10.21 (備)的設定檔
192.168.10.26 (備)的設定檔
5. 關閉每台機器的防火牆
/etc/init.d/iptables stop
6. 啟動每台機器上的mongodb
7. 在主機上進行初始化工作,一般在哪台機器上初始化,主就是哪台機器.但是,也可以用權重來控制哪台為主.
config_repl={_id:'alex',members:[
{_id:0,host:'192.168.10.27:27018',priority:10},
{_id:1,host:'192.168.10.26:27017',priority:9},
{_id:2,host:'192.168.10.21:27017',priority:9}]}
這裡的priority越大,主就是哪一台
然後執行rs.initiate(config_repl);
這時複本集已經配置完成.
可以用rs.status() 查看各個節點狀態.
以我的理解,查看備庫同步到主庫的什麼位置,可以通過optime來看
8. 設定複本集後,備節點預設是不能讀資料的,但可以設定rs.slaveOk().
但只對當前session有效.
如果用程式去串連,實現讀寫分離.例如JAVA有相應的方法和參數去達到這一點
9. 切換主-備. (192.168.10.26 提升為主)
rs.conf() # 查看配置
執行:
cfg=rs.conf();
cfg.members[1] = 11 # 把id為1的主機priority改為11
rs.reconfig(cfg)
10. 查看同步狀態.
上面第9步操作使192.168.10.26升級成為主了.
db.printSlaveReplicationInfo();
再執行
use local
db.oplog.rs.find();
可以查看到同步的語句.
{ "ts" : Timestamp(1448257041, 1), "h" : NumberLong("-1393509695161116878"), "v" : 2, "op" : "i", "ns" : "bbbb.test1", "o" : { "_id" : ObjectId("5652a6116894d5b1bcd83dd2"), "a" : 111 } }
含義解釋如下:
ts: 8位元組的時間戳記,由4位元組unix timestamp + 4位元組自增計數表示。這個值很重要,在選舉(如master宕機時)新primary時,會選擇ts最大的那個secondary作為新primaryop:1位元組的操作類型i :insertu :updated :deletec :db cmddb:聲明當前資料庫 (其中ns 被設定成為=>資料庫名稱+ '.')n : no op,即空操作,其會定期執行以確保時效性ns:操作所在的namespaceo :操作所對應的document,即當前操作的內容(比如更新操作時要更新的的欄位和值)o2: 在執行更新操作時的where條件,僅限於update時才有該屬性