真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么深入mongodb集群副本集內部機制

怎么深入MongoDB集群副本集內部機制,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

10多年建站經驗, 網(wǎng)站設計制作、網(wǎng)站設計客戶的見證與正確選擇。成都創(chuàng)新互聯(lián)公司提供完善的營銷型網(wǎng)頁建站明細報價表。后期開發(fā)更加便捷高效,我們致力于追求更美、更快、更規(guī)范。

  • 副本集故障轉移,主節(jié)點是如何選舉的?能否手動干涉下架某一臺主節(jié)點。

  • 官方說副本集數(shù)量最好是奇數(shù),為什么?

  • mongodb副本集是如何同步的?如果同步不及時會出現(xiàn)什么情況?會不會出現(xiàn)不一致性?

  • mongodb的故障轉移會不會無故自動發(fā)生?什么條件會觸發(fā)?頻繁觸發(fā)可能會帶來系統(tǒng)負載加重?

Bully算法 mongodb副本集故障轉移功能得益于它的選舉機制。選舉機制采用了Bully算法,可以很方便從分布式節(jié)點中選出主節(jié)點。一個分布式集群架構中一般都有一個所謂的主節(jié)點,可以有很多用途,比如緩存機器節(jié)點元數(shù)據(jù),作為集群的訪問入口等等。主節(jié)點有就有吧,我們干嘛要什么Bully算法?要明白這個我們先看看這兩種架構:

  1. 指定主節(jié)點的架構,這種架構一般都會申明一個節(jié)點為主節(jié)點,其他節(jié)點都是從節(jié)點,如我們常用的MySQL就是這樣。但是這樣架構我們在第一節(jié)說了整個集群如果主節(jié)點掛掉了就得手工操作,上架一個新的主節(jié)點或者從從節(jié)點恢復數(shù)據(jù),不太靈活。

    怎么深入mongodb集群副本集內部機制

  2. 不指定主節(jié)點,集群中的任意節(jié)點都可以成為主節(jié)點。mongodb也就是采用這種架構,一但主節(jié)點掛了其他從節(jié)點自動接替變成主節(jié)點。如下圖:

    怎么深入mongodb集群副本集內部機制

好了,問題就在這個地方,既然所有節(jié)點都是一樣,一但主節(jié)點掛了,怎么選擇出來下一個節(jié)點是誰來做為主節(jié)點呢?這就是Bully算法解決的問題。

那什么是Bully算法,Bully算法是一種協(xié)調者(主節(jié)點)競選算法,主要思想是集群的每個成員都可以聲明它是主節(jié)點并通知其他節(jié)點。別的節(jié)點可以選擇接受這個聲稱或是拒絕并進入主節(jié)點競爭。被其他所有節(jié)點接受的節(jié)點才能成為主節(jié)點。節(jié)點按照一些屬性來判斷誰應該勝出。這個屬性可以是一個靜態(tài)ID,也可以是更新的度量像最近一次事務ID(最新的節(jié)點會勝出)。

選舉 那mongodb是怎進行選舉的呢?官方這么描述:

We use a consensus protocol to pick a primary. Exact details will be spared here but that basic process is:

  1. get maxLocalOpOrdinal from each server.

  2. if a majority of servers are not up (from this server’s POV), remain in Secondary mode and stop.

  3. if the last op time seems very old, stop and await human intervention.

  4. else, using a consensus protocol, pick the server with the highest maxLocalOpOrdinal as the Primary.

大致翻譯過來為使用一致協(xié)議選擇主節(jié)點?;静襟E為:

  1. 得到每個服務器節(jié)點的最后操作時間戳。每個mongodb都有oplog機制會記錄本機的操作,方便和主服務器進行對比數(shù)據(jù)是否同步還可以用于錯誤恢復。

  2. 如果集群中大部分服務器down機了,保留活著的節(jié)點都為 secondary狀態(tài)并停止,不選舉了。

  3. 如果集群中選舉出來的主節(jié)點或者所有從節(jié)點最后一次同步時間看起來很舊了,停止選舉等待人來操作。

  4. 如果上面都沒有問題就選擇最后操作時間戳最新(保證數(shù)據(jù)是最新的)的服務器節(jié)點作為主節(jié)點。

這里提到了一個一致協(xié)議(其實就是bully算法),這個和數(shù)據(jù)庫的一致性協(xié)議還是有些區(qū)別,一致協(xié)議主要強調的是通過一些機制保證大家達成共識;而一致性協(xié)議強調的是操作的順序一致性,比如同時讀寫一個數(shù)據(jù)會不會出現(xiàn)臟數(shù)據(jù)。一致協(xié)議在分布式里有一個經典的算法叫“Paxos算法”,后續(xù)再介紹。

