【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是第一位的,其它幾項的排序未知,但是可以肯定,第一條肯定不在它們的前三之列。
最後,希望你能認真考慮以上警告。