對於ApsaraDB for MongoDB執行個體,您可以通過控制台修改參數。對於某些重要參數而言,不恰當的參數值會導致執行個體效能問題或應用報錯,所以本文介紹一些重要參數的最佳化建議以減少您在設定參數時的疑慮。
本文僅包含核心參數,用戶端驅動側的參數(比如socketTimeout等)並不包含在內。
複本集
operationProfiling.mode
適用大版本:大於等於3.0
修改完是否需要重啟:是
預設值:
off作用:指定查詢分析器的層級。
現象:
如果設定為
all或者slowOp且慢日誌比較多時,可能會出現執行個體效能退化而引起困惑。部分客戶也會因為忘了關閉查詢分析器而對自己的某個庫裡出現
system.profile集合而感到困惑。部分客戶也會誤解以為需要將此參數設定為
slowOp才會產生慢日誌。
修改建議:
維持預設值。不僅僅由於開啟查詢分析器會帶來一定的執行個體效能退化,而且慢日誌一般也能提供類似的分析資訊。請在必要的時候才考慮開啟,並且在開啟且分析完畢後及時關閉。更多關於查詢分析器(Database Profiler)的資訊,請參見官方文檔。
operationProfiling.slowOpThresholdMs
適用大版本:大於等於3.0
修改完是否需要重啟:否
預設值:
100作用:定義一個查詢是否為慢查詢的閾值。
現象:
參數設定過小,將導致產生大量慢日誌和審計日誌,帶來慢日誌噪音影響慢查詢分析。
參數設定過大,將導致很多慢查詢並不輸出在日誌中,影響慢查詢分析過程。
修改建議:根據業務的實際情況適當調小或調大閾值,推薦設定為比業務核心查詢的平均耗時稍大些的值。樣本如下:
假設一個對查詢延時比較敏感的業務,日常的查詢耗時都僅在30ms左右,為了協助分析一些瞬時抖動的慢查詢情況,可以將此參數調小到50。
假設一個分析查詢比較重的業務,日常查詢耗時都在300~400ms左右,為了減少慢日誌噪音,可以將此參數調大到500ms。
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作為記憶體 Clerk,此參數用於控制是否開啟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官方文檔。
setParameter.minSnapshotHistoryWindowInSeconds/setParameter.maxTargetSnapshotHistoryWindowInSeconds
適用大版本:大於等於4.4
修改完是否需要重啟:否
預設值:
300(5分鐘)作用:WT引擎保留快照(snapshot)歷史的視窗大小。單位為秒,0表示關閉快照歷史視窗。該參數主要用於支援atClusterTime的讀取。
現象:此參數會帶來一定的WT緩衝(WT cache)壓力,尤其是相同文檔頻繁更新的情境。
修改建議:一般情況無需調整。
如果業務側確定不會使用讀歷史快照(read atClusterTime)的功能,可以將此參數調小到0,以獲得一定的效能提升。
如果業務側希望能讀到早於5分鐘前的歷史快照資料,則可以將此參數調大。但也需要注意到調大後帶來的額外記憶體消耗和效能開銷。
說明如果該參數值較小,而讀歷史快照時指定的時間更早,則會收到返回的
SnapshotTooOld錯誤。
rsconf.chainingAllowed
適用大版本:大於等於4.0
修改完是否需要重啟:否
預設值:
true作用:是否允許複本集中的鏈式複製。
現象:
關閉鏈式複製可能會導致主節點的負載上升(例如CPU使用率、網路流量等)。
開啟鏈式複製可能會更容易出現從節點資料滯後。
修改建議:
節點數少時(小於等於4個 ):可以按需調整開啟或關閉鏈式複製。
節點數多時(大於等於5個):僅在writeConcern配置為
{w:majority}時,您需要在主節點負載和執行個體效能之間做進一步的取捨,關閉鏈式複製有助於提升寫入效能,但相應的主節點負載也會顯著增加。
setParameter.internalQueryMaxPushBytes/setParameter.internalQueryMaxAddToSetBytes
適用大版本:大於等於4.2
修改完是否需要重啟:否
預設值:104857600 B(100 MB)
作用:限制
$push和$addToSet運算元所能使用的最大記憶體值。現象:特定的sql(包含
$push或$addToSet)執行失敗,返回如下的錯誤資訊。"errMsg": "$push used too much memory and cannot spill to disk. Memory limit: 104857600...修改建議:一般情況無需調整。如果執行特定的SQL遇到了上述報錯,可以適當調大。但需注意,如果此參數設定得過大,可能會引起mongod節點出現OOM的情況。
分區叢集(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遷移後的文檔非同步刪除流程,調整時可以分別調整、組合調整或者漸進式調整。
setParameter.receiveChunkWaitForRangeDeleterTimeoutMS
適用大版本:大於等於4.4
修改完是否需要重啟:否
預設值:
10000(10秒)作用:指定Chunk遷移前等待刪除孤立文檔的逾時時間,單位為毫秒。
現象:Balancer運行過程中,您可能會看到如下的逾時錯誤記錄檔:
ExceededTimeLimit: Failed to delete orphaned <db.collection> range [{ <shard_key>: MinKey }, { <shard_key>: -9186000910690368367 }) :: caused by :: operation exceeded time limit修改建議:一般情況無需調整。遇到上述報錯的情況下,可以將此參數適當調大,使得moveChunk操作可以等待刪除孤立文檔操作更長時間,以避免類似逾時錯誤。
setParameter.minSnapshotHistoryWindowInSeconds/setParameter.maxTargetSnapshotHistoryWindowInSeconds
適用大版本:大於等於4.4
修改完是否需要重啟:否
預設值:
300(5分鐘)作用:WT引擎保留快照(snapshot)歷史的視窗大小。單位為秒,0表示關閉快照歷史視窗。該參數主要用於支援atClusterTime的讀取。
現象:此參數會帶來一定的WT緩衝(WT cache)壓力,尤其是相同文檔頻繁更新的情境。
修改建議:一般情況無需調整。
如果業務側確定不會使用讀歷史快照(read atClusterTime)的功能,可以將此參數調小到0,以獲得一定的效能提升。
如果業務側希望能讀到早於5分鐘前的歷史快照資料,則可以將此參數調大。但也需要注意到調大後帶來的額外記憶體消耗和效能開銷。
說明如果該參數值較小,而讀歷史快照時指定的時間更早,則會收到返回的
SnapshotTooOld錯誤。
rsconf.chainingAllowed
適用大版本:大於等於4.0
修改完是否需要重啟:否
預設值:
true作用:是否允許Shard中的鏈式複製。
現象:
關閉鏈式複製可能會導致主節點的負載上升(例如CPU使用率、網路流量等)。
開啟鏈式複製可能會更容易出現從節點資料滯後。
修改建議:
節點數少時(小於等於4個 ):可以按需調整開啟或關閉鏈式複製。
節點數多時(大於等於5個):僅在writeConcern配置為
{w:majority}時,您需要在主節點負載和執行個體效能之間做進一步的取捨,關閉鏈式複製有助於提升寫入效能,但相應的主節點負載也會顯著增加。
setParameter.internalQueryMaxPushBytes/setParameter.internalQueryMaxAddToSetBytes
適用大版本:大於等於4.2
修改完是否需要重啟:否
預設值:104857600 B(100 MB)
作用:限制
$push和$addToSet運算元所能使用的最大記憶體值。現象:特定的sql(包含
$push或$addToSet)執行失敗,返回如下的錯誤資訊。"errMsg": "$push used too much memory and cannot spill to disk. Memory limit: 104857600...修改建議:一般情況無需調整。如果執行特定的SQL遇到了上述報錯,可以適當調大。但需注意,如果此參數設定得過大,可能會引起mongod節點出現OOM的情況。
分區叢集(Mongos)
operationProfiling.slowOpThresholdMs
適用大版本:大於等於3.0
修改完是否需要重啟:否
預設值:
100作用:定義一個查詢是否為慢查詢的閾值。
現象:
參數設定過小,將導致產生大量慢日誌和審計日誌,帶來慢日誌噪音影響慢查詢分析。
參數設定過大,將導致很多慢查詢並不輸出在日誌中,影響慢查詢分析過程。
修改建議:根據業務的實際情況適當調小或調大閾值,推薦設定為比業務核心查詢的平均耗時稍大些的值。樣本如下:
假設一個對查詢延時比較敏感的業務,日常的查詢耗時都僅在30ms左右,為了協助分析一些瞬時抖動的慢查詢情況,可以將此參數調小到50。
假設一個分析查詢比較重的業務,日常查詢耗時都在300~400ms左右,為了減少慢日誌噪音,可以將此參數調大到500ms。
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)。無論如何,業務側都應盡量避免出現長時間空閒遊標的情況。