有坑勿踩(一):MongoDB PSS vs PSA

前言

在技術社區混了這麼長時間,由於一些常見的技術問題反覆被問到,老是想寫寫文章把它們講清楚。無奈不少時候看似基礎的技術問題背後都隱藏着很深的緣由,想要一次性說清楚太花時間,而平時又沒有不少時間能花在上面(主要是懶),因此產生了寫一系列文章的想法,講講我或個人客戶使用MongoDB過程當中常常遇到的各類「坑」。話雖如此,難者不會會者不難,但願看了這些講解你就再也不認爲這些是「坑」了。code

在講解這些問題前,我會假設讀者已經對MongoDB有了最基礎的瞭解,所以一些基本名詞和概念就不作過多的解釋,請本身查閱相關資料。資源

PSS vs PSA

什麼是PSS/PSA?

在MongoDB複製集中,存在三種類型的角色:it

  • PRIMARY: 主節點(P)
  • SECONDARY: 從節點(S)
  • ARBITER: 仲裁節點(A)

構建一個複製集至少須要3個節點,因此用戶就有了兩種選擇,即PSS和PSA。
注意:記住A的做用始終是把集羣中具備投票權的節點總數湊成奇數用,防止「腦裂」。所以諸如PAA,PSSAA之類的配置是沒有存在的意義的,極端狀況下還會擾亂集羣的正常工做。io

PSA有什麼好處?

最直接的好處:省錢啊!隨便找臺機器,不消耗什麼資源就能夠運行一個A,比一個S的成本小多了。社區

PSA有什麼問題?

讀寫失效

最直接的問題來自於MongoDB中的一個配置選項{w: "majority"},這個配置決定了一次成功的寫入操做須要到達多少個節點纔算真正的成功,w能夠定義爲1,2,...n(n<=集羣節點總數)或majority。而majority是保證在集羣故障時不丟失數據的必要配置(關於majorityw之後再專門寫文章討論)。其表明的意義是:集羣中必須有大多數節點收到並確認了一個寫操做,這個寫操做纔算成功。
在三個節點的集羣中,{w: "majority"} == {w: 2}。所以若是集羣配置是PSA,因爲A是不存數據的,因此集羣中可以確認寫操做的節點只有P和S,恰好是2。到這裏可能有人已經看出問題了:在PSA中若是有一個數據節點宕機,則不再能知足{w: "majority"},全部使用這種配置的寫操做都會失敗。所以能夠說,PSA在必定程度上丟失了高可用性,由於任何一個數據節點的失效都會致使{w: "majority"}類型寫入的失敗。
引伸一下,ReadConcern一樣有可選值majority,所以一樣可能由於一個數據節點的失效而失效。集羣

集羣部分功能失效

可能你會以爲:什麼{w: "majority"}沒據說過啊,我也不在意丟失數據,那用PSA是否是就沒有問題了?固然不是!在不少你沒注意到的場景都存在着{w: "majority"}。好比:基礎

  1. 分片集羣數據遷移。不管源或者目標片中不可以知足大多數時,遷移都會失敗。
  2. 分片集羣管理。包括但不限於如下這些操做實際上都隱含着{w: "majority"}。一旦不能知足,這些操做都會失敗:配置

    1. db.dropDatabase()
    2. db.collection.drop()
    3. db.collection.dropIndex({...})
    4. sh.shardCollection(...)
    5. db.createUser(...)

結論

majority比你想象的更重要,PSA不可以提供足夠的可用數據節點來保證majority,所以在不少場景下會引起隱藏的錯誤。在有可能的狀況下,應儘可能使用PSS代替PSA。高可用

相關文章
相關標籤/搜索