用還是不用MongoDB?悲催用戶炮轟10gen CTO
前幾天在HackNew上出現(xiàn)了一篇文章,標(biāo)題很彪悍,叫《Don’t use MongoDB》,其內(nèi)容也是直接表達(dá)了對(duì)MongoDB的不滿,作者列舉了MongoDB使用過(guò)程中遇到的種種問(wèn)題。甚至上升到對(duì)其開(kāi)發(fā)團(tuán)隊(duì)的質(zhì)疑,表示他們可能只關(guān)心benchmark的數(shù)據(jù),不關(guān)心用戶數(shù)據(jù)的安全性。真是大叫坑爹?。?/p>
***消息:這篇文章的作者已經(jīng)承認(rèn)文章只是他的一個(gè)惡作劇,他稱只是想做個(gè)實(shí)驗(yàn),以顯示控制一個(gè)人的思維是多么容易。但是他提到的案例并非完全沒(méi)有出現(xiàn)過(guò),這樣一篇惡作劇的文章,雖然著實(shí)唬了我們一把,但是能夠讓一些盲目的朋友更謹(jǐn)慎一些。還是有好處的。
但很快地,10gen CTO @ehwizard 就看到了這篇文章,并馬上對(duì)作者提到的各個(gè)問(wèn)題進(jìn)行了回應(yīng)。ehwizard表示,他翻遍了1600個(gè)用戶案例報(bào)告,并沒(méi)有發(fā)現(xiàn)出現(xiàn)了文章作者所說(shuō)這些問(wèn)題的案例(實(shí)際上也是對(duì)指責(zé)的真實(shí)性進(jìn)行了懷疑。你是哪個(gè)單位的?)。隨后ehwizard又友好的表示,如果你在使用MongoDB中遇到問(wèn)題,可以隨時(shí)到MongoDB的Google Group或者M(jìn)ongoDB相應(yīng)的IRC中進(jìn)行報(bào)告。
在MongoDB正被炒得火熱的今天,相信這樣一篇文章也著實(shí)向一些同學(xué)澆了一頭冷水。所以NoSQLFan將二者PK觀點(diǎn)都放在這里,大家可以自己看一看,甚至做做實(shí)驗(yàn),在使用NoSQL或者是其它新技術(shù)前,也都多了解一些可能出現(xiàn)的問(wèn)題。
下面綠色部分是原文作者對(duì)MongoDB的一些指責(zé)和質(zhì)疑,紅色部分為NoSQLFan的無(wú)聊演繹,其余為10gen CTO ehwizard的回應(yīng)。
1. MongoDB為了在benchmark上好看一些,不惜將不安全的方案作為其默認(rèn)配置。(就差大叫無(wú)良奸商了)
ehwizard說(shuō),哥們你這個(gè)說(shuō)法有點(diǎn)過(guò)份了,MongoDB的默認(rèn)方案的選擇,和benchmark根本就一點(diǎn)關(guān)系都沒(méi)有,而且不僅是默認(rèn)方案,包括API的設(shè)計(jì),以及MongoDB其它的一些功能取舍,都和benchmark沒(méi)有半毛錢(qián)關(guān)系。當(dāng)然,默認(rèn)配置的設(shè)定還是需要和用戶主要的使用場(chǎng)景相關(guān),MongoDB在使用上確實(shí)已經(jīng)經(jīng)歷了很多變化,對(duì)這些變化做出相應(yīng)的默認(rèn)策略調(diào)整,確實(shí)也有可能。
當(dāng)然,話說(shuō)回來(lái),MongoDB的實(shí)現(xiàn)策略的實(shí)現(xiàn),本身是可控的。比如你可以選擇寫(xiě)操作的安全級(jí)別,在你使用了replica sets的時(shí)候,你完全可以設(shè)定一個(gè)寫(xiě)操作同步到一定機(jī)器數(shù)量后才返回成功。(對(duì)作者一大嘴巴子,您這是真不懂呢還是裝不懂呢)
2. MongoDB丟數(shù)據(jù)現(xiàn)象嚴(yán)重,并且導(dǎo)致的情況很多
2.1 MongoDB經(jīng)常詭異的丟失數(shù)據(jù)
對(duì)此ehwizard的回應(yīng)是,對(duì)于丟數(shù)據(jù)的問(wèn)題,我們收到過(guò)bug報(bào)告,但是我們對(duì)MongoDB非常了解,所有的bug在收到后,幾乎都在***時(shí)間進(jìn)行了修復(fù)。如果你能夠給出你丟數(shù)據(jù)時(shí)的使用場(chǎng)景,我們會(huì)盡可能找出原因。ehwizard表示,如果你真的發(fā)生了丟數(shù)據(jù)的問(wèn)題,請(qǐng)馬上聯(lián)系10gen的工程師進(jìn)行bug修復(fù)。(哥們,有問(wèn)題,找組織,不丟人)
2.2 在不使用journaling的時(shí)候,如果MongoDB崩潰,數(shù)據(jù)無(wú)法恢復(fù)
ehwizard解釋說(shuō),這是正常的情況,對(duì)于單機(jī)使用MongoDB來(lái)說(shuō),不使用journaling日志本身就是不推薦的危險(xiǎn)做法,在2.0版本后,journaling日志已經(jīng)是默認(rèn)開(kāi)啟了。而如果是在replica sets等多機(jī)的情況下,你根本不需要進(jìn)行數(shù)據(jù)恢復(fù),只需要從另一個(gè)同步節(jié)點(diǎn)resync數(shù)據(jù)就可以了。
2.3 主從復(fù)制有問(wèn)題,存在丟失數(shù)據(jù)的操作,主從之間沒(méi)有同步校驗(yàn)。并且雖然數(shù)據(jù)丟了,但是在狀態(tài)上顯示還是同步正常的
ehwizard表示這種情況應(yīng)該不會(huì)發(fā)生,如果確實(shí)發(fā)生了,應(yīng)該是嚴(yán)重bug。
2.4 主從復(fù)制存在不明原因的中斷現(xiàn)實(shí),沒(méi)有任何錯(cuò)誤就直接中斷了
ehwizard說(shuō)這確實(shí)有可能發(fā)生,可能中間確實(shí)出錯(cuò)了,只是出錯(cuò)信息并沒(méi)有返回給客戶端而已。因?yàn)閺?fù)制操作本身是異步進(jìn)行的,如果你希望數(shù)據(jù)同步復(fù)制完后才返回,你可以通過(guò)getLastError命令將w參數(shù)設(shè)定為2。
3. MongoDB在進(jìn)行寫(xiě)操作時(shí)使用了一個(gè)全局的寫(xiě)鎖,這樣效率很低
這一點(diǎn)上ehwizard也承認(rèn)這確實(shí)是MongoDB長(zhǎng)期被詬病的問(wèn)題,但是目前在2.0版本中已經(jīng)做了相當(dāng)大的改進(jìn)。已經(jīng)對(duì)寫(xiě)操作需要涉及到磁盤(pán)IO的情況下進(jìn)行了優(yōu)化。而在2.2版本中,這一優(yōu)化還會(huì)進(jìn)一步推進(jìn)。(哥們,針對(duì)collection的lock啥時(shí)候來(lái)啊)
4. 大壓力比較大的時(shí)候,MongoDB的auto-sharding功能會(huì)出現(xiàn)問(wèn)題,在大負(fù)載下,添加一個(gè)sharding結(jié)點(diǎn)絕對(duì)是場(chǎng)噩夢(mèng)。因?yàn)檫@時(shí)候MongoDB只要去做chunk的移動(dòng),就會(huì)影響本身服務(wù),要么就只能不做移動(dòng)。
ehwizard解釋說(shuō),如果系統(tǒng)確實(shí)已經(jīng)到達(dá)極限,這時(shí)候再去做chunk塊的移動(dòng)確實(shí)不容易。關(guān)于這個(gè)話題他自己已經(jīng)在很多場(chǎng)合說(shuō)過(guò),他的建議是盡早監(jiān)測(cè)到集群已經(jīng)快到極限了,不要等到系統(tǒng)已經(jīng)到了100%負(fù)載的時(shí)候再去做添加節(jié)點(diǎn)的操作。(對(duì)自己的業(yè)務(wù)增長(zhǎng)上點(diǎn)心,別跟4sq一樣火燒眉毛了才發(fā)現(xiàn))
5. mongos非常不可靠,雖然 mongod/config server/mongos 結(jié)合的架構(gòu)看起來(lái)很美,但是mongos確實(shí)很不給力。當(dāng)壓力稍大一點(diǎn),mongos就經(jīng)常崩潰,少則幾天崩潰一次,多則幾小時(shí)就崩潰一次。有時(shí)候會(huì)出現(xiàn)拋出斷言然后殺掉某個(gè)關(guān)鍵線程,但是這時(shí)候進(jìn)程居然還依然運(yùn)行,所以重啟管理進(jìn)程也不是每次都管用。
ehwizard表示不知道他所謂的關(guān)鍵線程是什么,希望能夠多提供一些相關(guān)細(xì)節(jié)。
6. MongoDB曾經(jīng)出現(xiàn)過(guò)一次問(wèn)題,導(dǎo)致所有數(shù)據(jù)被刪除了。這個(gè)情況發(fā)生在 MongoDB 1.6版本的replica sets結(jié)構(gòu)中,由于選舉策略出現(xiàn)問(wèn)題,導(dǎo)致選擇了一個(gè)空數(shù)據(jù)節(jié)點(diǎn)作為新的primary,這樣導(dǎo)致那些有數(shù)據(jù)的節(jié)點(diǎn)都把自己的數(shù)據(jù)給刪除了,我們700G的數(shù)據(jù)就這樣沒(méi)了。還好在1.8版本中修復(fù)了這個(gè)問(wèn)題。
ehwizard說(shuō)查看了相關(guān)的報(bào)告,并沒(méi)有發(fā)現(xiàn)有所說(shuō)的問(wèn)題,希望能夠提供更多細(xì)節(jié)。
7. 10gen的人發(fā)布了一些還不能發(fā)布的東西。據(jù)我們所知,在一些stable版本中居然會(huì)有一些導(dǎo)致數(shù)據(jù)問(wèn)題的bug,而通常我們?cè)谟龅竭@些bug的時(shí)候才會(huì)發(fā)現(xiàn)。我們購(gòu)買(mǎi)了10gen的白金級(jí)服務(wù),但是得到的結(jié)果只是一些被他們稱為內(nèi)部RC版本的熱補(bǔ)丁,而我們需要將這些補(bǔ)丁打在我們線上版本上。天哪!
ehwizard表示我們并沒(méi)有什么白金合同,所有的問(wèn)題都是通過(guò)公開(kāi)的jira系統(tǒng)來(lái)反饋的。從問(wèn)題的提出和修改,都是在jira上公示的,(比尼瑪官員的財(cái)產(chǎn)還透明)。如果你不能提供更多的信息,這個(gè)真的不好再討論。我們通常的做法是在修復(fù)了問(wèn)題后會(huì)盡快的通知到相應(yīng)的用戶。
8. 在負(fù)載比較高的機(jī)器上,同步工作相當(dāng)廢柴
感覺(jué)應(yīng)該是負(fù)載過(guò)高了,跟我之前說(shuō)的一樣,同步默認(rèn)是異步的,如果你希望確認(rèn)同步成功,可以通過(guò)getLastError命令設(shè)置w參數(shù)為2。
而上面的問(wèn)題可能已經(jīng)有一些修復(fù)了,但是我想說(shuō)的是,作為一個(gè)公司,還是應(yīng)該將服務(wù)的可靠性放在***位。我認(rèn)為10gen應(yīng)該按下面的優(yōu)先級(jí)來(lái)進(jìn)行MongoDB的功能開(kāi)發(fā):
1. 不要丟數(shù)據(jù),對(duì)數(shù)據(jù)一定要非常小心2. 多做測(cè)試,保證可靠性3. 做到真正的多節(jié)點(diǎn)擴(kuò)展性4. 除低延遲5. 提高對(duì)資源的請(qǐng)求性能
而在我看來(lái),10gen眼中可能就在意第5個(gè),而***點(diǎn)估計(jì)在他們眼中連前三都進(jìn)不了。
看到這個(gè),ehwizard同學(xué)不認(rèn)同了(這是從道德層面上質(zhì)疑?。?,他表示10gen絕不是像作者說(shuō)的那樣,他說(shuō)你可以看一下我們bug修復(fù)的列表,這些都是公開(kāi)的,我們從來(lái)沒(méi)有說(shuō)偷偷的改掉某個(gè)bug了事,或者說(shuō)只跟一些特殊用戶說(shuō)明這些bug。如果我們真的那么在意讀寫(xiě)性能,我們?cè)缇托迯?fù)了那些浪費(fèi)CPU的問(wèn)題了。如果我們真的那么在意benchmark的話,我們?cè)缇蛢?yōu)化了全局鎖的問(wèn)題了,這東西對(duì)多線程的benchmark結(jié)果是有非常大的改進(jìn)的。更何況一般的benchmark都是多線程跑的,我們并不那么在意benchmark的數(shù)據(jù)。(我的benchmark已經(jīng)很牛X的好不好)
MongoDB確實(shí)還很新,還有很多問(wèn)題。如果你想來(lái)跟我們討論一些MongoDB相關(guān)的問(wèn)題,我們的的辦公室為你敞開(kāi),我們會(huì)以非常開(kāi)放的態(tài)度對(duì)待你提出的問(wèn)題,所以如果真的有問(wèn)題,我們非常期待與你的溝通。
【編輯推薦】