對 Oplog 不熟的朋友,建議先閱讀之前的內容
- 2021 iThome 鐵人賽 - DAY19 MongoDB Oplog 到底是什麼?
- 2021 iThome 鐵人賽 - DAY20 MongoDB Oplog 玩壞它
- 2021 iThome 鐵人賽 - DAY28 MongoDB Atlas 付費監控內容
四年一度的大型盛事終於結束,來回顧一下這個我們都知道,卻隱藏得很好的 MongoDB 殺手 - Oplog。
在流量真正進入之前,我們進行了多次的功能驗證、壓力測試,確保在各個環節都沒有問題,對於各個服務的狀態也甚是滿意。展開了 MongoDB Atlas 監控,正式迎接挑戰!
剛開始我們很明顯感受到流量帶來的壓力,各項數據都還是穩定、可預期的,這時候是第一個錯誤。
等到第二天、第三天,我們開始發現 Oplog 的 headroom 開始有降低趨勢,這部分根 Oplog GB/Per hour 是呈現相反的,畢竟量多了,自然餘裕就開始減少。
第一個錯誤是沒有仔細評估合理性,對於流量的增長,到底多少是合理的呢?這個在事情必須要充足的測試才有辦法進行推斷。
這個問題也衍伸出另一件事,就是全服務的壓力測試非常重要,在 pre-production 環境應該事先給予充足的壓力測試。
展開調查
我馬上在次一個環境展開調查,查看 oplog 這個 collection 裡面的資料分布,日後應該能夠寫個 script 進行分析哪類型的 數量 與 size 佔比,畢竟 oplog 數量與大小是影響抄寫速度的關鍵。
第二個錯誤發生在此,確認好哪些部分可以降低觸發頻率以減輕 oplog 負擔後,修改就一路上到 PROD 環境,再等待一兩天後,仍然不見顯著好轉跡象。最大原因在於次一個環境(我們是 UAT),客戶與使用者的操作行為與流量大不相同,因此這個分析不能完全反映真實情況。
礙於範圍大的查詢對 PROD 可能是一個潛在負擔,我們決議不這麼做。
在這個非常時刻,除非有嚴重錯誤,否則也不適合對流程上有大幅度的修改。既然程式面與分析都不是用,最後選擇了最快速的做法:升級機器與調整 Oplog size。
首先是調整 Oplog collection size,要說明一下這個做法就是用空間換取時間,因為 oplog 抄寫量完全趕不及產出量,因此時間拉長了還是會有空間不足的情況產生,不過這個改動很適合我們緊急止血,至少買到一些時間,撐過巨大衝擊的期間即可。
再來是升級 MongoDB 規格,使用 Atlas 的服務就是這麼方便,升級過程中幾乎是無痛執行,我們選定了一個離峰時刻執行,順便調整 oplog size,最後終於把 headroom 慢慢往上拉高,使得 oplog 不會空間不足。
Conclusion
- 開發期間,我們應該仔細檢驗 oplog 的大小與數量是否合理,而非只關注功能是否完成
- oplog 基礎的抄寫資訊大約是
0.8 kb
,再加上抄寫的資料內容可以估算出一個 document 大小 - 使用 Update 而非 Replace
- 儲存的資料結構是否可以更精簡
- 週期性執行的任務,確保在離峰時間執行,以免搶佔尖峰時間的資源
- TTL index 可以在特定期間移除,例如預期有兩週的尖峰時刻,那可以把那兩週的 TTL 資料預先延長到尖峰時刻之後,因為 DELETE 也是會產生 oplog。
- 商務流程上,能夠合併更新資料庫的,就應該從流程上或架構面著手,避免無謂的資料更新。例如要確保某一個資料有按時更新,即便沒內容我們也會去更新
Last Update Time
欄位。 - 預設 oplog collection size 就是 disk 的 5% 空間,這個是可以預先調大的,畢竟單獨修改這個項目會需要資料庫的重啟。
- 上線前給予系統面足夠大的壓力測試,且這個壓力測試要持續一段時間,這樣觀測 oplog headroom 才夠精準。
- 透過壓力測試
再度
分析 oplog 大小與數量是否符合預期 - 花錢了,直接升級 Atlas,各項硬體規格的提升,直接使 oplog 抄寫更快。
oplog 的概念不難,但卻是非常容易被忽略的一個項目。
在我上面遇到的例子就是緊要關頭,能選擇的解決方案已經剩下升級,希望大家不要遇到XD