|
最近聽說了很多關(guān)于NoSQL的新聞,比如之前Sourceforge改用MongoDB,Digg改用Cassandra等等。再加上之前做數(shù)據(jù)庫比較時有人推薦我mongodb,所以也搜索了一下NoSQL,覺得NoSQL可能真的是未來的趨勢。
NoSQL vs SQL
傳統(tǒng)SQL數(shù)據(jù)庫為了實現(xiàn)ACID(atomicity, consistency, isolation, durability),往往需要頻繁應(yīng)用文件鎖,這使得其在現(xiàn)代的Web2.0應(yīng)用中越來越捉襟見肘。現(xiàn)在SNS網(wǎng)站每一個點擊都是一條/多條查詢,對數(shù)據(jù)庫寫的并發(fā)要求非常之高,而傳統(tǒng)數(shù)據(jù)庫無法很好地應(yīng)對這種需求。而仔細(xì)想來SNS中大部分需求并不要求ACID,比如Like/Unlike投票等等。
NoSQL吸取了教訓(xùn),比如有些NoSQL采用了eventually consistency的概念,在沒有Update操作一段時間后,數(shù)據(jù)庫將最終是consistency的,顯然這樣的數(shù)據(jù)庫將能更好的支持高并發(fā)讀寫。
SQL數(shù)據(jù)庫是基于schema的,這對時時刻刻更新著的Web2.0應(yīng)用開發(fā)者來說是個噩夢:隨時隨地有新的應(yīng)用出現(xiàn),舊的數(shù)據(jù)庫無法適應(yīng)新的應(yīng)用,只能不停地更新schema,或者做補(bǔ)丁表,如此一來要么schema越發(fā)混亂,要么就是數(shù)據(jù)庫頻繁升級而耗時耗力耗錢。
NoSQL一般就沒有schema這種概念,大部分NoSQL都直接保存json類的Row,比如一個記錄可以是{ id = 1, name = Bob, phone = 38492839 },這樣擴(kuò)展升級非常方便,比如需要地址信息直接加入 address=blahblah 即可。
傳統(tǒng)SQL很難進(jìn)行分布式應(yīng)用,即使可以也往往代價高昂。而NoSQL則很好地解決了這個問題:他們一般都直接從分布式系統(tǒng)中吸取了Map/Reduce方法,從而很容易就可以處理規(guī)模急速增加的問題。
推薦robbin牛的NoSQL數(shù)據(jù)庫探討之一 - 為什么要用非關(guān)系數(shù)據(jù)庫?一文,介紹了主流的一些NoSQL系統(tǒng),還有這個站http://nosql-database.org/收集了基本上目前所有的NoSQL系統(tǒng)。
總結(jié)一下我對NoSQL的看法,NoSQL出現(xiàn)的目的就是為了解決高并發(fā)讀寫的問題,而高并發(fā)應(yīng)用往往需要分布式的數(shù)據(jù)庫來實現(xiàn)高性能和高可靠性,所以NoSQL的關(guān)鍵字就是concurrency和Scalability。
我的瓶頸
我之前主要關(guān)注數(shù)據(jù)庫的select性能也就是read性能,在讀性能方面SQL數(shù)據(jù)庫并沒有明顯的劣勢,應(yīng)該說純粹高并發(fā)讀的性能的話往往要優(yōu)于NoSQL數(shù)據(jù)庫,然而一旦涉及寫,事情就不一樣了。
我本來以為自己不會遇到大量寫的問題,后來發(fā)現(xiàn)即使在simplecd這種簡單的應(yīng)用環(huán)境下也會產(chǎn)生大量的并發(fā)寫:這就是爬VC用戶評論的時候。事實上,sqlite3在處理這個問題上非常的力不從心,所以我產(chǎn)生了換個數(shù)據(jù)庫的想法。
既然我是要求能高并發(fā)讀寫,干脆就不用SQL了,但是同時我也想測試一下其他SQL的寫性能。
我的數(shù)據(jù)有180萬條,總共350M,測試用了10個線程,每個線程做若干次100個數(shù)據(jù)的bulk寫入,然后記錄總共耗時。結(jié)果如下:
innodb: 15.19
myiasm: 14.34
pgsql: 23.41
sqlite3: 鎖住了
sqlite3(單線程): 300+
mongodb: 3.82
couchdb: 90
couchdb(單線程):66
作為一個MySQL黑,看到這組測試數(shù)據(jù)我表示壓力很大。在SQL數(shù)據(jù)庫中,mysql意外地取得了最佳的成績,好于pgsql,遠(yuǎn)好于sqlite。更令人意外的是myisam居然優(yōu)于號稱insert比較快的innodb。不管如何,對我的應(yīng)用來說,用mysql保存評論數(shù)據(jù)是一個更為明智的選擇。我對mysql徹底改觀了,我宣布我是mysql半黑。以后select-intensive的應(yīng)用我還是會選擇sqlite,但是insert/update-intensive的應(yīng)用我就會改用mysql了。
MongoDB和CouchDB同為NoSQL,表現(xiàn)卻截然相反,MongoDB性能很高,CouchDB的并發(fā)性能我只能ORZ,這種性能實在太抱歉了。
NoSQL的碎碎念
其實我本來還打算測試cassandra的,可是cassandra用的是Java,這首先讓我眉頭一皺,內(nèi)存大戶我養(yǎng)不起啊,其次看了cassandra的文檔,立刻崩潰,這簡直就是沒有文檔么。(BTW,CouchDB也好不到哪里去,我都是用Python-couchdb然后help(couchdb.client)看用法的)
至于CouchDB,可能是因為采用http方式發(fā)送請求,所以并發(fā)性能糟糕的一塌糊涂,很懷疑它是否有存在的理由。
MongoDB是我用下來最討人喜歡的一個NoSQL。不但文檔豐富,使用簡單,性能也非常好,它的Map/Reduce查詢(很多NoSQL都有)讓我驚嘆,數(shù)據(jù)庫可以非常簡單地就擴(kuò)大規(guī)模,完全不用理會什么分區(qū)分表之類繁瑣的問題,可惜這方面我暫時沒有需求。但是MongoDB有兩大致命問題。
第一是刪除鎖定問題,當(dāng)批量刪除記錄時,數(shù)據(jù)庫還是會鎖定不讓讀寫。這意味著進(jìn)行數(shù)據(jù)清理時會讓網(wǎng)站應(yīng)用失去響應(yīng)。見locking problems
第二是內(nèi)存占用問題,MongoDB用了操作系統(tǒng)的內(nèi)存文件映射,這導(dǎo)致操作系統(tǒng)會把所有空閑內(nèi)存都分配給MongoDB,當(dāng)MongoDB有這個需要時。更可怕的是,MongoDB從來不主動釋放已經(jīng)霸占的內(nèi)存,它只會滾雪球一樣越滾越大,除非重啟數(shù)據(jù)庫。這樣的上下文環(huán)境下,MongoDB只適合一臺主機(jī)就一個數(shù)據(jù)庫,而沒有其他應(yīng)用的環(huán)境,否則一會兒功夫MongoDB就會吃光內(nèi)存,然后你都fork不出新進(jìn)程,徹底悲劇。見memory limit
總之NoSQL雖然讓我眼前一亮,可是目前嘗試的一些產(chǎn)品都讓人望而生畏,現(xiàn)在的NoSQL都把目光放在了巨型網(wǎng)站上,而沒有一個小型的,可以在VPS里面應(yīng)用的高性能NoSQL,令我有點失望。NoSQL尚未成熟,很期待它的將來發(fā)展,目前來說MySQL還是更好的選擇。
it知識庫:SQL vs NoSQL:數(shù)據(jù)庫并發(fā)寫入性能比拼,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。