ApsaraDB for MongoDB執行個體的空間使用率是一個非常重要的監控指標。如果MongoDB執行個體的空間被完全使用,將會導致執行個體不可用。本文介紹查看MongoDB執行個體空間使用方式的方法,以及各種空間使用方式的原因和最佳化策略。
背景資訊
執行個體空間使用率達到80%以上時,可通過降低資料庫實際佔用空間或擴容儲存空間的方法避免空間佔滿的風險。
查看空間使用方式
複本集架構
當ApsaraDB for MongoDB執行個體為複本集架構時,您可以登入MongoDB管理主控台通過以下方法查看空間使用方式:
總體概覽
在基本資料頁面的規格資訊地區,查看當前執行個體的磁碟空間和使用率。
監控圖分析
在左側導覽列中單擊監控資訊,選擇目標節點,查看目標節點的磁碟空間使用量(Bytes)和磁碟空間使用率(%)。
ApsaraDB for MongoDB複本集執行個體提供一個可供讀寫訪問的Primary節點(主節點)、一個或多個提供高可用的Secondary節點(從節點)、一個隱藏的Hidden節點(隱藏節點)和一個或多個可選的ReadOnly節點(唯讀節點)。MongoDB節點的空間使用量由data_size和log_size組成,即ins_size=data_size+log_size。其中:
data_size:資料磁碟使用空間(不包括local庫),主要包括collection開頭的資料物理檔案、以索引開頭的索引物理檔案和部分中繼資料物理檔案,例如WiredTiger.wt。
log_size:local庫的物理大小、MongoDB作業記錄大小和部分審計日誌大小。
詳細分析
您可以通過以下兩種方法詳細分析空間使用問題:
通過MongoDB自身提供的命令
db.stats()和db.$collection_name.stats()分析。在頁面分析。
您可以在頁面查看以下配置資訊:
資料庫和表使用空間情況概覽、日均增長量和預測可用天數。
異常資料庫和表使用空間情況。
詳細業務表使用空間情況,包括索引檔案大小、資料檔案大小,壓縮率分析,平均行長等。
分區叢集架構
當ApsaraDB for MongoDB執行個體為分區叢集架構時,您可以登入MongoDB管理主控台通過以下方法查看空間使用方式:
監控圖分析
在監控資訊頁面,選擇目標節點,查看目標節點的磁碟空間使用量(Bytes)和磁碟空間使用率(%)。
詳細分析
通過ApsaraDB for MongoDB自身提供的命令
db.stats()和db.$collection_name.stats()依次分析各個節點的空間使用方式。
執行compact指令導致資料量過大
compact期間對執行個體的影響
由於compact執行的時間與集合的資料量相關,如果資料量過大,則會使compact的執行時間很長,所以為避免影響業務的讀寫,建議在業務低峰期執行compact。
compact方法
首先在備庫上執行命令db.runCommand({compact:"collectionName"}),然後進行主備切換,以減少compact期間對業務的影響。其中collectionName為集合名稱,請根據實際情況替換。
更多關於compact使用方法的介紹,請參見回收磁碟片段以提升磁碟利用率。
日誌過大導致空間上漲
Journal Log過大導致主備空間差距巨大
ApsaraDB for MongoDB 4.0以前的版本,如果宿主機的open files達到設定上限,則會使ApsaraDB for MongoDB內部的log server清理線程中斷,進而使Journal Log過大導致空間無限上漲,當通過ApsaraDB for MongoDB的作業記錄查看到類似以下內容時,您可以將核心版本升級到ApsaraDB for MongoDB 4.0以上,或者通過重啟雲資料庫mongod進程進行臨時解決,詳情請參見log-server thread exit quietly on error while the mongodb process still running。
2019-08-25T09:45:16.867+0800 I NETWORK [thread1] Listener: accept() returns -1 Too many open files in system
2019-08-25T09:45:17.000+0800 I - [ftdc] Assertion: 13538:couldn't open [/proc/55692/stat] Too many open files in system src/mongo/util/processinfo_linux.cpp 74
2019-08-25T09:45:17.002+0800 W FTDC [ftdc] Uncaught exception in 'Location13538: couldn't open [/proc/55692/stat] Too many open files in system' in full-time diagnostic data capture subsystem. Shutting down the full-time diagnostic data capture subsystem.備庫延遲和增量備份可能導致從節點日誌空間持續增長
ApsaraDB for MongoDB在出現主備延遲的情況下,Oplog可以使用的大小不再受限於設定檔定義的固定集合大小,理論上可以達到使用者申請磁碟容量的20%,但當備庫延遲恢複後,Oplog之前佔用的物理空間並不會回縮。
ApsaraDB for MongoDB使用物理備份的方式在隱藏節點備份ApsaraDB for MongoDB執行個體期間會有大量的checkpoint,進而導致佔用了更多的資料和日誌空間。
對於以上兩種情境,通過對Oplog單獨做compact操作解決,具體如下:
進行compact期間會阻塞所有的寫操作。
db.grantRolesToUser("root", [{db: "local", role: "dbAdmin"}])
use local
db.runCommand({ compact: "oplog.rs", force: true })選擇和使用分區不合理導致資料分布不均衡
sharding key類型選擇不合理
在一個分區叢集中,片鍵類型的選擇至關重要,一般會使用hash分區或者ranged分區兩種類型。通常情況下,在磁碟均衡度方面,hash分區的策略會比ranged好很多,因為根據不同的key值,ApsaraDB for MongoDB通過內部的雜湊函數可以使得資料均勻地分布在不同的分區上,而range分區一般是根據key的大小範圍進行資料分布,所以往往會造成這樣的一個現象:新插入的資料在一個熱點的chunk上,不但會引起該chunk所在的shard磁碟I/O過高,也會帶來短期資料不均勻的情境。
Sharding Key類型的介紹,詳情請參見sharding-shard-key、hashed-sharding和ranged-sharding。
sharding key欄位選擇不合理
各個分區上的chunk數量基本一致,但實際上絕大部分資料都只儲存在部分chunk上,導致這些熱點chunk所在的分區上的資料量遠遠大於其他分區上的資料量,執行命令sh.status()查看ApsaraDB for MongoDB的作業記錄,從日誌中可以查看到以下類似警示資訊:
2019-08-27T13:31:22.076+0800 W SHARDING [conn12681919] possible low cardinality key detected in superHotItemPool.haodanku_all - key is { batch: "201908260000" }
2019-08-27T13:31:22.076+0800 W SHARDING [conn12681919] possible low cardinality key detected in superHotItemPool.haodanku_all - key is { batch: "201908260200" }
2019-08-27T13:31:22.076+0800 W SHARDING [conn12681919] possible low cardinality key detected in superHotItemPool.haodanku_all - key is { batch: "201908260230" }mongos負載平衡主要考慮的是各個shard的chunk數量保持相當,就認為資料是均衡的,所以就會出現以上的極端情境:雖然各個shard數量相當,但實際資料嚴重傾斜。因為一個chunk內shardKey幾乎完全相同,但觸發到64MB的chunk分裂閾值,這時就會分裂出一個空的chunk。久而久之,雖然chunk的數量變多了並且完成了chunk的遷移,但實際上遷移走的chunk都是空的chunk,造成了chunk數量均衡但實際資料不均衡的情況。對於這種情況,需要在架構上重新設計,選擇合適的區分度較高的列作為sharding key。
spilt的介紹,詳情請參見sharding-data-partitioning和split-chunks-in-sharded-cluster。
部分資料庫未做分區
ApsaraDB for MongoDB分區叢集執行個體允許部分資料庫做分區,部分資料庫不做分區。那麼必然會帶來這樣一個問題:不做分區的資料庫的資料必然只能存在一個分區上,如果該資料庫的資料量很大,可能會造成該分區的資料量遠大於其他分區。
從一個源端mongos叢集匯入到一個新的mongos叢集,但邏輯匯入處理程序中忽略了在目標端mongos叢集做好分區設計的步驟。
針對上述問題,我們建議:
如果是因為目的地組群初始化匯入,匯入之前做好分區設計。
如果不做分區的庫很多且資料量基本相當,通過ApsaraDB for MongoDB提供的命令
movePrimary將指定資料庫遷移到指定分區。如果存在某個資料庫的資料量極大且未做分區,建議對其做分區設計或者將其拆分出來作為單一的複本集對待。
如果出現這種情況,但磁碟空間足夠大,建議忽略該問題。
大規模的movechunk操作可能引起分區的磁碟佔用不均
movechunk的本質是向目標端shard寫入資料後remove源端資料。預設情況下,remove操作不會釋放空間,因為對於wiredTiger引擎,每個表都有獨立的資料檔案和索引檔案,如果該檔案不刪除,總的磁碟空間就不可能回縮。通常最容易引起該問題的操作為:之前的sharding叢集中未做shard設計,運行一段時間後才做了Sharding。
從原理上說movechunk引起的空間片段和大規模刪除一樣,因此針對出現大量movechunk或者remove文檔的情況,可以對該分區進行compact操作來回收片段空間,正常情況下compact後資料會進行重組以回收檔案的片段空間。
movechunk的介紹,詳情請參見migrate-chunks-in-sharded-cluster和manage-sharded-cluster-balancer。