當前位置:
首頁 > 知識 > 一些MongoDB的坑

一些MongoDB的坑

由於過去的歷史原因,我們使用的默認DB是MongoDB資料庫。MongoDB資料庫本身在支持非格式化的數據存儲方面有比較大的優勢,也不需要額外做很多的Schema Migration,在我們項目初期,數據存儲結構變動頻繁時幫助非常大。

但是,隨著我們的業務不斷增長,我們也遇到了一些問題,這篇文章總結了一些我們在過去的過程中出現的一些問題或者失誤,幫助大家在實踐過程中進行規避。

WiredTriger引擎集合使用不當問題

WiredTriger引擎在使用過程中,我們創建了大量的集合,這個在使用過程中暫時未對我們造成實際的業務影響,但是從實際使用而言,對整體資料庫性能、後續主從複製集群同步,都是有一定影響的。這個只是經驗記錄性內容,實際上,應該避免:一個DB下有過多Collection,這樣會導致鎖競爭,部分操作出現大幅度性能下滑。同時,過多的DB也會導致主從同步失敗(listDatabse超時導致失敗,從庫退出)。

資料庫索引建立

MongoDB Collection索引建立功能支持前台創建模式與後台創建模式兩種。默認模式為前台創建模式。這種模式下會發生:DB被鎖,主庫所有讀寫被禁止、從庫無法訪問。從另一方面來說,會導致業務系統的資料庫訪問受到影響。雖然前台創建模式效率更高,但是如果是線上操作,並且有一定數量級,創建索引時需要添加

{background:true}

讓創建索引操作轉換為後台操作,儘管時間較長,但是對業務影響較小。

資料庫主從切換

雖然MongoDB的Replica Set功能可以方便的進行自動主從切換。但是實際使用過程中,我們也會出現一些手工進行主從庫切換的情況,比如,進行版本升級操作。但是如果這個時候強行進行Primary的重啟,則可能會出現未同步至Secondary的數據丟失的情況(血淚教訓)。這種情況下,重啟集群的方式是,優先進行Secondary的更新操作,在Secondary更新完成後,對Primary進行 stepDown 操作,等待主節點降級成為Secondary節點,之後進行操作。這樣的好處是不會丟失數據。但是如果主從數據差異較大時,有可能會造成降級失敗,此時可以重複執行stepDown直至成功。還有一個值得注意的是,即便Secondary可以停機維護,但是仍舊有可能丟數據,這個與

oplog

有關,我們放在後面說。

慢查詢問題

慢查詢的記錄可以通過Profiling進行記錄,這部分資料比較多,可以通過

db.setProfilingLevel()

進行管理。同時,主動分析也可以通過

explain

進行預分析。這一部分資料比較多,我這裡就不再啰嗦了。但是還有一個問題是,部分慢查詢操作不會隨著客戶端斷開中斷執行,需要通過

db.currentOp()

db.killOp()

功能幹掉長時間執行、浪費資源的操作。

主從同步延遲問題

主從同步問題是比較常見的延遲問題了,主要問題都是出在

oplog

上。畢竟主從同步機制都是通過此實現的。

oplog

是固定大小的集合,如果滿了,就會自動刪除老的數據。

這裡可以看到,此處查詢

oplog

操作記錄到從庫同步,已經執行了194毫秒。

上面我們提到,當Secondary停機維護時也可能出現問題,就是因為,當

oplog

不足時,那麼就有可能會導致數據同步失敗。因此一般資料庫停機維護操作,也應該放在業務量小的時候進行。不過

oplog

是可以調整的,可以參考官方文檔

進行調整。

主從同步延遲一般出現的情況都是數據出現大量插入和修改的情況。在Secondary進行

oplog

重放時,開銷會大於

Primary

進行操作的開銷。這種情況會產生大量的

oplog

(每條修改記錄一條,非操作),記錄越多,同步速度越慢。同時,某些操作也會大幅度降低單條記錄的成本,比如

$inc

$push

等等會讓同步更慢。如果你對資料庫中較大量數據進行

$set

操作,同樣也會造成數據延遲。我們的一位工程師就因為這樣曾經造成了分鐘級別的延遲,教訓也是非常慘痛的。這種操作比較頻繁時,我們可以通過調整

replWriterThreadCount

參數進行Secondary重放線程數量調整。在MongoDB中默認為16,這個可以根據情況進行具體調整。不過該參數為MongoDB啟動參數,調整該參數會要求重啟MongoDB。另外一個值得注意的是這種操作會加大內存開銷,如果內存緊張時也需要注意。

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 PHP技術大全 的精彩文章:

PHP 7.2 Beta的Benchmarks 測試:PHP 仍然越來越快
如何解決中文亂碼問題?
PHP浮點數的一個常見問題的解答
關於PHP浮點數的問題

TAG:PHP技術大全 |

您可能感興趣

MongoDB 涼了?
別了,MongoDB!
Spring Boot使用MongoDB
Spring Boot與Kotlin 使用MongoDB資料庫
Docker 安裝 MongoDB
IDEA中安裝MongoDB插件-再也無要nosql manager for mongodb
在Red Hat和Centos上安裝MongoDB
Spring data MongoDB 之 MongoRepository
MongoDB Python官方驅動 PyMongo 的簡單封裝
雲資料庫TencentDBforMongoDB
MongoDB 管理工具: Rockmongo
RedHat 移除 MongoDB
MongoDB - 連接
如何在Ubuntu上開啟MongoDB的IP Security
如何在 Ubuntu 上安裝 MongoDB
AWS 對開源豎中指:推出 MongoDB 替代品 DocumentDB
AWS 開戰 MongoDB!
MongoDB 編程
Memcached、Redis、MongoDB、HBase對比
從Oracle到MongoDB:為什麼AWS不斷拋棄合作夥伴?