mongodb複製集Replica Set使用簡介
MongoDB高可用
對於MongoDB,可以支援使用單機模式提供服務,但是在實際的生產環境中,單機模式將面臨很大的風險,一旦這個資料庫服務出現問題,就會導致線上的服務出現錯誤甚至崩潰。因此,在實際生產環境下,需要對MongoDB做相應的主備處理,提高資料庫服務的可用性。
對於提高可用性,一些博文裡提到了使用主從模式(master-slaver)。
WARNING:
Deprecated since version 3.2: MongoDB 3.2 deprecates the use of master-slave replication for components of sharded clusters.
主從模式是高可用的一種方案。然而從上面這段警告中可以知道,在高版本的MongoDB(3.2以上)中,官方已經不推薦使用主從模式,取而代之的,是使用複製集(Replica Set)的方式做主備處理。
IMPORTANT:
Replica sets replace master-slave replication for most use cases. If possible, use replica sets rather than master-slave replication for all new production deployments. This documentation remains to support legacy deployments and for archival purposes only.
因此,本文將介紹如何將已有的單機MongoDB資料庫拓展為主備模式的複製集,以提高可用性。
複製集 Replica Set
在複製集中,有且只有一個主節點(primary),可以包含一個或多個從節點(secondary),主從節點直接會通過心跳檢測來確定節點是否健康或存活。所有的讀寫操作都是在主節點上進行的,如果要實現讀寫分離,需要進行相應的處理,這個最後會說。從節點會根據oplog(也就是操作日誌)來複制主節點的資料。
MongoDB複製集
除了主從節點外,MongoDB的複製集中還存在著一種叫仲裁者(Arbiter)的角色。一個仲裁者節點是比較輕量級的,因為它不會去複製主庫的資料,因此也就不會成為主節點;但是,它的作用是在投票選舉階段——當主節點故障時,仲裁者可以進行投票。一般來說,不建議一個複製集中包含超過一個仲裁者。
當主節點突然故障後,MongoDB有自己的機制,會自動切換,通過選舉,在從節點中選出一個節點作為新的主節點。
MongoDB複製集故障處理
如何使用複製集
首先,需要在MongoDB例項的啟動引數中加入replSet,指定複製集的名稱。
mongod --port 8017 --dbpath /home/work/data/db1 --replSet rstest
對於已有的單機例項,也可以加入該引數並進行重啟。此外,我們還需要另外啟動兩個MongoDB例項作為從節點,注意replSet引數指定的名稱需要相同。
mongod --port 8016 --dbpath /home/work/data/db2 --replSet rstest mongod --port 8015 --dbpath /home/work/data/db2 --replSet rstest
然後,需要通過mongo命令連線MongoDB服務,進入主節點進行初始化。
mongo 127.0.0.1:8017
rs.initiate({ _id:"rstest", // replSet指定的名稱 members:[{ _id:0, host:"127.0.0.1:8017" // 主節點ip與埠 }] })
需要注意的是,如果是將已有單機拓展為複製集,要在連線原單機的例項並在其中執行使其作為主節點。
最後,再將其他兩個從節點加入到該複製集中。
rs.add("127.0.0.1:8016") rs.add("127.0.0.1:8015")
通過rs.status()
檢視效果,可以看到rstest
這個複製集中已經有了三個節點,stateStr
指明瞭節點的型別,health
為1表明該節點是健康的。
{ "set" : "rstest", "date" : ISODate("2017-10-31T13:04:16.704Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "127.0.0.1:8017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", // 節點的型別,主節點 "uptime" : 1508, "optime" : Timestamp(1509455043, 1), "optimeDate" : ISODate("2017-10-31T13:04:03Z"), "electionTime" : Timestamp(1509454568, 2), "electionDate" : ISODate("2017-10-31T12:56:08Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "127.0.0.1:8016", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 25, "optime" : Timestamp(1509455043, 1), "optimeDate" : ISODate("2017-10-31T13:04:03Z"), "lastHeartbeat" : ISODate("2017-10-31T13:04:15.657Z"), "lastHeartbeatRecv" : ISODate("2017-10-31T13:04:15.108Z"), "pingMs" : 0, "syncingTo" : "127.0.0.1:8017", "configVersion" : 3 }, { "_id" : 2, "name" : "127.0.0.1:8015", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 13, "optime" : Timestamp(1509455043, 1), "optimeDate" : ISODate("2017-10-31T13:04:03Z"), "lastHeartbeat" : ISODate("2017-10-31T13:04:15.657Z"), "lastHeartbeatRecv" : ISODate("2017-10-31T13:04:15.661Z"), "pingMs" : 0, "configVersion" : 3 } ], "ok" : 1}
連線複製集
由於複製集中的切換機制,在主節點故障的情況下,叢集內其他從節點會通過投票方式產生新的主節點,因此,不能像單機情況下那樣,直接連線主節點;否則在MongoDB自動切換主節點時,資料庫訪問就會出問題。因此連線複製集需要特定的連線方式。
在MongoDB的連線字串(connection url)中可以進行指定。
mongodb://[username:[email protected]]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
其中可以指定多個host:port,用英文逗號連線,並在最後的option中支援replicaSet引數,用於指定連線的複製集。例如:
mongodb://127.0.0.1:8017,127.0.0.1:8016,127.0.0.1:8015/books?replicaSet=rstest
這樣就可以連線上覆制集中的books這個資料庫。
總結
MongoDB複製集的故障機制切換是它自身來保障,在部署好上面一系列的服務後,我們可以測試一下當主節點故障時,叢集中的節點狀態與服務可用性。通過kill主節點MongoDB程序,使用rs.status()
可以發現,其中一個從節點已經升級為了主節點(這部分在從節點的日誌中也有體現)。此外,資料查詢依然可以進行,不會因為主節點的宕機而導致資料服務不可用。