上面有個問題,就是所有從節(jié)點的最后操作時間都是一樣怎么辦?就是誰先成為主節(jié)點的時間最快就選誰。

選舉觸發(fā)條件 選舉不是什么時刻都會被觸發(fā)的,有以下情況可以觸發(fā)。

  1. 初始化一個副本集時。

  2. 副本集和主節(jié)點斷開連接,可能是網(wǎng)絡問題。

  3. 主節(jié)點掛掉。

選舉還有個前提條件,參與選舉的節(jié)點數(shù)量必須大于副本集總節(jié)點數(shù)量的一半,如果已經小于一半了所有節(jié)點保持只讀狀態(tài)。
日志將會出現(xiàn):

can't see a majority of the set, relinquishing primary

主節(jié)點掛掉能否人為干預?答案是肯定的。

  1. 可以通過replSetStepDown命令下架主節(jié)點。這個命令可以登錄主節(jié)點使用

    db.adminCommand({replSetStepDown : 1})

    如果殺不掉可以使用強制開關

    db.adminCommand({replSetStepDown : 1, force : true})

    或者使用 rs.stepDown(120)也可以達到同樣的效果,中間的數(shù)字指不能在停止服務這段時間成為主節(jié)點,單位為秒。

  2. 設置一個從節(jié)點有比主節(jié)點有更高的優(yōu)先級。
    先查看當前集群中優(yōu)先級,通過rs.conf()命令,默認優(yōu)先級為1是不顯示的,這里標示出來。

    rs.conf();

    {
            "_id" : "rs0",
            "version" : 9,
            "members" : [
                    {
                            "_id" : 0,
                            "host" : "192.168.1.136:27017"                },
                    {
                            "_id" : 1,
                            "host" : "192.168.1.137:27017"                },
                    {
                            "_id" : 2,
                            "host" : "192.168.1.138:27017"                }
            ]
            }

    我們來設置,讓id為1的主機可以優(yōu)先成為主節(jié)點。

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

    然后再執(zhí)行rs.conf()命令查看優(yōu)先級已經設置成功,主節(jié)點選舉也會觸發(fā)。

    {
            "_id" : "rs0",
            "version" : 9,
            "members" : [
                    {
                            "_id" : 0,
                            "host" : "192.168.1.136:27017"                },
                    {
                            "_id" : 1,
                            "host" : "192.168.1.137:27017",
                            "priority" : 2
                    },
                    {
                            "_id" : 2,
                            "host" : "192.168.1.138:27017"                }
              ]
             }

    如果不想讓一個從節(jié)點成為主節(jié)點可以怎么操作?
    a、使用rs.freeze(120)凍結指定的秒數(shù)不能選舉成為主節(jié)點。
    b、按照上一篇設置節(jié)點為Non-Voting類型。

  3. 當主節(jié)點不能和大部分從節(jié)點通訊。把主機節(jié)點網(wǎng)線拔掉,嘿嘿:)

    優(yōu)先級還可以這么用,如果我們不想設置什么hidden節(jié)點,就用secondary類型作為備份節(jié)點也不想讓他成為主節(jié)點怎么辦?看下圖,共三個節(jié)點分布在兩個數(shù)據(jù)中心,數(shù)據(jù)中心2的節(jié)點設置優(yōu)先級為0不能成為主節(jié)點,但是可以參與選舉、數(shù)據(jù)復制。架構還是很靈活吧!

    怎么深入mongodb集群副本集內部機制

奇數(shù) 官方推薦副本集的成員數(shù)量為奇數(shù),最多12個副本集節(jié)點,最多7個節(jié)點參與選舉。最多12個副本集節(jié)點是因為沒必要一份數(shù)據(jù)復制那么多份,備份太多反而增加了網(wǎng)絡負載和拖慢了集群性能;而最多7個節(jié)點參與選舉是因為內部選舉機制節(jié)點數(shù)量太多就會導致1分鐘內還選不出主節(jié)點,凡事只要適當就好。這個“12”、“7”數(shù)字還好,通過他們官方經過性能測試定義出來可以理解。具體還有哪些限制參考官方文檔《 MongoDB Limits and Thresholds 》。 但是這里一直沒搞懂整個集群為什么要奇數(shù),通過測試集群的數(shù)量為偶數(shù)也是可以運行的,參考這個文章http://www.itpub.net/thread-1740982-1-1.html。后來突然看了一篇stackoverflow的文章終于頓悟了,mongodb本身設計的就是一個可以跨IDC的分布式數(shù)據(jù)庫,所以我們應該把它放到大的環(huán)境來看。

