Mongodb常見問題


一.數據庫級鎖

MongoDB的鎖機制和一般關系數據庫如 MySQL(InnoDB), Oracle 有很大的差異,InnoDB 和 Oracle 能提供行級粒度鎖,而 MongoDB 2.x 只能提供 庫級粒度鎖,這意味着當 MongoDB 一個寫鎖處於占用狀態時,其它的讀寫操作都得干等。

MongoDB 使用的是“readers-writer”鎖, 可以支持並發但有很大的局限性,當一個讀鎖存在,許多讀操作可以使用這把鎖,然而, 當一個寫鎖的存在,一個單一的寫操作會 exclusively 持有該鎖,同時其它讀,寫操作不能使用共享這個鎖;舉個例子,假設一個集合里有 10 個文檔,多個 update 操作不能並發在這個集合上,即使是更新不同的文檔。


初看起來庫級鎖在大並發環境下有嚴重的問題,但是 MongoDB 依然能夠保持大並發量和高性能,這是因為 MongoDB 的鎖粒度雖然很粗放,但是在鎖處理機制和關系數據庫鎖有很大差異,主要表現在:

MongoDB 沒有完整事務支持,操作原子性只到單個 document 級別,所以通常操作粒度比較小;
MongoDB 鎖實際占用時間是內存數據計算和變更時間,通常很快;
MongoDB 鎖有一種臨時放棄機制,當出現需要等待慢速 IO 讀寫數據時,可以先臨時放棄,等 IO 完成之后再重新獲取鎖


在MongoDB 3.0版本中鎖的粒度就變得更細了,除了全局鎖、數據庫鎖還加入了集合鎖,而且對於WiredTiger存儲引擎和MMAPv1存儲引擎而言兩者之間的鎖機制也有不同。
 WiredTiger:對於大部分的讀寫操作,WiredTiger使用樂觀鎖。WiredTiger對於全局、數據庫、集合級別只會使用意向鎖。當存儲引擎檢測到兩個操作之間的沖突,一個寫沖突導致MongoDB透明地重試寫操作。一些全局操作,跟2.2版本一樣還是會需要全局鎖,例如,刪除一個集合,那么仍然還是需要一個互斥的數據庫鎖的。


如何查看鎖的狀態

db.serverStatus()
db.currentOp()
mongotop
mongostat

產生數據庫鎖的操作

操作 鎖類型
Issue a query Read lock
Get more data from a cursor Read lock
Insert data Write lock
Remove data Write lock
Update data Write lock
Map-reduce Read lock and write lock, unless operations are specified as non-atomic. Portions of map-reduce jobs can run concurrently.
Create an index Building an index in the foreground, which is the default, locks the database for extended periods of time.

db.eval() Write lock.

二.原子操作但不支持事務

所謂原子操作就是要么對這個文檔操作全部成功,要么全部失敗,不會出現查詢到的文檔沒有保存完整的情況
mongodb不支持事務,所以,在你的項目中應用時,要注意這點。無論什么設計,都不要要求mongodb保證數據的完整性。但是mongodb對單個文檔的操作提供了許多原子操作,比如文檔的保存,修改(包括對單個文檔修改多個字段),刪除等,都是原子操作。

三.插入刪除更新瞬時完成

插入刪除更新都是瞬時完成的,不需要等待數據庫響應。這不屬於異步操作,發出指令后就不在操心之后的操作。客戶端將文檔發給服務器端,就干別的去了,不等待響應。

優點速度快,缺點是操作發送到服務器之后,不管后續服務器是否操作成功,有可能丟數據,(日志,用戶點擊,或數據分析可以接受,但付費系統不適合)

安全性高的付費系統,可采用安全操作在執行完成之后需調用GETLastERROR檢查執行是否成功,然后拋出異常,由前段進行處理

四.單個文件大小限制16M

習慣了使用mongodb中文檔(document)存儲方式, 可以靈活的將大量數據存入一個集合中的一條文檔中, 這樣可以減少大量的數據冗余, 不會出現關系性數據庫, 如myslq中表的某一列的數據冗余. 不過這樣存儲雖好, 但其實也會存在一定的問題, 也就是mongodb中的大小限制, 即單個文檔大小不能超過16M

對遇到過這個問題的人來說, 這個16M的'概念'很好理解, 而對於還未意識到這個問題的人來說, 這個'坑' 可能會讓你花時間都難以發現, 因為這又要牽扯到mongodb的另一個存儲機制 ---- 無返回碼. 在 < mongodb 權威指南> 一書中, 作者稱之為離弦之箭. 什么意思呢, 就是mongodb的插入,刪除等操作, 客戶端向數據庫發出請求之后, 是不需要等待數據庫返回操作是否成功的返回結果. 這也是mongodb插入,更新等操作速度快的原因. 這就導致, 當單個文件超過16M之后, 程序並不會報錯, 但此時, 數據已經無法插入數據庫了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM