對于云數據庫 MongoDB 版實例,您可以通過控制臺修改參數。對于某些重要參數而言,不恰當的參數值會導致實例性能問題或應用報錯,所以本文介紹一些重要參數的優化建議以減少您在設置參數時的疑慮。
本文僅包含內核參數,客戶端驅動側的參數(比如socketTimeout等)并不包含在內。
副本集
operationProfiling.mode
適用大版本:大于等于3.0
修改完是否需要重啟:否
默認值:
off
作用:指定查詢分析器的級別。
現象:
如果設置為
all
或者slowOp
且慢日志比較多時,可能會出現實例性能退化而引起困惑。部分客戶也會因為忘了關閉查詢分析器而對自己的某個庫里出現
system.profile
集合而感到困惑。部分客戶也會誤解以為需要將此參數設置為
slowOp
才會產生慢日志。
修改建議:
維持默認值。不僅僅由于開啟查詢分析器會帶來一定的實例性能退化,而且慢日志一般也能提供類似的分析信息。請在必要的時候才考慮開啟,并且在開啟且分析完畢后及時關閉。更多關于查詢分析器(Database Profiler)的信息,請參見官方文檔。
operationProfiling.slowOpThresholdMs
適用大版本:大于等于3.0
修改完是否需要重啟:否
默認值:
100
作用:定義一個查詢是否為慢查詢的閾值。
現象:
參數設置過小,將導致產生大量慢日志和審計日志,帶來慢日志噪音影響慢查詢分析。
參數設置過大,將導致很多慢查詢并不輸出在日志中,影響慢查詢分析過程。
修改建議:根據業務的實際情況適當調小或調大閾值,推薦設置為比業務核心查詢的平均耗時稍大些的值。示例如下:
假設一個對查詢延時比較敏感的業務,日常的查詢耗時都僅在30ms左右,為了協助分析一些瞬時抖動的慢查詢情況,可以將此參數調小到50。
假設一個分析查詢比較重的業務,日常查詢耗時都在300~400ms左右,為了減少慢日志噪音,可以將此參數調大到500。
replication.oplogGlobalIdEnabled
適用大版本:大于等于4.0
修改完是否需要重啟:是
默認值:
false
作用:是否開啟oplog的GID來支持DTS或mongoShake的雙向同步,該參數為自研參數。GID的目的是為了解決雙向同步中的環形同步問題。
修改建議:只在需要進行雙向同步時開啟。該參數需要重啟實例生效,應盡量在業務低峰期變更。
replication.oplogSizeMB
適用大版本:大于等于3.0
修改完是否需要重啟:否
默認值:
規格的磁盤空間的10%
(比如實例的磁盤大小是500GB,則初始oplogSizeMB就是51200,即50GB)作用:指定用于保存邏輯同步日志的oplog表的最大值(邏輯大小)。
現象:參數設置過小,可能會導致從節點跟不上而進入異常的RECOVERING狀態;也有可能導致日志備份來不及覆蓋所有oplog記錄而出現空洞,進而無法進行按時間點恢復。
修改建議:維持默認值,不要調小,需要時調大。如遇以下場景可適當調大該值:業務的workload屬于數據量不大但更新很多的情況,oplog產生速度比較快。此時適當調大oplogSizeMB可以使得oplog表能夠覆蓋更長時間的oplog記錄,避免出現oplog記錄空洞的問題。最佳實踐為設置的oplogSize至少應可以保留1小時以上的oplog記錄。
該參數的修改并不是通過變更配置文件里的此參數來生效的,阿里云側管控會通過專門的replsetResizeOplog命令來調整oplog大小。
setParameter.cursorTimeoutMillis
適用大版本:大于等于3.0
修改完是否需要重啟:否
默認值:
600000
(10min)作用:空閑游標的到期閾值,單位為毫秒。如果游標的空閑時間超過該閾值,則MongoDB會自動清理該游標。
現象:如果嘗試訪問一個已經被清理的過期游標,客戶端側會收到以下格式的報錯:
Message: "cursor id xxxxxxx not found" ErrorCode: CursorNotFound(43)
修改建議:不建議調大,為了降低空閑游標的資源開銷,可以適當調小(比如300000)。無論何種場景,業務側都應盡量避免出現長時間空閑游標的情況。
setParameter.flowControlTargetLagSeconds
適用大版本:大于等于4.2
修改完是否需要重啟:否
默認值:
10
作用:flowControl機制觸發的閾值,flowControl的目的是為了確保大多數提交點不會落后太多。
現象:出現類似下面的慢日志(durationMillis基本等價于flowControl.timeAcquiringMicros,說明請求慢主要是受到flowControl影響),且請求明顯受到影響,耗時大幅增加。
{ "t": { "$date": "2024-04-25T13:28:45.840+08:00" }, "s": "I", "c": "WRITE", "id": 51803, "ctx": "conn199253", "msg": "Slow query", "attr": { "type": "update", "ns": "xxx.xxxxx", "command": ..., "planSummary": "IDHACK", "totalOplogSlotDurationMicros": 61, "keysExamined": 1, "docsExamined": 1, "nMatched": 1, "nModified": 1, "nUpserted": 0, "keysInserted": 0, "keysDeleted": 0, "numYields": 0, "locks": ..., "flowControl": { "acquireCount": 1, "acquireWaitCount": 1, "timeAcquiringMicros": 959000 }, "readConcern": { "level": "local", "provenance": "implicitDefault" }, "storage": {}, "cpuNanos": 258845, "remote": "172.16.6.38:52368", "durationMillis": 959 } }
修改建議:可以適當調大該參數,以此來降低flowControl機制介入的敏感度。如果調大后還是會出現請求經常被限流的情況,則說明實例在主從同步方面存在一定的性能瓶頸,需要進一步分析并采取其他方式來解決,比如升級實例配置或者將writeConcern設置為majority。
setParameter.oplogFetcherUsesExhaust
適用大版本:大于等于4.4
修改完是否需要重啟:是
默認值:
true
作用:是否開啟流式復制(Stream Replication)。如果關閉此功能的話,主從同步將回退到與之前版本一致的拉取方式。即從節點給同步源發獲取一批oplog的請求,然后等待回復,這意味著每批oplog都需要一次網絡往返的交互。
現象:部分場景下,流式復制機制可能會帶來額外的性能開銷和網絡帶寬開銷。
修改建議:不建議調整。流式復制可以在高負載和高延遲的網絡環境中減輕復制延遲,還可以降低writeConcern為
{w:1}
時primary節點異常宕機時的寫入丟失風險,也可以降低其他依賴主從復制的writeConcern(比如{w:majority}
或{w:>1}
)下的寫入延遲。
setParameter.maxTransactionLockRequestTimeoutMillis
適用大版本:大于等于4.0
修改完是否需要重啟:否
默認值:
5
作用:指定事務加鎖的超時時間,單位為毫秒。如果事務里的操作無法在給定的時間內獲取到需要的鎖,則事務會自動abort。
現象:在日志中或者客戶端中遇到如下的鎖獲取超時報錯信息。(高版本驅動對于這種TransientTransactionError會自動重試,因此可能只在日志中出現,客戶端側無法感知)
Message: "Unable to acquire lock '{8442595743001781021: Database, 1525066715360699165}' within a max lock request timeout of '5ms' milliseconds." ErrorCode: LockTimeout(24)
修改建議:如果客戶端側經常遇到類似的報錯,可以嘗試將此參數調大,能適當緩解瞬時并發鎖獲取不到而導致的事務中止,但相應地也會使得死鎖事務操作的中止延后。如果參數調大后問題依然出現,則不建議進一步調大參數,而是需要考慮從業務邏輯上進行優化,比如避免事務內對相同文檔的并發修改,以及重新審視事務里的操作,檢查事務中是否包含了可能會長時間占用鎖的操作(比如DDL、待優化的查詢),從源頭上避免類似問題發生。
setParameter.replWriterThreadCount
適用大版本:大于等于3.2
修改完是否需要重啟:是
默認值:
16
作用:指定主從同步中并行復制的最大線程數,實際生效的最大線程數為實例規格CPU核數的2倍。
現象:極端場景下可能出現主從同步不及時而從節點產生延遲(lag)不斷增大的情況。
修改建議:一般情況不建議調整。特殊情況推薦在阿里云研發工程師的建議下來進行調整。
setParameter.tcmallocAggressiveMemoryDecommit
適用大版本:大于等于4.2
修改完是否需要重啟:否
默認值:
0
(代表關閉TCMalloc激進回收)作用:MongoDB內部使用了TCMalloc作為內存分配器,此參數用于控制是否開啟TCMalloc的激進回收策略。開啟后,MongoDB會主動嘗試合并相鄰的空閑內存塊并歸還一部分內存給操作系統。
現象:
因為查詢請求消耗過大,內存來不及回收而出現mongod節點OOM的情況。
隨著不斷使用,堆內存碎片空間越來越多,表現上為內存使用率超過80%且穩定緩慢上升。
修改建議:一般情況不建議調整。有內存相關問題時可以考慮在業務低峰期時調整。
開啟此參數可能會帶來一定的性能退化,具體情況取決于您的工作負載。建議您只在業務低峰期時嘗試開啟此參數,且調整完持續觀察業務一段時間,如果有受影響的情況應及時回滾參數調整。
setParameter.transactionLifetimeLimitSeconds
適用大版本:大于等于4.0
修改完是否需要重啟:否
默認值:
60
作用:指定事務的生命周期,單位為秒。如果事務的整體執行時間超過了此限制,會被標記為過期并被后臺的周期性清理線程主動處理并abort掉。
現象:客戶端側遇到格式如下的報錯:
Message: "Aborting transaction with txnNumber xxx on session with lsid xxxxxxxxxx because it has been running for longer than 'transactionLifetimeLimitSeconds'"
修改建議:可以適當調小(比如到
30
),不建議調大。未提交的長事務可能會給WiredTiger存儲引擎的緩存帶來很大壓力,一旦緩存壓力超載通常會帶來更多問題,包括數據庫卡頓、請求延遲大幅增加、CPU使用率滿等,導致業務受損。無論如何,業務側都應該盡量避免長事務的出現。為了解決超時問題,您應該將事務分解為更小的部分,以便在配置的時間限制內可以執行完成。您還需要確保已經優化過查詢語句,查詢語句具有適當的索引覆蓋率,以便在事務中快速地訪問數據。
關于事務使用的最佳實踐,請參見事務與Read/Write Concern。
storage.oplogMinRetentionHours
適用大版本:大于等于4.4
修改完是否需要重啟:否
默認值:
0
(代表此參數不生效,oplog大小完全由前面提到的replication.oplogSizeMB
參數控制)作用:指定用于保存邏輯同步日志的oplog表的最小保留時間。
現象:
參數設置過大,導致oplog表占據過多磁盤空間。
部分用戶忘記曾經設置過此參數,疑惑實例的磁盤空間大小波動原因。
修改建議:對于相對穩定的workload,維持默認值。對于可能會發生大幅度寫入操作變化的workload,建議將此參數配置為>1.0的浮點數。設置此參數時也需要評估可能的空間占用,避免觸發磁盤滿鎖引發其他問題。
storage.wiredTiger.collectionConfig.blockCompressor
適用大版本:大于等于3.0
修改完是否需要重啟:是
默認值:
snappy
作用:設置集合數據的存儲壓縮算法(修改后僅對所有的新建的表生效,已存在的表不受影響)。目前支持設置為不壓縮或者
snappy
、zlib
、zstd
壓縮算法(4.2及以上的版本才支持zstd
)。修改建議:按需修改。不同的壓縮算法有著不同的表現,有的壓縮率更高但壓縮和解壓時的CPU開銷更大。實際壓縮算法之間的對比,應以您實際測試的結果為準。如果實例主要用來存儲冷數據,那么為了獲得更高的壓縮比,可以考慮將此參數修改為
zstd
。說明如果您想針對不同的表使用不同的壓縮算法,需要使用帶相關選項的顯式
createCollection
命令,更多介紹,請參見MongoDB官方文檔。
分片集群(Shard)
setParameter.migrateCloneInsertionBatchSize
適用大版本:大于等于4.0
修改完是否需要重啟:否
默認值:
0
(代表受16MB文檔大小限制)作用:指定chunk遷移時克隆步驟中單個批次的最大文檔數量。
現象:部分場景下,chunk遷移時可能會導致分片出現性能毛刺問題。
修改建議:一般情況無需調整。如果分片集群實例在均衡期間因為chunk遷移而導致性能毛刺問題,可以考慮將此參數調整為一個固定的批次大小。
setParameter.rangeDeleterBatchDelayMS
適用大版本:大于等于4.0
修改完是否需要重啟:否
默認值:
20
作用:chunk遷移時清理步驟中批量刪除的間隔時間(也會影響清理孤立文檔的
cleanupOrphaned
命令),單位為毫秒。現象:
部分場景下,進行chunk遷移后的文檔異步刪除時可能會導致CPU突增。
參數設置過大,文檔可能未及時刪除導致變成孤立文檔;或者需要刪除的文檔太多而超時,出現下面的錯誤日志:
Message: "OperationFailed: Data transfer error: ExceededTimeLimit: Failed to delete orphaned <db>.<collection> range [xxxxxx,xxxxx] :: caused by :: operation exceeded time limit"
修改建議:一般情況無需調整。如果分片集群實例在均衡期間因為文檔異步刪除而導致CPU使用率突增,可以考慮將此參數調大,比如調整為
200
。
setParameter.rangeDeleterBatchSize
適用大版本:大于等于4.0
修改完是否需要重啟:否
默認值:
0
(代表自動選擇合理的批次大小,一般為128)作用:指定chunk遷移時清理步驟中批量異步刪除單個批次的最大文檔數量。
現象:部分場景下,進行chunk遷移后的文檔異步刪除時可能會導致CPU使用率突增。
修改建議:一般情況無需調整。如果分片集群實例在均衡期間因為文檔異步刪除而導致CPU突增,可以考慮將此參數調整為一個固定的批次大小。
此參數與setParameter.rangeDeleterBatchDelayMS參數共同作用來影響chunk遷移后的文檔異步刪除流程,調整時可以分別調整、組合調整或者漸進式調整。
分片集群(Mongos)
operationProfiling.slowOpThresholdMs
適用大版本:大于等于3.0
修改完是否需要重啟:否
默認值:
100
作用:定義一個查詢是否為慢查詢的閾值。
現象:
參數設置過小,將導致產生大量慢日志和審計日志,帶來慢日志噪音影響慢查詢分析。
參數設置過大,將導致很多慢查詢并不輸出在日志中,影響慢查詢分析過程。
修改建議:根據業務的實際情況適當調小或調大閾值,推薦設置為比業務核心查詢的平均耗時稍大些的值。示例如下:
假設一個對查詢延時比較敏感的業務,日常的查詢耗時都僅在30ms左右,為了協助分析一些瞬時抖動的慢查詢情況,可以將此參數調小到50。
假設一個分析查詢比較重的業務,日常查詢耗時都在300~400ms左右,為了減少慢日志噪音,可以將此參數調大到500。
setParameter.ShardingTaskExecutorPoolMaxConnecting
適用大版本:大于等于3.6
修改完是否需要重啟:
3.6和4.0版本:是
大于等于4.2版本:否
默認值:
2
作用:指定分片集群實例Mongos上TaskExecutor連接池初始化連接時的最大并發度。用來控制mongos到mongod的連接建立速度。
現象:如果該值設置較大,在觸發較多連接創建時,可能會引起Mongos的CPU使用率突增。
修改建議:不建議調整。
setParameter.ShardingTaskExecutorPoolMaxSize
適用大版本:大于等于3.6
修改完是否需要重啟:
3.6和4.0版本:是
大于等于4.2版本:否
默認值:
2^64-1
(int64類型的最大值)作用:指定分片實例Mongos上每個TaskExecutor連接池的最大連接數。
修改建議:無需調整。如果期望限制Mongos到Shard之間的連接池上限,可以設置,但不建議設置得太小,否則會導致連接池耗盡時Mongos上請求阻塞等待的問題。
setParameter.ShardingTaskExecutorPoolMinSize
適用大版本:大于等于3.6
修改完是否需要重啟:
3.6和4.0版本:是
大于等于4.2版本:否
默認值:
1
作用:指定分片集群實例Mongos上每個TaskExecutor連接池的最小連接數。
現象:部分場景下,Mongos上突發的請求可能會導致TaskExecutor連接池需要額外新建很多連接,然后引起Mongos上的CPU突增以及其他問題。
修改建議:建議設置為
[10,50]
間的合理值,具體多少應該取決于分片實例的拓撲結構(分片數以及分片內的節點數)。請注意,Mongos維護這些到Shard上的空閑連接會有少量資源開銷。
setParameter.cursorTimeoutMillis
適用大版本:大于等于3.0
修改完是否需要重啟:否
默認值:
600000
(10min)作用:空閑游標的到期閾值,單位為毫秒。如果游標的空閑時間超過該閾值,則MongoDB會自動清理該游標。
現象:如果嘗試訪問一個已經被清理的過期游標,客戶端側會收到以下格式的報錯:
Message: "cursor id xxxxxxx not found" ErrorCode: CursorNotFound(43)
修改建議:不建議調大,為了降低空閑游標的資源開銷,可以適當調小(比如到300000)。無論如何,業務側都應盡量避免出現長時間空閑游標的情況。