MongoDB 搭建副本集

来源:http://www.cnblogs.com/ljhdo/archive/2016/09/29/4503317.html
-Advertisement-
Play Games

副本集(Replica Set)是一組MongoDB實例組成的集群,由一個主(Primary)伺服器和多個備份(Secondary)伺服器構成。通過Replication,將數據的更新由Primary推送到其他實例上,在一定的延遲之後,每個MongoDB實例維護相同的數據集副本。通過維護冗餘的資料庫 ...


副本集(Replica Set)是一組MongoDB實例組成的集群,由一個主(Primary)伺服器和多個備份(Secondary)伺服器構成。通過Replication,將數據的更新由Primary推送到其他實例上,在一定的延遲之後,每個MongoDB實例維護相同的數據集副本。通過維護冗餘的資料庫副本,能夠實現數據的異地備份,讀寫分離和自動故障轉移。

一,MongoDB版本和環境

在Windows上創建包含三個節點的副本集,使用的環境:

  • 資料庫:MongoDB 版本 3.2.9
  • Server 環境:Windows Server 2012 R2
  • 可視化編程環境:Robomongo 版本 0.08.4
  • 三台Windows Server:srv1,srv2,srv3

二,拓撲結構分析

創建一個Replica Set,包含三個成員:一個Primary 成員和兩個Secondary 成員,Primary用於處理客戶端請求,Secondary用於保存Primary的數據副本。客戶端Application 在 Primary 節點上進行讀寫操作,通過Replication的非同步同步機制,將數據操作同步到 Secondary 成員,在一定的延遲之後,三個成員擁有相同的數據集。

理論上,每個成員可以分佈在不同的數據中心機房內,這些數據中心可能相距甚遠,實現數據的異地備份;可以設置Primary 節點只負責寫入操作,而使Secondary節點負責讀取操作,實現數據集的讀寫分離;如果Primary 連接中斷超過10s,其他節點會自動選舉出一個Primary 節點,負責響應客戶端Application的請求,實現數據的自動故障轉移。

三,技術原理說明

1,以Replica Set模式啟動MongoDB實例

MongoDB Instance有兩種不同的啟動方式:單機模式(Standalone)和副本集模式(Replica Set),在啟動mongod時,如果設置 replSet 參數,那麼MongoDB 實例以副本集模式啟動;如果不設置replSet 參數,那麼MongoDB以單機模式啟動。

單機實例是指運行在伺服器上的一個mongod 進程,該進程不是任何一個Replica Set的成員,因此,單機實例不能自動故障轉移,在產品環境中,風險很高,如果伺服器崩潰了,客戶端App至少在一段時間內不可訪問,如果硬體出現問題,可能會造成數據的永久丟失。建議,使用Replica Set,至少保留兩份數據集副本。

2,選舉Primary成員

在Replica Set中有兩種成員:Primary成員和Secondary成員,一個Replica Set只能有一個Primary成員,但可以有多個Secondary成員。Primary用於處理客戶端請求,Secondary用於保存Primary的數據副本。如果Primary崩潰了,Replica Set探測到Primary不可訪問,將啟動自動故障轉移進程,從剩下的Secondary成員中,投票選舉出一個成員作為Primary,接收和處理客戶端的請求。

選舉Primary成員時,使用“大多數”和“一票否決”原則。在Replica Set中,每個成員只能要求自己被選舉為Primary節點。當一個Secondary成員無法與Primary成員連通時,該成員就會發起選舉,請求其他成員將自己選舉為Primary成員,只有得到“大多數”成員的支持,該成員才能被選舉為Primary成員;只要有一個成員否決,選舉就會取消。

不是每一個成員都有投票選舉的權利,在一個Replica Set中,最多有7個成員用於投票選舉的權利,Primary成員是由這7個成員選舉出來的。有投票權利的成員,其屬性:"votes" 是1;若為0,表示該成員沒有投票權利。

3,操作日誌

MongoDB使用操作日誌(oplog)來實現複製(Replication)功能,oplog包含了Primary成員的每一個更新操作,通過將oplog傳遞到其他Secondary成員中,在其他成員中重做(redo)已經提交的操作,實現數據的非同步同步。Replica Set中的每個成員都維護著自己的oplog,記錄著每一個從Primary成員複製操作的數據。複製操作的過程是先複製數據,再將操作寫入到oplog中。如果某一個成員在執行操作時失敗,當該成員重啟之後,自動從oplog中最後一個操作進行同步。由於複製操作的過程是先複製數據,再寫入oplog,該成員可能會在已經同步的數據上再次執行複製操作,MongoDB在設計oplog時,就考慮到這種情況:將oplog中的同一個操作執行多次,與執行一次的結果是一樣的。

oplog保存的是對每個doc的更新操作日誌,如果一個命令只更新一個doc,那麼Replication進程向oplog插入一條日誌;如果一個命令更新多個doc,那麼Replication進程向oplog插入多條日誌,每一條日誌只更新一個doc。

