MongoDB基礎教程系列--第八篇 MongoDB 副本集實現復制功能


返回目錄

為什么用復制

為什么要使用復制呢?如果我們的數據庫只存在於一台服務器,若這台服務器宕機了,那對於我們數據將會是災難,當然這只是其中一個原因,若數據量非常大,讀寫操作勢必會影響數據庫的性能,這時候復制就顯得相當重要了,因為 MongoDB 可以通過復制,實現讀寫分離。

復制是一種在多個服務器上同步數據的過程。通過在不同的數據庫服務器上實現多個數據副本。總之,復制可以使你免受硬件故障與服務中斷的影響,及時恢復數據。由於數據有多個副本,所以可以將其中一個副本用於災難恢復、報告或備份。

復制的作用

  • 保證數據的安全性
  • 保證數據的高可用性(24*7)
  • 用戶災難恢復
  • 不需要停機維護(如備份,重建索引,壓縮等任務)
  • 讀寫的靈活性

那么,復制是怎么實現的呢?MongoDB 用副本集實現復制的功能。副本集是一組托管同一數據集的 mongod 對象。在副本集中有三個成員:主節點(Primary)、從節點(Secondary)、仲裁節點(Arbiter)

副本集

先對副本集成員進行說明:

主節點(Primary)

提供所有增、刪、查、改操作

從節點(Secondary)

可以提供查詢服務,這樣就可以減少主節點的壓力,當客戶端進行數據查詢時,請求自動轉到從節點上。

仲裁節點(Arbiter)

仲裁節點是一種特殊的節點,它本身並不存儲數據,主要作用在於,當主節點掛掉以后,通過投票的方式決定哪個從節點成為主節點。如果沒有仲裁節點,如果主節點掛掉,那么整個副本集中就沒有了主節點。

那么,副本集是怎么實現主、從節點的數據同步的呢?原來,主節點上的所有操作都記錄在oplog,從節點定期從主節點獲取這些操作,然后對自己的數據副本執行這些操作,從而保證從節點的數據與主節點一致。

  1. 副本集具有 2 個或多個節點(但一般最少需要 3 個節點)。
  2. 副本集只有一個主節點,其他全是從節點。
  3. 所有數據都是從主節點復制到從節點上的。
  4. 當發生自動故障轉移或維護時,會重新推舉一個新的主節點。
  5. 當失敗節點恢復后,該節點重新又連接到副本集中,重新作為從節點。

下面展示一下典型的 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盤上的服務器已經存在數據了。 

 

業精於勤,荒於嬉;行成於思,毀於隨。

如果你覺得這篇文章不錯或者對你有所幫助,可以通過右側【打賞】功能,給予博主一點點鼓勵和支持


免責聲明!

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



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