為什么用復(fù)制

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

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

復(fù)制的作用

  • 保證數(shù)據(jù)的安全性

  • 保證數(shù)據(jù)的高可用性(24*7)

  • 用戶災(zāi)難恢復(fù)

  • 不需要停機維護(如備份,重建索引,壓縮等任務(wù))

  • 讀寫的靈活性

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

副本集

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

主節(jié)點(Primary)

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

從節(jié)點(Secondary)

可以提供查詢服務(wù),這樣就可以減少主節(jié)點的壓力,當客戶端進行數(shù)據(jù)查詢時,請求自動轉(zhuǎn)到從節(jié)點上。

仲裁節(jié)點(Arbiter)

仲裁節(jié)點是一種特殊的節(jié)點,它本身并不存儲數(shù)據(jù),主要作用在于,當主節(jié)點掛掉以后,通過投票的方式?jīng)Q定哪個從節(jié)點成為主節(jié)點。如果沒有仲裁節(jié)點,如果主節(jié)點掛掉,那么整個副本集中就沒有了主節(jié)點。

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

  1. 副本集具有 2 個或多個節(jié)點(但一般最少需要 3 個節(jié)點)。

  2. 副本集只有一個主節(jié)點,其他全是從節(jié)點。

  3. 所有數(shù)據(jù)都是從主節(jié)點復(fù)制到從節(jié)點上的。

  4. 當發(fā)生自動故障轉(zhuǎn)移或維護時,會重新推舉一個新的主節(jié)點。

  5. 當失敗節(jié)點恢復(fù)后,該節(jié)點重新又連接到副本集中,重新作為從節(jié)點。

下面展示一下典型的 MongoDB 復(fù)制圖,客戶端從主節(jié)點讀取數(shù)據(jù),在客戶端寫入數(shù)據(jù)到主節(jié)點時, 主節(jié)點與從節(jié)點進行數(shù)據(jù)交互保障數(shù)據(jù)的一致性。

photoshop培訓,電腦培訓,電腦維修培訓,移動軟件開發(fā)培訓,網(wǎng)站設(shè)計培訓,網(wǎng)站建設(shè)培訓

副本集特點

  • 具有 N 個節(jié)點的集群

  • 任何節(jié)點都可能成為主節(jié)點

  • 所有寫入操作必須由主節(jié)點來完成

  • 自動故障轉(zhuǎn)移

  • 自動故障恢復(fù)

  • 重新推舉主節(jié)點

創(chuàng)建副本集

1、關(guān)閉正在運行的 MongoDB 服務(wù)器

2、通過指定 --replSet 選項來啟動mongoDB。--replSet 基本語法格式如下:

1
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"

范例

因為沒有安裝虛擬機,就把 MongoDB 文件夾放在C盤、D盤、E盤、F盤,模擬放在多個服務(wù)器上。

1、先啟動C盤上的 MongoDB 服務(wù)器:127.0.0.1:27017,指定端口為27017,并取副本集的名稱為 "myRep"

1
mongod --port 27017 --dbpath c:\data\db --replSet myRep

2、然后啟動D盤上的 MongoDB 服務(wù)器:127.0.0.1:27020,指定端口為27020,并取副本集的名稱為 "myRep"

1
mongod --port 27020 --dbpath d:\data\db --replSet myRep

3、MongoDB 中用 rs.initiate() 命令初始化一個副本集,打開C盤上的 Mongo shell,輸入以下命令

1
2
3
4
5
6
7
8
9
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),給副本集添加節(jié)點。請記住,使用 rs.add() 之前,一定要用 rs.initiate() 初始化副本集,沒有參數(shù)也可以。我們先啟動E盤上 MongoDB 服務(wù)器:127.0.0.1:27022,指定端口為27022,并取副本集的名稱為 "myRep"

1
mongod --port 27022 --dbpath e:\data\db --replSet myRep

5、我們用 rs.add() 命令添加一個節(jié)點。把服務(wù)連接到 主節(jié)點 上,在 Mongo shell 中輸入以下命令

1
rs.add("127.0.0.1:27022")

6、沒有仲裁節(jié)點的副本集是不完整的,MongoDB 中使用 rs.addArb(HOST_NAME:PORT) 命令添加仲裁節(jié)點。我們先啟動F盤上 MongoDB 服務(wù)器:127.0.0.1:27030,指定端口為27030,并取副本集的名稱為 "myRep"

1
mongod --port 27030 --dbpath f:\data\db --replSet myRep

7、我們用 rs.addArb() 命令添加一個仲裁節(jié)點。把服務(wù)連接到 主節(jié)點 上,在 Mongo shell 中輸入以下命令

1
rs.addArb("127.0.0.1:27030")

8、MongoDB 可以使用 rs.status() 命令查看副本集的狀態(tài),可以清楚的看出哪個服務(wù)器是主節(jié)點,哪個服務(wù)器是從節(jié)點,哪個服務(wù)器是仲裁節(jié)點。在返回的結(jié)果中,members 文檔中可以清楚的看到字段 stateStr 的值,該值標識服務(wù)器屬于哪個類型的節(jié)點。通過返回結(jié)果可以看到C盤的 MongoDB 服務(wù)器是主節(jié)點。因為 status() 返回的結(jié)果太長,我就不截圖了。

9、副本集已經(jīng)建好了,是不是特別想試試它的奧秘啊,我們用 Mongo shell連接到主節(jié)點服務(wù)器,添加 user 集合,并添加文檔

1
2
3
4
mongodb://127.0.0.1:27017   #連接主節(jié)點服務(wù)器
...db
test
myRep:PRIMARY>db.user.insert({"name":"liruihuan","age":18})

10、我們再連接到D盤上的服務(wù)器:127.0.0.1:27020,查看 test 數(shù)據(jù)庫中是否有 user 集合,如果有,并查看 user 中的文檔。

1
2
3
4
5
6
7
8
mongodb://127.0.0.1:27020   #連接D盤上的服務(wù)器
...db
test
myRep:PRIMARY>show collections  #查看數(shù)據(jù)庫 test 中的集合
user
myRep:PRIMARY>db.user.find()
{"_id" : ObjectId("58f0857b54caa5a0e463db06"), "name" "liruihuan""age" : 18}
myRep:PRIMARY>

哇,我們發(fā)現(xiàn)D盤上的服務(wù)器已經(jīng)存在數(shù)據(jù)了。 

 

業(yè)精于勤,荒于嬉;行成于思,毀于隨。

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

http://www.cnblogs.com/liruihuan/p/6709741.html