oplog的大小是固定的,只能保存特定數量的操作日誌,如果Primary成員更新的數據量特別大,oplog很快就被填滿,Secondary來不及同步數據,Primary成員就將oplog中的日誌,這樣,Secondary成員就會變成陳舊的(Stale)。建議,讓Primary成員使用比較大的oplog,保存足夠多的操作日誌。

四,創建配置文檔

1,創建mongod 啟動的配置文件

在每台server上創建配置文件,將配置文件存放在目錄C:\data\中。在同一個Replica Set中的所有成員必須有相同的Replica Set Name,這裡設置為“rs0”。

--srv1    config_file_name:rs0_1.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_1.log
port=40001
replSet=rs0

--srv2   config_file_name:rs0_2.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_2.log
port=40002
replSet=rs0

--srv3  config_file_name:rs0_3.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_3.log
port=40003
replSet=rs0

配置參數含義:

  • replSet:設置Replica Set的name,在各個配置文件中,其值必須相同。
  • dbpath:MongoDB用於存儲數據的目錄,預設值是C:\data\db
  • logpath:用於記錄mongod的日誌數據
  • port:指定MongoDB監聽的埠,預設值是27017

2,以配置文件方式啟動mongod

一般情況下,mongod的參數值是不變的,將這些參數寫入到配置文件中,能夠簡化MongoDB的管理。

mongod 命令有參數:--config 或 -f,用於引用配置文件。

--srv1
mongod -f C:\data\rs0_1.conf

--srv2
mongod -f C:\data\rs0_2.conf

--srv3
mongod -f C:\data\rs0_3.conf

3,啟動mongo shell

在任意一臺Server上打開三個mongo shell,使用參數 --host 指定Server Name,使用 --port 指定埠號。由於mongod沒有使用預設的監聽埠 27017,因此,必須使用 在mongo shell中使用 --port參數顯式指定監聽的Port。

--connect srv1
mongo --host srv1 --port 40001

--connect srv2
mongo --host srv2 --port 40002

--connect srv3 
mongo --host srv3 --port 40003

五,配置Replica Set

在不同的Server上運行不同的MongoDB Instance,但是,每個mongod 都不知道其他mongod的存在,為了讓每個mongod能夠感知彼此的存在,需要配置Replica set,增加成員。

1,使用配置文檔為Replica Set 增加成員

在srv1的mongo shell中,創建配置文檔,調用rs.initiate()函數,按照配置文檔來初始化Replica Set。

conf=
{
    "_id" : "rs0",
    "members" : [
        { "_id" : 0,  "host" : "srv1:40001"  },
        { "_id" : 1,  "host" : "srv2:40002"  },
        { "_id" : 2,  "host" : "srv3:40003"  }
    ]
}

rs.initiate(conf)

在配置doc中,使用"_id" : "rs0" 指定Replica Set的name,members數組指定 Replica Set的成員的ID 和 host(“host:port”)。等到所有成員配置完成之後,Replica Set 會自動選舉出一個Primary 節點,兩個Secondary 節點。在Primary 節點上進行更新操作,就能同步到Secondary 節點了。

2,修改Replica Set

如果以rs.initiate()方式初始化Replica Set,那麼MongoDB以預設配置文檔初始化Replica Set,可以通過add()函數增加成員。

2.1 向Replica Set中增加一個成員

rs.add("host:port")

2.2 從Replica Set中刪除一個成員

rs.remove("host")

2.3 查看Replica Set的配置

rs.conf()

2.4 重新配置Replica Set

var conf=rs.conf()
conf.members[1].priority =5

--at primary member
rs.reconf(conf)

--at secondary member rs.reconf(conf,{force:true})

2.5 查看Replica Set的狀態

rs.status()

六,維護Replica Set

1,查看Replica Set的配置信息

rs.conf()

配置文檔主要分為三塊:Replica Set 的ID和 Version,Members數組 和 Settings,下麵是經過簡化的配置信息。

{
    "_id" : "rs0",
    "version" : 202997,
    "members" : [ 
        {
            "_id" : 1,
            "host" : "srv1:40001",
            "arbiterOnly" : false,
            "hidden" : false,
            "priority" : 5,
            "votes" : 1
        }, {...}
    ],
    "settings" : {  .....  }
}

Replica Set的ID欄位唯一標識一個Replica Set,每一個Replica Set都有一個自增的版本號,由Version欄位標識,標識Replica Set的不同版本。version欄位的初始值是1,每次修改Replica Set的配置時,version欄位都會自增。

Settings 欄位的值是應用到Replica Set中所有成員的配置信息。

