258_Mongodb_集合_副本集2

      網友投稿 658 2025-03-31

      MongoDB副本集模式

      通過實時數據同步提高數據的可用性, 包括寫入策略(write concern) 和 讀取策略(read preference)來提升數據的讀寫性能

      1 副本集角色

      258_Mongodb_集合_副本集2

      主節點(primary)

      副節點(secondary)

      仲裁節點(Arbiter)

      一個副本集, 至少包括一個主節點(primary), 與一個副節點(secondary),通過不同的節點與數量,可以配置不同效果的副本集

      主節點與副節點

      主節點與副節點均屬于數據節點,保存完整的數據

      主節點: 接收數據寫入需求, 然后通過同步機制同步到所有的副節點, 節點通過”心跳”機制進行溝通, 確保所有節點正常運行

      仲裁節點 當主宕機后, 參與投票,選出新主,本身不存儲數據, 這樣在資源有限的情況下 給了副本集模式很大彈性

      副本集的基本架構: 1個主節點 + 1個副節點 + 一個沖裁節點 (奇數 3個具有投票權的節點 可進行有效的投票)

      2 高可用(節點故障轉移)

      在副本集中實現高可用 通過以下重要機制

      Oplog 同步

      心跳機制(Hearbeat)

      選舉策略(vote)

      副本集回滾(RollBack)

      Oplog 同步

      主節點的oplog異步同步到從節點,副本集可以在一個或多個成員失敗的情況下繼續運行 從數據庫成員將這些操作復制并應用本身。所有副本集成員都將心跳(ping)發送給所有其他成員,任何從成員都可以從任何其他成員應用操作日志,如果副本集只剩一個節點,該節點會變成從節點(不能寫)操作日志中的每個操作都是冪等的,也就是說oplog操作會產生相同的結果,無論是一次還是多次應用于目標數據集

      Oplog(操作日志)是一個特殊的capped集合,保持所有修改存儲在數據庫中的數據的操作的記錄,類似于MySQL的Binlog

      Oplog 記錄操作記錄, 是副本集成員特有集合,默認固定大小(5% 且不超過50G)可以通過oplogSizeMB 進行設置, 此參數僅在集群初始化前配置有效, 一旦創建完成無法進行修改

      Oplog 本質是一個Capped Collections(環形隊列), 新操作進來,會寫入下一個位置(偏移量 & 時間戳)

      Oplog 會被記錄在數據節點 local庫中 oplog.rs的集合中

      Oplog 初始化

      新加入副本節點如果落后primary太多, 會從副本節點進行完整的數據復制(整個數據文件&oplog, 新節點用全備進行創建,然后構建主從)

      Oplog 同步

      節點同步會對比其它節點狀態, 選擇數據比自己更完整的節點作為同步源進行同步(可指定:use admin; db.adminCommad({replSetSyncFrom: “hostname<:port>”}))

      設置同步源后三種情況會恢復默認同步機制:

      此節點實例重新啟動

      此節點與同步源節點之間斷開連接

      同步源節點數據落后其它副本節點超過30S

      Oplog狀態查看

      rs.printReplicationInfo() 查看oplog的狀態,輸出信息包括oplog日志大小,操作日志記錄的起始時間 configured oplog size: oplog文件大小 log length start to end: oplog日志的啟用時間段 oplog first event time: 第一個事務日志的產生時間 oplog last event time: 最后一個事務日志的產生時間 now: 現在的時間

      db.getReplicationInfo() 可以用來查看oplog的狀態、大小、存儲的時間范圍 在primary/secondary上查看從庫落后信息 rs.printSlaveReplicationInfo() 查看slave狀態 通過"db.printSlaveReplicationInfo()"可以查看slave的同步狀態 副本節點中執行db.printSlaveReplicationInfo()命令可以查看同步狀態信息 source——從庫的IP及端口 syncedTo——當前的同步情況,延遲了多久等信息

      bertram:PRIMARY> use local; switched to db local bertram:PRIMARY> show tables; me oplog.rs replset.election replset.minvalid startup_log system.profile system.replset local庫下面的me集合保存了服務器名稱 local庫下面的replset.minvalid集合保存了數據庫最新操作的時間戳 local庫下面的startup_log集合記錄這mongod每一次的啟動信息 local庫下面的system.indexes集合記錄當前庫的所有索引信息 local庫下面的system.replset記錄著復制集的成員配置信息rs.conf()讀取這個集合 local庫下面的oplog.rs集合記錄著所有操作,MongoDB就是通過oplog.rs來實現數據同步的。當Primary節點插入一條數據后,oplog.rs集合中就會多一條記錄 bertram:PRIMARY> db.oplog.rs.findOne(); { "ts" : Timestamp(1465879171, 238), "h" : NumberLong("-2275413922284641862"), "v" : 2, "op" : "u", "ns" : "MyDB.SyncTable", "o2" : { "_id" : "bbf80260-3d58-49f1-9c8c-e093d5d57527" }, "o" : { "_id" : "bbf80260-3d58-49f1-9c8c-e093d5d57527", "EntityId" : "362569", "TypeName" : "Product", "Times" : 14208, "CreateTime" : ISODate("2014-11-15T14:35:51.916Z"), "LastModified" : ISODate("2016-06-14T04:38:21.708Z"), "LastOperationTime" : ISODate("2016-06-14T04:39:30.957Z") } } 字段含義 ts:8字節的 時間戳,由4字節unix timestamp + 4字節自增計數表示。在選舉(如master宕機時)新primary時,會選擇ts最大的那個secondary作為新primary。 op:1字節的操作類型,例如i表示insert,d表示delete。 ns:操作所在的namespace。 o:操作所對應的document,即當前操作的內容(比如更新操作時要更新的的字段和值) o2: 在執行更新操作時的條件,僅限于update時才有該屬性。 其中op,可以是如下幾種情形之一: "i": insert "u": update "d": delete "c": db cmd "db":聲明當前數據庫 (其中ns 被設置成為=>數據庫名稱+ '.') "n": no op,即空操作,其會定期執行以確保時效性。修改配置,會產生 "n" 操作

      同步過程

      大致流程:

      檢查配置、初始化local庫的各個集合、轉換各個成員的狀態(STARTUP -> STARTUP2 -> RECOVERING -> SECONDARY)、10秒后開始選舉(SECONDARY -> PRIMARY)

      初始化同步:

      復制除local數據庫外的所有數據庫,mongod掃描每個源數據庫中的每個集合,并將所有數據插入這些集合的自己的數據庫中

      版本3.4中更改:在為每個集合復制文檔時,初始同步將構建所有集合索引(先同步索引,再同步數據) 在早期版本中,在此階段僅構建_id索引(先同步數據,再同步索引)

      版本3.4中更改:初始同步在數據復制期間提取新添加的操作日志記錄。

      確保目標成員在local數據庫中具有足夠的磁盤空間,以在此數據復制階段持續時間臨時存儲這些操作日志記錄。

      mongod使用源中的操作日志,將所有更改應用于數據集。

      初始同步完成后,成員將從STARTUP2轉換為SECONDARY。

      初始化時,同步源的選擇取決于mongod啟動參數initialSyncSourceReadPreference的值(4.2.7中的新增功能)。

      如果無法選擇同步源,將記錄錯誤并等待1秒鐘,然后重新選擇,從mongod最多可以重新初始同步源選擇過程10次,然后錯誤退出。

      復制:多線程

      MongoDB使用多線程批量應用寫入操作以提高并發性。 MongoDB按文檔ID(WiredTiger)對批次進行分組,并同時使用不同的線程來應用每組操作,MongoDB始終以原始寫入順序對給定文檔應用寫入操作

      副本集的完整配置信息和狀態

      副本集的完整配置信息和狀態通過 rs.status & db.admincommand({replSetGetStatus : 1 }) 查看

      https://docs.mongodb.com/manual/reference/command/replSetGetStatus/#std-label-rs-status-output

      rs.status命令新增了一些可參考監控項,例如:

      replSetGetStatus.optimes.lastCommittedOpTime:已寫入大多數副本集成員的最新操作時間;

      replSetGetStatus.optimes.appliedOpTime:已應用于副本集的該成員的最新操作時間;

      replSetGetStatus.optimes.durableOpTime:已寫入該副本集的該成員的journal日志的時間

      MongoDB數據節點狀態編號

      狀態值

      狀態名

      狀態說明

      0

      STARTUP

      節點剛啟動未完成加載副本集,配置初期為該狀態

      1

      PRIMARY

      有投票權主節點狀態,唯一支持寫的節點。有投票資格

      2

      SECONDARY

      有投票權 副本節點狀態,可進行數據同步,擁有投票權

      3

      RECOVERING

      有投票權 特殊原因導致數據落后,節點自我檢查/修復,無法讀取數據

      5

      STARTUP2

      有投票權 節點加載完副本集配置,并已經運行初始同步

      6

      UNKNOWN

      無投票權 從副本集的另一個成員的角度來看,該成員的狀態尚不清楚

      7

      ARBITER

      有投票權 仲裁節點

      8

      DOWN

      無投票權 節從副本集的另一個成員的角度來看,該成員不可訪問。例網絡問題

      9

      ROLLBACK

      有投票權 執行回滾, 暫不能讀取數據,回滾后進入recovering狀態

      10

      REMOVED

      節點曾在副本集中, 但被移除

      非投票成員的屬性如

      { "_id" : , "host" : , "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 0 }

      rs.status() { "set" : "replset", "date" : ISODate("2019-12-04T04:49:18.693Z"), "myState" : 1, "term" : NumberLong(3), # 代表副本集成員數量 "syncingTo" : "", "syncSourceHost" : "", # 代表primary "syncSourceId" : -1, # 代表primary "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "optimes" : { "lastCommittedOpTime" : { #已寫入大多數副本集成員的最新操作時間 "ts" : Timestamp(1575434954, 1), "t" : NumberLong(3) }, "lastCommittedWallTime" : ISODate("2019-12-04T04:49:14.378Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1575434954, 1), "t" : NumberLong(3) }, "readConcernMajorityWallTime" : ISODate("2019-12-04T04:49:14.378Z"), "appliedOpTime" : { #已應用于副本集的該成員的最新操作時間 "ts" : Timestamp(1575434954, 1), "t" : NumberLong(3) }, "durableOpTime" : { #已寫入該副本集的該成員的journal日志的時間 "ts" : Timestamp(1575434954, 1), "t" : NumberLong(3) }, "members" : [ { "_id" : 0, "name" : "m1.example.net:27017", "ip" : "198.51.100.1", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 2019, "optime" : { "ts" : Timestamp(1575434954, 1), "t" : NumberLong(3) }, "optimeDate" : ISODate("2019-12-04T04:49:14Z"), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1575434944, 1), "electionDate" : ISODate("2019-12-04T04:49:04Z"), "configVersion" : 1, "self" : true, "lastHeartbeatMessage" : "" },

      3 選舉和投票機制

      選舉(election)與投票(Vote)機制, MongoDB primary發生異常時, 促使副本集自動修復, 從有投票權中的secondary節點挑選出最適合的節點來接替primary工作

      投票機制:大多數原則 (總節點數/2) +1 取整數; 例 5個節點的副本集,5/2+1=3; 至少得三票,最高可以容錯2臺機器down掉

      4 回滾機制

      Primary A寫操作未同步給secondary節點,網絡異常導致中斷, secondary選取新主primary B,原A 扔寫入數據 加入副本集后 成為secondary 這樣數據就有了差異,需要回滾

      回滾的前提

      在同步源上沒有查到比其更新的oplog(我們剛剛通過一系列麻煩的規則選出它作為同步源,但是我們的oplog卻比它還新)

      返回的的第一條oplog和其最新的oplog的OpTime和hash都不同,注意這里是比較整個OpTime,即除了時間戳之外還包括term,首先會比較term,如果term不同,那就不同

      大概流程: 首先找到B與A的共同操作點,A將共同操作點后的操作寫入 rollback目錄下的BSON文件文件, 并撤銷Oplog記錄, 然后繼續同步B節點數據

      BSON 文件格式:...bason

      回滾的限制

      4.0 之后版本,回滾數量無限制, 回滾時間默認24h (rollbackTimeLimitSecs)

      4.0 之前版本, 數量不能超過300M ?回滾時間不能超過30min

      5 數據讀寫策略

      5.1 寫入策略(write Concern)

      不同場景對應寫入策略不同,要求最終一致性(日志業務),要求很高的響應時間(支付業務)

      客戶端 使用write concern來配置,通過寫入響應(acknowledgement)層級,決定數據寫入何時返給客戶端

      Write concern 包含字段 {w: <值>, J: <布爾值>, wtimeout:<數字>}

      W字段 整數N 表示反饋完成操作必須同步到N個副本集上

      1 表只寫入主節點

      0 不需要寫入任何節點, 可能會出現未寫入成功但未收到報錯信息

      大于1 代表必須寫入大于1的節點數,不然會報錯 “not enough data-bearing nodes at….”

      Majority: 寫入大多數節點(半數+1 )

      J 字段 表示寫操作是否需要記錄到日志文件中(journal) 若寫入日志中,則服務意外時, 可通過日志恢復數據

      Wtimeout ?表示等待時間閾值,單位ms , 超過閾值代表寫入失敗

      db.collection.insert({name:”alex”},writeConcern:{w:1})? # 代表寫入主節點

      5.2 讀取策略

      類似寫入策略,可以配置讀取策略 Read Concern & Read Preference 非互斥, 可配合使用

      Read concern 的作用是讓客戶端指定什么樣的數據可以被讀取,如 數據寫入primary A 后,A異常,集群重新選B, 則A要回滾,這時A的數據是不可取的

      語法

      db.collection.find().readConcern()

      level參數配置如下

      local 從primary節點讀取時的默認值, 在未寫入大部分節點前就反數據(此做法會導致臟讀)

      available 從secondary讀取的默認值,在未寫入大部分節點前就反數據(此做法會導致臟讀)

      majority? 數據操作必須更新至大多數節點才能被讀取

      linearizable? 只允許在主節點讀取(readConcern(“majority”)配置時候 能保證讀到已經確認的數據且查詢結果為單個文檔生效)

      snapshot? 4.0 版本提供 多文檔事物中使用

      read Preference

      配置該參數,可以讓客戶端驅動知道從哪個節點去讀取數據,可以配置讀寫分離,就近讀取數據的負載均衡效果

      Mongo.setReadPref(,)

      Mode可設置

      Primary 主節點讀取

      PrimaryPreferred? 優先從主節點讀取,若主節點無法讀取, 從副節點讀取

      Secondary 從副節點讀取

      SecondaryPreferred 優先從副節點驅動,若無法讀取,從primary讀取

      Nearest 根據網絡情況從最近的節點讀取, 可搭配知道副本的tags限制讀取來源 db.collection.find().readPref(“nearest”,[‘source’:’rpt’])

      MongoDB 數據庫

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何把兩張照片弄一樣大小(怎樣弄兩張不一樣的照片和一張上)
      下一篇:Excel中使用鼠標滾輪的幾個技巧(excel鼠標滑輪上下滾動設置)
      相關文章
      亚洲人成网站观看在线播放| 亚洲AV午夜成人片| 亚洲码国产精品高潮在线| 亚洲一区二区三区乱码在线欧洲| 久久亚洲私人国产精品| 亚洲成人免费在线| 亚洲人成网77777色在线播放| 久久精品国产精品亚洲艾草网美妙| 亚洲高清国产拍精品青青草原| 国产精品久久久久久亚洲影视| 亚洲Aⅴ在线无码播放毛片一线天 亚洲avav天堂av在线网毛片 | 亚洲AV综合色区无码一二三区| 亚洲国产成a人v在线观看| 亚洲区精品久久一区二区三区| 亚洲福利视频一区二区三区| 亚洲精品视频在线观看免费| 亚洲成人黄色在线观看| 亚洲国产综合在线| 国产精品亚洲综合五月天| 亚洲色欲啪啪久久WWW综合网| 亚洲欧美日韩一区二区三区| 亚洲第一街区偷拍街拍| 99亚洲乱人伦aⅴ精品| 亚洲成A人片在线观看无码3D| 亚洲综合色在线观看亚洲| 亚洲一区二区三区无码中文字幕| 国产成人亚洲综合| 亚洲色中文字幕无码AV| 久久亚洲成a人片| 亚洲美女视频一区二区三区| 亚洲午夜久久久久久尤物| 亚洲人片在线观看天堂无码| 亚洲AV成人精品日韩一区| 亚洲一区二区三区无码影院| 在线精品亚洲一区二区三区| 亚洲AV无码乱码国产麻豆| 亚洲成av人片不卡无码| 亚洲国产日韩a在线播放| 亚洲国模精品一区| 久久夜色精品国产亚洲| 亚洲美女大bbbbbbbbb|