往期分享
RDS MySQL
RDS PostgreSQL
RDS SQL Server
Redis
MongoDB
概述
阿里雲數據庫MongoDB的IOPS使用率是一個非常重要的監控指標,IOPS使用率達到或接近100%後容易引起業務響應緩慢,甚至導致業務不可用的情形。一般雲數據庫廠商為了避免宿主機出現IO爭搶,會使用Cgroup等技術進行實例間的IO隔離和IOPS限制,即不同規格的實例配置對應不同的IOPS使用上限。
本文將由淺入深幫您查看、分析和優化雲數據庫MongoDB的IOPS使用率。
查看IOPS使用
監控圖查看
首先需要確認該實例的最大IOPS上限,通過點擊"基本信息"可以查看,如下圖:
不同實例規格對應的IOPS使用上限參考:
https://help.aliyun.com/document_detail/57141.html
通過點擊"監控信息"可以查看到當前的IOPS使用量,因為絕大部分情況下阿里雲數據庫MongoDB的data目錄和log目錄使用同一塊盤,所以IOPS使用量=data_iops=log_iops。
命令行查看
在監控圖展示上,目前阿里雲MongoDB僅限制IOPS,也僅展示IOPS的相關信息。在實際的IO問題中,我們同樣可能需要關注IO吞吐量,IO延遲情況,通過db.serverStatus().systemInfo命令可以查看IO相關的其他指標監控,不過所有監控項都是自MongoDB啟動以來的累加值,並不建議直接查看。
如果用戶有自行開發更為詳細的MongoDB性能指標,可以基於上述命令的累加數值獲取更多的MongoDB IO指標。
MongoDB 磁盤IO問題常見原因和優化策略
對於雲數據庫MongoDB來說,底層的磁盤硬件性能對用戶透明,完全交由雲廠商負責,用戶只需要核心關注業務的正確使用MongoDB,以及配置合適的內存和IOPS上限。
通常來說,MongoDB的IO問題與內存的CacheSize大小息息相關。CacheSize越大,表示能夠緩存的熱數據越大,那麼系統需要的磁盤IO量也就越低,出現IO瓶頸的概率越低;反之,CacheSize越小,表示能否緩存的熱數據越少,系統刷髒也更頻繁,實例出現IO壓力的概率也就越大。
您可以通過mongostat或者阿里雲數據庫自治服務DAS實時查看當前的cache dirty,目前阿里雲數據庫MongoDB暫不支持cache dirty歷史情況查看。如果出現 dirty>20%,並一直持續,說明內存淘汰壓力很大,用戶的請求線程會阻塞參與page淘汰,請求延時就會增加,這時可以考慮"擴大內存"或者"擴大IOPS"。
更多mongostat的使用方式可以參考:https://docs.mongodb.com/v4.2/reference/program/mongostat/
還有一些與磁盤IO相關的參數和配置,比如MongoDB Journal和運行日誌刷盤,WriteConcern設置,分片集群的MoveChunk等,這些因素我們建議用戶根據實際業務需求情況設置即可,一般來說,不必為了儘可能地提高IO能力刻意修改。
關於更多Journal內容可參考:https://docs.mongodb.com/manual/core/journaling/
關於更多WriteConcern內容可參考:https://docs.mongodb.com/manual/reference/write-concern/
對於阿里雲MongoDB來說,我們更推薦配置好合適的實例規格的同時,重點關注Index的優化和部分應用系統的寫入優化。
如何配置合適的實例規格
一般很難事先預估熱數據與CacheSize的比例設置為多少最合適,這是性能與實例費用的一個折衷。通用經驗下,我們建議在MongoDB實例在日常態運行過程中滿足業務RT要求的情況下,保證每日的峰值CPU使用率和IOPS使用率控制在50%以內。
Index優化
SQL全表掃描或者使用了不恰當的Index,比如導出全表數據期間,消耗的IO必然很大。另一方面,過多累贅的Index創建也會產生更多的數據規模,導致WiredTiger Cache只能緩存更小的熱數據,業務數據寫操作過程中也同樣多一次IO操作去更新Index,從而影響IO性能。
所以在避免濫用Index的情況下,需要為每個Query創建最合適的Index,關於這部分內容,可以參考:https://docs.mongodb.com/manual/indexes/
業務架構和運維優化
在業務架構層面,要避免磁盤IO成為瓶頸,主要從以下幾個方面入手:
控制併發寫入/讀取線程數
MongoDB是多線程應用,但是我們並不推薦"極致壓榨"MongoDB實例本身的性能,過高的併發寫入速度和複雜查詢併發數,容易引起IOPS瓶頸,甚至導致Secondary節點持續延遲。具體的MongoDB IO壓力可以參考上文提到的mongostat中的dirty數值。
如果業務寫入量就是大到超出單機瓶頸,建議升級至MongoDB分片集群模式,通過數據的水平拆分來線性擴容MongoDB的寫入性能。
儘可能避免峰值寫入
部分業務,比如日誌系統的定期寫入或者遊戲系統中用戶信息的批量持久化,容易造成一個一個IOPS峰值。針對這種情況,在當前的實例配置不足以支撐如此峰值寫入的情況下,我們建議業務側改造為平滑寫入,比如給每一個批量寫入操作添加一個隨機時間片。
避免業務高峰期間做運維操作
一些對性能影響較大的運維操作本質上也是認為造成了IOPS峰值,在無法避免的情況下,應該儘可能避免在業務高峰期執行。常見的容易引起IO高峰的運維操作有批量寫入/更新/刪除數據,添加Index,對集合執行Compact操作,批量導出數據等。