假設四個節(jié)點被分成兩個IDC,每個IDC各兩臺機器,如下圖。但這樣就出現(xiàn)了個問題,如果兩個IDC網(wǎng)絡斷掉,這在廣域網(wǎng)上很容易出現(xiàn)的問題,在上面選舉中提到只要主節(jié)點和集群中大部分節(jié)點斷開鏈接就會開始一輪新的選舉操作,不過mongodb副本集兩邊都只有兩個節(jié)點,但是選舉要求參與的節(jié)點數(shù)量必須大于一半,這樣所有集群節(jié)點都沒辦法參與選舉,只會處于只讀狀態(tài)。但是如果是奇數(shù)節(jié)點就不會出現(xiàn)這個問題,假設3個節(jié)點,只要有2個節(jié)點活著就可以選舉,5個中的3個,7個中的4個。。。

怎么深入mongodb集群副本集內部機制

心跳 綜上所述,整個集群需要保持一定的通信才能知道哪些節(jié)點活著哪些節(jié)點掛掉。mongodb節(jié)點會向副本集中的其他節(jié)點每兩秒就會發(fā)送一次pings包,如果其他節(jié)點在10秒鐘之內沒有返回就標示為不能訪問。每個節(jié)點內部都會維護一個狀態(tài)映射表,表明當前每個節(jié)點是什么角色、日志時間戳等關鍵信息。如果是主節(jié)點,除了維護映射表外還需要檢查自己能否和集群中內大部分節(jié)點通訊,如果不能則把自己降級為secondary只讀節(jié)點。

同步,副本集同步分為初始化同步和keep復制。初始化同步指全量從主節(jié)點同步數(shù)據(jù),如果主節(jié)點數(shù)據(jù)量比較大同步時間會比較長。而keep復制指初始化同步過后,節(jié)點之間的實時同步一般是增量同步。初始化同步不只是在第一次才會被處罰,有以下兩種情況會觸發(fā):

  1. secondary第一次加入,這個是肯定的。

  2. secondary落后的數(shù)據(jù)量超過了oplog的大小,這樣也會被全量復制。

那什么是oplog的大?。壳懊嬲f過oplog保存了數(shù)據(jù)的操作記錄,secondary復制oplog并把里面的操作在secondary執(zhí)行一遍。但是oplog也是mongodb的一個集合,保存在local.oplog.rs里,但是這個oplog是一個capped collection也就是固定大小的集合,新數(shù)據(jù)加入超過集合的大小會覆蓋。所以這里需要注意,跨IDC的復制要設置合適的oplogSize,避免在生產環(huán)境經常產生全量復制。oplogSize 可以通過–oplogSize設置大小,對于linux 和windows 64位,oplog size默認為剩余磁盤空間的5%。

同步也并非只能從主節(jié)點同步,假設集群中3個節(jié)點,節(jié)點1是主節(jié)點在IDC1,節(jié)點2、節(jié)點3在IDC2,初始化節(jié)點2、節(jié)點3會從節(jié)點1同步數(shù)據(jù)。后面節(jié)點2、節(jié)點3會使用就近原則從當前IDC的副本集中進行復制,只要有一個節(jié)點從IDC1的節(jié)點1復制數(shù)據(jù)。

設置同步還要注意以下幾點:

  1. secondary不會從delayed和hidden成員上復制數(shù)據(jù)。

  2. 只要是需要同步,兩個成員的buildindexes必須要相同無論是否是true和false。buildindexes主要用來設置是否這個節(jié)點的數(shù)據(jù)用于查詢,默認為true。

  3. 如果同步操作30秒都沒有反應,則會重新選擇一個節(jié)點進行同步。

到此,本章前面提到的問題全部解決了,不得不說mongodb的設計還真是強大!

后續(xù)繼續(xù)解決上一節(jié)這幾個問題:

  • 主節(jié)點掛了能否自動切換連接?目前需要手工切換。

  • 主節(jié)點的讀寫壓力過大如何解決?

還有這兩個問題后續(xù)解決:

  • 從節(jié)點每個上面的數(shù)據(jù)都是對數(shù)據(jù)庫全量拷貝,從節(jié)點壓力會不會過大?

  • 數(shù)據(jù)壓力大到機器支撐不了的時候能否做到自動擴展?

關于怎么深入mongodb集群副本集內部機制問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關知識。


文章標題:怎么深入mongodb集群副本集內部機制
URL標題:http://weahome.cn/article/gghisc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部