最關鍵的是members數組的欄位,標識每個成員的配置信息。

  • arbiterOnly:0或1,標識一個仲裁(arbiter),Arbiter的唯一作用是參與Primary的選舉,Arbiter不保存數據,不會為client提供服務,它存在的意義就是為了選舉Primary。
  • hidden:0或1,表示該成員是不是隱藏成員,Hidden成員的主要作用是備份數據,可以使用性能較差的伺服器作為Hidden成員。Hidden成員不會接收Client的請求,也不會成為Primary。在設置Hidden成員時,必須設置members[n].priorty屬性為0;
  • priority數值類型,用於設置成員成為Primary的優先順序。priority越高的成員,越有機會成為Primary。如果priority=0,那麼該成員永遠不會成為Primary。
  • votes:1或0,表示該成員的投票的數量,在每個Replica Set中,最多有7個成員,其votes屬性值是1。votes 屬性是1的成員(voting members)擁有選舉Primary的權利。一個成員要想成為一個Primary,那麼必須獲得voting members的大多成員的支持。

在Replica Set中,如果voting members的數量是5,那麼一個成員成為Primary的條件是:獲得超過2個voting members的支持,並且沒有任何voting members 反對。只要有任意一個voting member 反對該成員成為Primary,那麼該成員就不能成為Primary。

2,強制一個成員成為Primary

如果將一個成員的priority屬性在Replica Set的所有成員中是最高的,那麼該成員最有可能成為Primary。

將成員0的priority設置5,其他成員的priority設置為1,這樣,成員0成為Primary的優先順序是最高的。

cfg = rs.conf()
cfg.members[0].priority = 5
cfg.members[1].priority = 1
cfg.members[2].priority = 1
rs.reconfig(cfg)

七,測試數據

1,在Primary上讀寫數據

db.users.insert({_id:1,name:"a",age:24})

2,在Secondary上讀取數據

預設情況下,客戶端不能從Secondary成員中讀取數據。在Secondary成員上顯式執行setSlaveOk之後,才能從Secondary節點讀取數據。

rs.setSalveOk()

db.users.find({_id:1})

八,查看mongod 伺服器的命令行參數

db.serverCmdLineOpts()

/* 0 */ { "argv" : [ "mongod", "-f", "C:\\data\\rs0_1.conf" ], "parsed" : { "config" : "C:\\data\\rs0_1.conf", "net" : { "port" : 40001 }, "replication" : { "replSet" : "rs0" }, "storage" : { "dbPath" : "C:\\data\\db\\db_rs0" }, "systemLog" : { "destination" : "file", "path" : "C:\\data\\db\\db_rs0\\rs0_1.log" } }, "ok" : 1 }

參考doc:

Replication

Replica Set Tutorials

MongoDB - Replication

Replica Set Configuration

Force a Member to Become Primary


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分組函數 什麼是分組函數 分組函數作用於一組數據,並對一組數據返回一個值 組函數類型:主要有6種 平均 計數 最大 最小 求和 方差 組函數語法 AVG(平均值)和 SUM (合計)函數 可以對 數值型數據 使用AVG 和 SUM 函數。 MIN(最小值)和 MAX(最大值)函數 可以對 任意數據類 ...
  • 【知識點整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和執行速度的比較 1 BLOG文檔結構圖 2 前言部分 2.1 導讀和註意事項 各位技術愛好者,看完本文後,你可以掌握如下的技能,也可以學到一些其它你所不知道的知識,~O(∩_∩)O~ ...
  • 最近抽時間把Redis學了一下,所以就在網上找了一些資料。然後找到 尚矽谷 周陽 老師的視頻教程,覺得裡面的講的挺好。所以就把他視頻當中的資料教程整理出來。 單機MySQL的美好時代 在90年代,一個網站的訪問量一般都不大,用單個資料庫完全可以輕鬆應付。 在那個時候,更多的都是靜態網頁,動態交互類型 ...
  • 在服務端開發過程中,一般會使用MySQL等關係型資料庫作為最終的存儲引擎,Redis其實也可以作為一種鍵值對型的資料庫,但在一些實際場景中,特別是關係型結構並不適合使用Redis直接作為資料庫。這倆家伙簡直可以用“男女搭配,幹活不累”來形容,搭配起來使用才能事半功倍。本篇我們就這兩者如何合理搭配以及... ...
  • 小Alan國慶後就要回深圳找工作了,最近在複習工作所需的相關的技術,今天剛好複習到redis,redis是一個非關係型(NoSql)資料庫,採用key-value的方式存儲數據,她可以保存字元串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted s ...
  • 從定義中我們可以看出方案(Schema)為資料庫對象的集合,為了區分各個集合,我們需要給這個集合起個名字,這些名字就是我們在企業管理器的方案下看到的許多類似用戶名的節點,這些類似用戶名的節點其實就是一個schema,schema裡面包含了各種對象如tables, views, sequences, ...
  • 目錄: 連接hadoop配置語法 配置hadoop連接 Pushdown配置 Create external tables for Azure blob storage 連接hadoop配置語法: global configuration settings for PolyBase Hadoop a ...
  • 1. 索引重建和重組有什麼用? 當修改表(UPDATE、INSERT、DELETE等)中數據,資料庫引擎自動維護索引的數據和結構。但是隨著修改次數的累積,可能會現: 索引中記錄的數據順序(邏輯順序)和數據的實際順序不一致(物理順序),這也稱之為 外部碎片 。 索引頁的數據填充度變小(頁密度),也稱之 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...