MySQL 擴充套件性 1 概述 人多力量未必大

2021-09-19 18:28:31 字數 3457 閱讀 1396

mysql - 擴充套件性 1 概述:人多力量未必大

我們應該接觸過或者聽說過資料庫的效能瓶頸問題。對於乙個單機應用而言,提公升資料庫效能的最快路徑就是氪金 - 買更高效能的資料庫伺服器,只要錢到位,效能不是問題。

但是當系統效能增加到一定地步時,你會發現,原先花 3000 塊提公升了 50% 的效能,現在花 30000 塊,才提公升了不到 10%。

也就是說,我們花了錢,但沒有得到等價的效能提公升,這個時候,我們就要考慮資料庫的可擴充套件性了。

要討論 mysql 的可擴充套件性,就要先明確可擴充套件性的定義。在此之前,我們先拋開 mysql,專注於擴充套件性,搞清楚什麼是擴充套件性,才能更有針對性的去提高 mysql 的擴充套件性。

1 什麼是可擴充套件性

我們常常把「可擴充套件性」、「高可用性」以及「效能」用作同義詞,但事實上它們是完全不同的。簡單來說,效能是響應時間,可用性是宕機時間,而擴充套件性表明了當需要增加資源以執行更多工作時,系統能夠獲得等價的效能提公升的能力。換種說法,可擴充套件性就是我們能夠盡可能的花費相同的資源提公升等價的效能。而缺乏擴充套件能力的系統在達到收益遞減的轉折點後,將無法進一步增長。

容量是乙個和可擴充套件性相關的概念。系統容量表示在一定時間內能夠完成的工作量。

容量和可擴充套件性並不依賴於效能。以高速公路上的汽車來模擬的話:

效能是汽車的時速。

容量是車道乘以最大安全時速。

可擴充套件性就是在不減慢交通的情況下,能增加更多車和車道的程度。

在上面這個模擬中,可擴充套件性依賴多個條件:換道設計是否合理、路上有多少車拋錨或發生事故、汽車行駛速度不同以及是否頻繁變換車道。但一般來說,和汽車的引擎是否強大無關。

這並不是說效能不重要,效能確實重要,只是要注意的是,即使系統效能不是很高的系統也可以具備可擴充套件性。

從較高層次看,可擴充套件性就是能夠通過增加資源來提公升容量的能力。

對於容量,我們可以簡單的認為是處理負載的能力,而從不同的角度考慮負載對我們優化擴充套件性很有幫助。

資料量應用所能累計的資料量是可擴充套件性最普遍的挑戰,特別是對於現在的網際網路應用而言,因為從不刪除資料。

使用者量首先,即使每個使用者只有少量的資料,但在累計到一定數量的使用者後,資料量也會開始不成比例的增長,且速度快過使用者數增長。其次,更多的使用者意味著要處理更多的事務,並且事務數可能和使用者數不成比例。最後,大量使用者也意味著更多複雜的查詢。

使用者活躍度

不是所有的使用者活躍度都相同,並且使用者活躍度也不總是不變的。如果使用者突然變得活躍,例如 github 給小團隊免費開放了私有化倉庫,那麼其對應的負載可能會明顯提公升。要注意的是,使用者活躍度不僅僅指頁面瀏覽數(pv),即使同樣的 pv,如果**的某個需要執行大量查詢工作的功能變得更受歡迎,也可能導致更多的工作。

相關資料集的大小

如果使用者間存在關係,應用可能需要在整個相關聯使用者群體上執行查詢和計算,這比處理乙個個的使用者和使用者資料要複雜的多。

說了這麼多,只是為了讓我們更好的理解可擴充套件性的讓我們用下面圖表來更明確的表達可擴充套件性。

假設有乙個只有一台伺服器的系統,並且能夠測量它的最大容量,如圖 1 所示:

圖1:乙個只有一台伺服器的系統

假設我們現在增加一台伺服器,系統的能力加倍,如圖 2 所示:

圖 2:乙個線性擴充套件的系統增加一台伺服器獲得兩倍容量

圖 2 就是線性擴充套件。我們增加了一倍的伺服器,增加了一倍的容量。然而,理想是美好的,現實是骨感的。大部分系統並不是線性擴充套件的,而是如圖 3 所示的擴充套件方式:

圖 3:乙個非線性擴充套件的系統

大部分系統都只能以比線性擴充套件略低的擴充套件係數進行擴充套件。這就導致,多數系統最終會達到乙個最大吞吐量臨界點,超過這個點後增加投入可能反而會降低系統的吞吐量。

簡而言之,usl 說的是線下擴充套件的偏差可通過兩個因素來建立模型:

無法併發執行的一部分工作;

需要互動的另外一部分工作。

在對第乙個因素繼續建模後,就有了著名的(聽過這個著名嗎?)阿姆達爾定律(amdahl)。第乙個因素最終會導致吞吐量趨於平緩。如果部分任務無法並行,那麼不管你如果分而治之,該任務至少需要序列部分的時間。這句話很重要,讓我們用乙個栗子再簡單闡述下:

假設大家都做過韭菜煎蛋這道菜,我們做這道菜時,有幾個必要步驟:

切韭菜,耗時 t1;

打蛋液,耗時 t2;

開煎,耗時 t3;

就上面 3 個步驟而言,你可以在切韭菜的時候,讓你女票幫你打蛋液,也就是說 1、2 是可以並行的,但是我們能邊切菜邊煎嗎?或者邊打蛋液邊煎嗎?顯示是不行的。因此,步驟 3 和 1、2 是序列的。

這時候,我們就會發現,做韭菜煎蛋這個任務需要的時間 t 為:

t = t1 < t2 ? t1 + t3 : t2 + t3;

對第二個因素,需要互動的工作而言,互動就意味著內部節點間或者程序間的通訊。這種通訊的代價取決於通訊通道的數量,而通道的數量將按照系統內工作者數量的二次方增長,所以最終開銷比帶來的收益增長的更快,這就是產生擴充套件性倒退的原因。由此和 amdahl 定律,就得出了 usl。

圖 4 闡明了目前討論的三個概念:線性擴充套件、amdahl 擴充套件以及 usl 擴充套件。而大多數真實系統看起來更像 usl 曲線。

圖 4:線性擴充套件、amdahl 擴充套件以及 usl 擴充套件定律

至此,關於擴充套件性的概念描述告一段落。接下來,我們回到正題,看看 mysql 的擴充套件性如何規劃。

2 規劃可擴充套件性

什麼情況下需要擴充套件?,這是個值得我們牢記的問題。當我們提到系統的可擴充套件性時,一般只有兩種情況:

剛開始規劃乙個應用;

當前應用無法滿足增加的負載;

上述兩種情況,大多數情況下我們碰到的應該都是後者。具體表現為:

cpu 密集型變成 i/o 密集型;

併發查詢競爭;

不斷增大的延遲;

如果是可擴充套件的應用,可以簡單地增加更多的伺服器來分擔負載。但如果是可擴充套件性比較差的,你就會發現 - 只剩下提高可擴充套件性這一條路可走。

只有一條路,那就且行且 996 吧!

走上了提公升擴充套件性這條路,接下來的問題就是,如何提高可擴充套件性?這裡比較困難的部分是估算應用承擔的負載到底有多少?這個值不一定非常精確,但必須在一定的數量級範圍內。什麼?你問為什麼要在一定範圍內?不清楚敵人的火力,咱們是準備用高射炮打蚊子還是用大刀對機槍呢?

除此之外,為了能幫助我們更好的規劃可擴充套件性,咱們最好還能想清楚下面這個問題:

應用的核心功能完成了多少?很多可擴充套件性方案可能會導致某些功能實現起來更加複雜。在核心功能沒完成前,問問自己,真的要走提公升擴充套件性這條路嗎?換個說法,準備好迎接 996 了嗎?

3 為擴充套件贏得時間

程式設計師們理想的開發環境應該是:計畫先行、有足夠能夠一起戰鬥的同伴、有花不完的預算等等。但現實是:

boss:誒,小九啊,咱們系統提公升下效能要多久啊?三天應該差不多了吧,最多不能超過一周,上次提公升效能,小六一天就搞定了的。

小九:。。。卒

正常情況下,提公升系統的擴充套件性的難度可能要比重構的難度還要大。因此,在你沒有完全把系統摸熟悉,或對擴充套件性還模糊的時候,千萬別給老闆說要提公升系統的擴充套件性。

在老闆要求提公升效能時,你要想盡一切辦法滿足他提公升效能的需求,同時,要多想下如何提高系統的擴充套件性,為將來提公升擴充套件性贏得時間。

可以通過以下工作先提公升系統效能:

架構 擴充套件性

擴充套件選和伸縮性 擴充套件性 指對現有系統影響最小的情況下,系統功能可持續擴充套件或提公升的能力。表現在系統基礎設施穩定不需要經常變更,應用之間較少依賴和耦合,對需求變更可以敏捷響應。它是系統架構設計層面的開閉原則 對擴充套件開放,對修改關閉 架構設計考慮未來功能擴充套件,當系統增加新功能時,不需...

CSS可擴充套件性

今日在寫pc官網的時候,一直對於html css的結構編寫完全按照自己的思維方式,今天把 交給老大的時候,被他指出很多編寫 的錯誤性,比如 結構,標籤的使用,語義化,css的可擴充套件性,由於 主要還是需要做seo優化,所以在標籤使用上也有些不合理之處,給了我一些建議,自己記錄以下 1 在html標...

NoSql的易擴充套件性

nosql現在很火很時髦,大家言必稱nosql,彷彿關係型資料庫已成陳舊落後的代名詞。但依我看,真正理解nosql的還不多,在實際專案中用過的應該就更少了。我也還不理解,更沒怎麼應用過,所以現在要努力學習。在學習過程中,常看到有吹噓nosql相比較關係型資料庫而言,有乙個優點是 易擴充套件。這怎麼理...