本文介紹ApsaraDB for MongoDB 8.0版本推出的新特性和最佳化項。
預覽
本文將從以下方面介紹ApsaraDB for MongoDB 8.0版本:
MongoDB 8.0 的更多新特性以及最佳化項,請參見MongoDB 8.0 release-notes。
升級版TCMalloc
MongoDB 8.0版本開始使用升級版的TCMalloc:
緩衝機制調整:升級版TCMalloc會使用每個CPU的緩衝(而不是每個線程的緩衝),以減少記憶體片段並使資料庫更能適應高壓力工作負載。
記憶體釋放機制:升級版TCMalloc使用時會在後台建立一個線程,每秒嘗試將記憶體釋放回作業系統。
tcmallocReleaseRate參數用於控制記憶體釋放的速率,單位為bytes/s(取值不再是之前版本1-10的模糊設定)。tcmallocReleaseRate參數在ApsaraDB for MongoDB中的預設值為10485760(即10MB。該參數值即使是0,也會釋放一定記憶體),您可以根據業務情況自訂調整。
複製效能最佳化
Majority寫
從MongoDB 8.0版本開始,writeConcern為majority時,MongoDB會在大多數複本集成員已經寫入了相關的oplog後就返回確認,而不是等待應用這個更改後才返回,此更改提高了majority模式下寫入的效能。
因此如果應用程式在收到majority寫確認後,立刻到Secondary節點上讀取資料,返回的結果可能不包含這次寫操作更改的內容。
Oplog緩衝區
Secondary節點會並行寫入和應用每個批次的oplog內容。當Writer線程從主節點讀取新的oplog條目並將其寫入本地oplog時,Applier線程會非同步將這些更改應用到本機資料庫。此更改提高了Secondary節點的複製輸送量。
因此,serverStatus下的相關指標也發生了變化,變成metrics.repl.buffer.write和metrics.repl.buffer.apply兩個緩衝區。
reshard效能最佳化
reshardCollection效能改進,您可以通過此命令改變集合的分區鍵並改變資料的分布。
MongoDB 8.0版本支援了forceRedistribution選項,允許使用和之前相同的分區鍵對集合進行重新分區,將資料重新分配到新的分區上。這個過程相比Chunk進行範圍遷移要快很多,還可以與zones選項搭配將資料移轉到特定地區。操作樣本如下:
db.adminCommand({
reshardCollection: "db.coll",
key: { shard_key: "hashed" },
forceRedistribution: true
})重新分區過程中若進行索引構建,可能導致索引構建失敗且無顯式報錯。您應避免在重新分區期間構建索引,或確保索引構建完成後再重新分區。
在追趕增量oplog階段時,如果預估剩餘操作時間在兩秒以內,源分區才會阻止此集合的寫入,等待目標分區追趕完成。但如果業務上可接受更長時間的阻塞,即停服或營運視窗,您可以使用commitReshardCollection命令提前對此集合進行禁寫操作,協助更快地完成重新分區。
分區
除reshard效能最佳化外,分區還有以下最佳化內容:
雜湊分區會預設為每個分區建立1個Chunk(MongoDB 8.0版之前是預設2個)。
dbhash命令可以直接在分區上運行。findAndModify和deleteOne命令可以使用部分Shard Key作為查詢條件。在一個已經分區的集合上使用
upsert為true的updateOne命令時,查詢條件中可以不包含所有的Shard Key。支援通過
unshardCollection命令或sh.unshardCollection()方法取消現有集合的分區,此操作會將集合中的所有文檔移動到指定的分區或資料量最少的分區上。支援通過
moveCollection命令將某一個未分區的集合移動到指定的分區上,不必約束於Primary Shard。但時間序列集合和可查詢密碼編譯集合不可移動,且可能會有2秒左右的集合寫入阻塞。提供了新的資料庫命令和mongosh協助函數:
命令
mongosh協助函數
說明
moveCollection
sh.moveCollection()
將一個未分區的集合移至某個Shard。
unshardCollection
sh.unshardCollection()
取消對現有分區集合的分區,並將集合資料移至某個Shard。
abortMoveCollection
sh.abortMoveCollection()
停止進行中的
moveCollection操作。abortUnshardCollection
sh.abortUnshardCollection()
停止進行中的
unshardCollection操作。無
sh.shardAndDistributeCollection()
對集合進行分區,並使用提供的分區鍵立即重新分配資料。
運行該協助函數與連續運行
shardCollection和reshardCollection的結果相同,目的是加快資料移動速度。
日誌記錄
慢日誌中添加了workingMillis欄位,用於展示實際執行操作所花費的時間。
區別於之前的durationMillis操作總延遲,workingMillis不會包含鎖等待或流量控制等因素消耗的時間。
彙總
BinData轉換
您可以使用$convert運算子執行以下轉換:
字串值轉換為binData值。
binData值轉換為字串值。
另外,$toUUID運算式提供了將字串轉換為UUID值的簡化文法。
$queryStats
$queryStats階段會返回已記錄查詢的統計資料,且最佳化了在Change Stream中的跟蹤和報告指標。
安全
可查詢加密:範圍查詢
可查詢加密支援使用$lt、$lte、$gt、$gte對加密欄位進行範圍查詢。
入口隊列
MongoDB 8.0引入了一個新的隊列用於入口准入控制(ingressAdmissionControllerTicketPoolSize ),即從網路進入資料庫的操作將進入入口隊列。
入口隊列預設情況下不進行限制,您可以自訂隊列最大值使得請求進行排隊。
其他最佳化
引入了一種新的Query Shape,此前的Query Shape被稱為Plan Cache Query Shape,同時查詢最佳化工具會將Query Settings作為附加的輸入資訊,影響最終的查詢計劃選擇。
setQuerySettings添加查詢設定:
可用於指定索引選擇,8.0版本棄用了使用
planCacheSetFilter來設定index filter的方式。可用於限流設定,您可以通過
reject選項設定拒絕某個Query Shape。
removeQuerySettings用於刪除查詢設定。$querySettings用於查看查詢設定。
explain()命令現在會通過queryPlanner.optimizationTimeMillis返回查詢計劃用在最佳化上的時間,單位為毫秒。新增
defaultMaxTimeMS參數,用於指定單個讀取操作完成的預設時間限制,單位為毫秒。適用的操作:
findaggregate(不包括$merge和$out階段)countdistinctdbHash
如果用戶端指定了
maxTimeMS,那麼defaultMaxTimeMS對此操作將不再生效。
新增
bulkWrite命令,可以在一個請求中對多個集合執行多條插入、更新、刪除操作。updateOne支援對sort選項進行排序。支援在Capped Collection上建立TTL索引。
非事務的批量插入不會再產生單獨的oplog,而是放到一個oplog中進行批處理,所有插入的文檔在Change Stream事件中有相同的
clusterTime。此改動提高了批量插入的效能,避免從節點回放多條oplog可能導致的複寫延遲。支援對同一資料庫下的不同集合并發執行DDL操作。
在叢集執行DDL操作(如
reshardCollection這種會修改集合的命令)的過程中添加或刪除分區會被阻塞,您只能在DDL操作後執行。改進了索引構建,返回錯誤報表的速度更快,故障恢複能力更強。
行為
MongoDB 8.0版本
MongoDB 8.0之前版本
發現錯誤停止構建索引的時機
在收集掃描階段發現的索引錯誤(重複鍵錯誤除外)會立即返回,然後索引構建停止。
MongoDB 8.0可協助您快速診斷索引錯誤。例如,如果發現不相容的索引值格式,則會立即將錯誤返回給您。
MongoDB 8.0之前版本在收集掃描階段發現的索引錯誤會在提交階段返回錯誤,提交階段發生在索引構建的末尾。
與MongoDB 8.0相比,索引構建錯誤可能需要很長時間才能返回,因為錯誤是在提交階段索引構建結束時返回的。
彈性部署
提高部署的彈性。如果發生索引構建錯誤,輔助成員可以請求主成員停止索引構建,並且輔助成員不會崩潰。
停止索引構建的請求並不總是可行的,如果成員已經投票提交索引,則輔助成員無法請求停止索引構建,並且輔助成員會崩潰(類似於MongoDB 7.0及更早版本)。
索引構建錯誤可能導致輔助成員崩潰。
磁碟空間
改進了索引構建的磁碟空間管理。如果可用磁碟空間低於
indexBuildMinAvailableDiskSpaceMB參數中指定的最小值,索引構建可能會自動停止。如果成員已經投票同意提交索引,則索引構建不會停止。
可用磁碟空間不足時,也會停止索引構建。