你的資料庫有87%機率超過用量

87%真的不能再高了!

古哥
pgsql-tw
6 min readMay 23, 2020

--

資料庫系統是大量使用磁碟空間的服務。很困擾的是,我們總是在資料庫磁碟已經爆炸後,才開始雞飛狗跳。難道不能事先估計嗎?我推薦使用簡易的統計方式協助你有所本地評估用量。當然,如果你有水晶球的話,也許會是更好的解決方案 😅

這篇的方法,程式設計師、資料庫管理者、決策主管都可以使用,統計函數在 MS Excel、LibreOffice Calc、Google Spreadsheet 都有,沒有藉口說你沒辦法評估。

87%

這個數字當然是湊的,實際上我的經驗通常會抓 80% 開始做一些系統或行政上的措施。

為什麼你應該評估磁碟用量

  1. 磁碟空間很不容易彈性調整,也很難像 CPU 或 RAM 一樣做積極的Overcommit。
  2. 磁碟空間很貴!如果你是管理階層,請一定要把空間當錢看!
  3. 如果因為磁碟用盡,造成資料不一致,損失的商業價值比怪罪系統人員更嚴重。
  4. 依據不同評估結果,客觀地制定管理政策,明確區分責任承擔。

平均數、標準差、相關係數、常態分配

直接破題,我們只要善用這幾個結果,就可以輕易評估,而它的假設是常態分配。如果你覺得你的應用很不常態,請勿無腦使用。而這幾個數字, Excel 中就有直接可以計算的函數,所以你只需要自學怎麼使用即可。

機率密度函數

需要使用的函數:AVERAGE, STDDEV, CORREL, NORMDIST

你可以嘗試使用其他的統計分析方法及模型,或許會準一些,但計算工具可能沒有這麼單純。而且磁碟空間的評估通常容許誤差會抓比較大,更準不一定有作業決策上的意義。

最重要的觀念是,你的記錄要找到和決策的相關性,另一方面,你的決策點是依觀測統計結果設定的。

本文假定的決策情境:

  1. 擴增空間的行政流程要 7 天,我今天開始跑流程來得及嗎?
  2. 如果我今天沒進行空間回收或擴增,明天爆掉的機率有多少?

實驗

實驗還是用 pgbench 來做吧。和資料庫架構無關,我只是需要一些看起來真實的數字而已。只是方便想先嘗試的人有一致的參考操作罷了。你完全可以直接套用在你的資料庫設計上。

事實上,要以紙上談兵算容量是不切實際的。最準備也最實際的作法就是觀察你的資料庫,由小至大,持續的收集統計數據,如同這個實驗做的一樣。

我建立了一個資料庫 pgbench,以使用者 pgbench 來操作:

剛建好資料庫是沒有資料,但還是有基本開銷,就以 pg_database_size 的結果為準記錄下來。接下來就以不同的 scale 來取得樣本。我已經事先假設業務邏輯是很清楚的,scale 成長的情況是磁碟用量最關鍵的指標。

雖然各種應用會有不同的成長模型,但資料庫的資料是一種累積性的內容,一般只會越用越大,或是到某個程度就持平。而在未來資料量的評估上,就會使用近期資料量的斜率,作為短期估計的成長率,然後不斷依新增的觀測值調整評估。一般情況是每日定時記錄使用空間。在此次實驗我額外加入了日期,其間故意進行了很多次交易增加資料量。

依空間使用關係預測

根據實驗結果,依 Scale 和 Size 計算相關係數 COLREL,不意外高達 0.9995,而日期和 Size 的相關係數則為 0.9853。這個例子有很明顯的成長關連度。所以如果要估計空間是否足夠,決策上要判斷的就是「 Scale 還會成長嗎?」並且,就算 Scale 沒有成長,資料也會隨日期增長。

如果想要注意空間臨界值是 1,600 MB,那麼依 Scale 和容量的比例來計算,Scale 約 106 時會到達 1,600 MB;而如果以日期計算的話,以全年估計是 4 天後超過,但近 10 日的話則是 6 天後會達標。通常會以近期記錄為主。

以決策而言,如果你的擴增資源的行政流程需要 7 日,那麼你現在已經來不及申請,等著它爆炸了。

那如果你很好心又大方分配了 100GB 給這個資料庫,太好了!照這個用法,我們可以撐超過 40 年呢,有錢就是任性。

依每日變化預測

那如果改以機率來看呢?問題會變成是:
「明天空間使用量突然達到 1,600 MB 的機率是多少?」(NORMDIST)

如果以近 10 日記錄值估計的話,發生機率為 0.007%。注意,這指的是一日之內爆衝到 1,600 MB 的機率。這通常用於例外情況偵測,因為發生機率極低,如果還是發生了,經驗上就是系統故障或程式錯誤。

回應一下標題,隔天 87% 會爆掉的機率,回推臨界值應該要落在 1,548MB。以這個設定看來已經爆 2 天了,可能放棄治療中。

機率用於估計每日變化量的範圍也有很好的效果,計算邏輯相同,就不贅述了。

其他

  1. 你也可以使用 df 或 du 取代 pg_database_size,如果你希望從作業系統層級來監控的話。在一致性監控不同服務系統用量時,會採用這個方式。
  2. 有一些暫存性質的資料庫,因為時常會清理資料,也可能不會越來越大,而是維持在某個範圍的區間,而那個「區間」就可以利用統計來得到更為清析的範圍。
  3. 不要過於密集去計算或記錄這些觀測數字,可能會造成數字的敏感度降低。以空間使用量而言,每日計量就可以了。原則上是和你想要估計的時間顆粒度相同。如果你統一每分鐘記錄資訊,但要估計每日機率,最好可以先把每天記錄合併為一筆資料,而不是直接計算每分鐘的記錄內容。
  4. 一定要先假設好你的決策要件,不要無腦收集數據!
  5. 你可以把統計結果另外儲存,然後就可以把原始資料刪除,我們只需要這幾個用來描述模型的參數就足夠了,儲存多種時間顆粒度的模型參數。也算是某種形式的壓縮資料。

數字永遠是中立的,如何用數字幫助決策更有效率,由你的智慧決定。

草率的範例放在 Google Spreadsheet:https://docs.google.com/spreadsheets/d/1qNz-4Lp8xwGp2VcDtoESlPREd5Y5gl3Gdp9iwWJB410/edit?usp=sharing

--

--

古哥
pgsql-tw

解決不了問題,就解決提出問題的人