【IT168 評論】出於某些政治上的原因,我對這個問題沉默了一段時間,但是現在我覺得我有責任站出來以我的親身經歷來告誡那些想要在它們的業務中使用MongoDB的人們。
我們團隊在一個很大的項目(幾千萬用戶)中使用了MongoDB,根據早期的使用,我們希望可以像10gen公司吹捧的那樣,通過長期使用來獲得它 們宣揚的伸縮性上的好處,但是事實證明,我們錯了,我覺得有必要分享下我們的教訓,即使只有一個人從中收益,我認爲也值了。要說明的是,10gen公司確 實盡了他們最大的努力並且很熱情的幫助我們,有時甚至熱心過度,但是,這並不妨礙我對他們失敗產品的批評。
1. MongoDB爲了追求贏得基準測試導致它默認以不安全的方式進行寫操作
如果你不調用getLastError(),MongoDB會在寫操作實際完成之前就返回了,這會導致2種問題:
在併發環境下(比如連接池),如果你在“完成”一個寫操作後接着去讀剛剛寫入的數據,可能會遇到一個讀錯誤,並且你沒法知道數據庫會在什麼時候完成這個寫操作。
很多情況下,隊列中的保存操作會被丟棄,而你得不到任何通知,比如連接中斷,或者數據庫崩潰或者其它意外情況下,TCP緩存中保存的操作就人間蒸發了。
2. MongoDB會以很多莫名其妙的方式弄丟你的數據
數據忽然就沒了,不知道爲什麼。
損壞的數據庫沒法恢復。
主節點和從節點的備份存在縫隙,導致從節點經常缺少某些數據,是得,沒有校驗和,並且備份狀態顯示從節點的數據是同步的。
備份經常不工作,沒有錯誤,你需要自己監控你的備份狀態。
3. 需要全局鎖來發出寫請求
4. MongoDB的分區(sharding)在帶負載的情況下工作也不正常
在高負載的情況下添加一個shard簡直就是噩夢,Mongo要麼就是過快的在分區之間移動數據塊,變成對自己的DOS攻擊,要麼就是拒絕接受更多的塊。
5. Mongo完全沒有可靠性可言
Mongod/配置服務器/mongos的架構確實很聰明,但不幸的是,mongos完全就是垃圾,在有負荷的情況下,它隨時都會崩潰,短則幾小時,長則幾天,並且重啓管理進程有時也不管用,有時它會拋出斷言破壞一個關鍵線程,但是進程卻依然在運行。
你猜怎麼着,唯一可行的方式就是在mongos前面配置一個haproxy,然後啓動一個外部監管程序對mongos進行輪詢,定期清除老實例然後創建新實例,沒錯,就是這樣,不開玩笑。
6. MongoDB有次甚至刪除了整個數據庫
MongoDB 1.6,在配置了備份後,有時會錯誤的將一個全新節點的數據當作是最新的數據,然後刪除其它所有節點的所有數據(大約有700G的好數據被刪掉了),並將 這個空數據同步到其它所有節點,作爲一個數據庫,這種事情是絕對不應該發生的,如果不能確定,應該詢問管理員來選擇合適的操作,而不是刪除所有數據。
謝天謝地,這個Bug在1.8已經修復了。
7. 他們總是交付些壓根就不應該交付的東西
一個令人尷尬的事實就是,即使是穩定版也會存在破壞數據的Bug——而且總是在我們的數據被破壞之後我們才發現——我們購買了10gen的白金支持,但是我們得到的支持就是一堆它們稱之爲內部RC的熱補丁,直接運行在我們的數據上。
8. 備份(Replication)在忙碌的服務器上基本就是廢柴
備份經常性不工作,要麼就是DOS master,要麼就是消耗太多時間直到耗光oplog(即使oplog有50G的空間)。
但是,這些都不是最主要的,真正的問題:
你可能會說,這些都是老黃曆了,他們已經在最新版修復了這些問題,但這不是我想說的,我要表達的是,作爲一個數據庫開發公司,它們應該按照下面的順序來排列它們的工作優先級:
1. 不能丟失數據,確保數據非常可靠
2. 通過實踐確保可達性
3. 多節點的伸縮性
4. 降低延遲到99%和95%之間
5. 單個資源的每秒請求數
10gen的排序似乎是#5是第一位的,其它幾項的排序未知,但是可以肯定,第一條肯定不在它們的前三之列。
最後,希望你能認真考慮以上警告。