為什么用復制
為什么要使用復制呢?如果我們的數據庫只存在於一台服務器,若這台服務器宕機了,那對於我們數據將會是災難,當然這只是其中一個原因,若數據量非常大,讀寫操作勢必會影響數據庫的性能,這時候復制就顯得相當重要了,因為 MongoDB 可以通過復制,實現讀寫分離。
復制是一種在多個服務器上同步數據的過程。通過在不同的數據庫服務器上實現多個數據副本。總之,復制可以使你免受硬件故障與服務中斷的影響,及時恢復數據。由於數據有多個副本,所以可以將其中一個副本用於災難恢復、報告或備份。
復制的作用
- 保證數據的安全性
- 保證數據的高可用性(24*7)
- 用戶災難恢復
- 不需要停機維護(如備份,重建索引,壓縮等任務)
- 讀寫的靈活性
那么,復制是怎么實現的呢?MongoDB 用副本集實現復制的功能。副本集是一組托管同一數據集的 mongod 對象。在副本集中有三個成員:主節點(Primary)、從節點(Secondary)、仲裁節點(Arbiter)
副本集
先對副本集成員進行說明:
主節點(Primary)
提供所有增、刪、查、改操作
從節點(Secondary)
可以提供查詢服務,這樣就可以減少主節點的壓力,當客戶端進行數據查詢時,請求自動轉到從節點上。
仲裁節點(Arbiter)
仲裁節點是一種特殊的節點,它本身並不存儲數據,主要作用在於,當主節點掛掉以后,通過投票的方式決定哪個從節點成為主節點。如果沒有仲裁節點,如果主節點掛掉,那么整個副本集中就沒有了主節點。
那么,副本集是怎么實現主、從節點的數據同步的呢?原來,主節點上的所有操作都記錄在oplog,從節點定期從主節點獲取這些操作,然后對自己的數據副本執行這些操作,從而保證從節點的數據與主節點一致。
- 副本集具有 2 個或多個節點(但一般最少需要 3 個節點)。
- 副本集只有一個主節點,其他全是從節點。
- 所有數據都是從主節點復制到從節點上的。
- 當發生自動故障轉移或維護時,會重新推舉一個新的主節點。
- 當失敗節點恢復后,該節點重新又連接到副本集中,重新作為從節點。
下面展示一下典型的 MongoDB 復制圖,客戶端從主節點讀取數據,在客戶端寫入數據到主節點時, 主節點與從節點進行數據交互保障數據的一致性。
副本集特點
- 具有 N 個節點的集群
- 任何節點都可能成為主節點
- 所有寫入操作必須由主節點來完成
- 自動故障轉移
- 自動故障恢復
- 重新推舉主節點
創建副本集
1、關閉正在運行的 MongoDB 服務器
2、通過指定 --replSet 選項來啟動mongoDB。--replSet 基本語法格式如下:
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
范例
因為沒有安裝虛擬機,就把 MongoDB 文件夾放在C盤、D盤、E盤、F盤,模擬放在多個服務器上。
1、先啟動C盤上的 MongoDB 服務器:127.0.0.1:27017,指定端口為27017,並取副本集的名稱為 "myRep"
mongod --port 27017 --dbpath c:\data\db --replSet myRep
2、然后啟動D盤上的 MongoDB 服務器:127.0.0.1:27020,指定端口為27020,並取副本集的名稱為 "myRep"
mongod --port 27020 --dbpath d:\data\db --replSet myRep
3、MongoDB 中用 rs.initiate() 命令初始化一個副本集,打開C盤上的 Mongo shell,輸入以下命令
rs.initiate( { _id: "myRep", members: [ { _id: 0, host : "127.0.0.1:27017" }, { _id: 1, host : "127.0.0.1:27020" } ] } )
4、除了用 rs.initiate() 命令初始化副本集外,MongoDB 還可以用 rs.add(HOST_NAME:PORT),給副本集添加節點。請記住,使用 rs.add() 之前,一定要用 rs.initiate() 初始化副本集,沒有參數也可以。我們先啟動E盤上 MongoDB 服務器:127.0.0.1:27022,指定端口為27022,並取副本集的名稱為 "myRep"
mongod --port 27022 --dbpath e:\data\db --replSet myRep
5、我們用 rs.add() 命令添加一個節點。把服務連接到 主節點 上,在 Mongo shell 中輸入以下命令
rs.add("127.0.0.1:27022")
6、沒有仲裁節點的副本集是不完整的,MongoDB 中使用 rs.addArb(HOST_NAME:PORT) 命令添加仲裁節點。我們先啟動F盤上 MongoDB 服務器:127.0.0.1:27030,指定端口為27030,並取副本集的名稱為 "myRep"
mongod --port 27030 --dbpath f:\data\db --replSet myRep
7、我們用 rs.addArb() 命令添加一個仲裁節點。把服務連接到 主節點 上,在 Mongo shell 中輸入以下命令
rs.addArb("127.0.0.1:27030")
8、MongoDB 可以使用 rs.status() 命令查看副本集的狀態,可以清楚的看出哪個服務器是主節點,哪個服務器是從節點,哪個服務器是仲裁節點。在返回的結果中,members 文檔中可以清楚的看到字段 stateStr 的值,該值標識服務器屬於哪個類型的節點。通過返回結果可以看到C盤的 MongoDB 服務器是主節點。因為 status() 返回的結果太長,我就不截圖了。
9、副本集已經建好了,是不是特別想試試它的奧秘啊,我們用 Mongo shell連接到主節點服務器,添加 user 集合,並添加文檔
mongodb://127.0.0.1:27017 #連接主節點服務器 ...db test myRep:PRIMARY>db.user.insert({"name":"liruihuan","age":18})
10、我們再連接到D盤上的服務器:127.0.0.1:27020,查看 test 數據庫中是否有 user 集合,如果有,並查看 user 中的文檔。
mongodb://127.0.0.1:27020 #連接D盤上的服務器 ...db test myRep:PRIMARY>show collections #查看數據庫 test 中的集合 user myRep:PRIMARY>db.user.find() {"_id" : ObjectId("58f0857b54caa5a0e463db06"), "name" : "liruihuan", "age" : 18} myRep:PRIMARY>
哇,我們發現D盤上的服務器已經存在數據了。
業精於勤,荒於嬉;行成於思,毀於隨。
如果你覺得這篇文章不錯或者對你有所幫助,可以通過右側【打賞】功能,給予博主一點點鼓勵和支持