九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
視覺中國的NoSQL之路:從MySQL到MongoDB

文 /  潘凡

起因

網(wǎng)站(www.chinavisual.com)是國內(nèi)最大的創(chuàng)意人群的專業(yè)網(wǎng)站。2009年以前,同很多公司一樣,我們的CMS和社區(qū)產(chǎn)品都構(gòu)建于PHP+Nginx+MySQL之上;MySQL使用了Master+Master的部署方案;前端使用自己的PHP框架進行開發(fā);Memcached作為緩存;Nginx進行Web服務(wù)和負(fù)載均衡;Gearman進行異步任務(wù)處理。在傳統(tǒng)的基于靜態(tài)內(nèi)容(如文章,資訊,帖子)的產(chǎn)品,這個體系運行良好。通過分級的緩存,數(shù)據(jù)庫端實際負(fù)載很輕。2009年初,我們進行了新產(chǎn)品的開發(fā)。此時,我們遇到了如下一些問題。

用戶數(shù)據(jù)激增:我們的MySQL某個信息表上線1個月的數(shù)據(jù)就達到千萬。我們之前忽略的很多數(shù)據(jù),在新形勢下需要跟蹤記錄,這也導(dǎo)致了數(shù)據(jù)量的激增;

用戶對于信息的實時性要求更高:對信息的響應(yīng)速度和更新頻度就要求更高。簡單通過緩存解決的靈丹妙藥不復(fù)存在;

對于Scale-out的要求更高:有些創(chuàng)新產(chǎn)品的增長速度是驚人的。因此要求能夠無痛的升級擴展,否則一旦停機,那么用戶流失的速度也是驚人的;

大量文件的備份工作:我們面向的是創(chuàng)意人群,產(chǎn)生的內(nèi)容是以圖片為主。需要能夠?qū)@些圖片及不同尺寸的縮略圖進行有效的備份管理。我們之前使用的Linux inotify+rsync的增量備份方案效果不佳;

需求變化頻繁:開發(fā)要更加敏捷,開發(fā)成本和維護成本要更低,要能夠快速地更新進化,新功能要在最短的周期內(nèi)上線。

最初,我們試圖完全通過優(yōu)化現(xiàn)有的技術(shù)架構(gòu)來解決以上問題:對數(shù)據(jù)時效性進一步分級分層緩存,減小緩存粒度;改進緩存更新機制(線上實時和線下異步更新)提高緩存命中率;嘗試對業(yè)務(wù)數(shù)據(jù)的特點按照水平和垂直進行分表;使用MogileFS進行分布存儲;進一步優(yōu)化Mysql的性能,同時增加MySQL節(jié)點等。但很快發(fā)現(xiàn),即便實施了上述方案,也很難完全解決存在的問題:過度依賴Memcached導(dǎo)致數(shù)據(jù)表面一致性的維護過于復(fù)雜,應(yīng)用程序開發(fā)需要很小心,很多時候出現(xiàn)Memcached的失效會瞬間導(dǎo)致后端數(shù)據(jù)庫壓力過大;不同類型數(shù)據(jù)的特點不同,數(shù)據(jù)量差別也很大;分表的機制和方式在效率平衡上很難取舍;MogileFS對我們而言是腳小鞋大,維護成本遠(yuǎn)遠(yuǎn)超過了實際的效益;引入更多的MySQL數(shù)據(jù)庫節(jié)點增大了我們的維護量,如何有效監(jiān)控和管理這些節(jié)點又成了新的問題。雖然虛擬化可以解決部分問題,但還是不能令人滿意;

除了MySQL,能否找到一個更為簡單、輕便的瑞士軍刀呢?我們的目光投向了NoSQL的方案。

候選方案

最初,對于NoSQL的候選方案,我依據(jù)關(guān)注和熟悉程度,并且在甄別和選擇合適的方案時特別制定了一些原則:是否節(jié)省系統(tǒng)資源,對于CPU等資源是否消耗過大;客戶端/API支持,這直接影響應(yīng)用開發(fā)的效率;文檔是否齊全,社區(qū)是否活躍;部署是否簡單;未來擴展能力。按以上幾點經(jīng)過一段測試后,我們候選名單中剩下Redis、MongoDB和Flare。

Redis對豐富數(shù)據(jù)類型的操作很吸引人,可以輕松解決一些應(yīng)用場景,其讀寫性能也相當(dāng)高,唯一缺點就是存儲能力和內(nèi)存掛鉤,這樣如果存儲大量的數(shù)據(jù)需要消耗太多的內(nèi)存(最新的版本已經(jīng)不存在這個問題)。

Flare的集群管理能力令人印象深刻,它可以支持節(jié)點的動態(tài)部署,支持節(jié)點的基于權(quán)重的負(fù)載均衡,支持?jǐn)?shù)據(jù)分區(qū)。同時允許存儲大的數(shù)據(jù),其key的長度也不受Memcached的限制。而這些對于客戶端是透明的,客戶端使用Memcached協(xié)議鏈接到Flare的proxy節(jié)點就可以了。由于使用集群,F(xiàn)lare支持fail-over,當(dāng)某個數(shù)據(jù)節(jié)點宕掉,對于這個節(jié)點的訪問都會自動被proxy節(jié)點forward到對應(yīng)的后備節(jié)點,恢復(fù)后還可以自動同步。Flare的缺點是實際應(yīng)用案例較少,文檔較為簡單,目前只在Geek使用。

以上方案都打算作為一個優(yōu)化方案,我從未想過完全放棄MySQL。然而,用MongoDB做產(chǎn)品的設(shè)計原型后,我徹底被征服了,決定全面從MySQL遷移到MongoDB。

為什么MongoDB可以替代MySQL?

MongoDB是一個面向文檔的數(shù)據(jù)庫,目前由10gen開發(fā)并維護,它的功能豐富,齊全,完全可以替代MySQL。在使用MongoDB做產(chǎn)品原型的過程中,我們總結(jié)了MonogDB的一些亮點:

使用JSON風(fēng)格語法,易于掌握和理解:MongoDB使用JSON的變種BSON作為內(nèi)部存儲的格式和語法。針對MongoDB的操作都使用JSON風(fēng)格語法,客戶端提交或接收的數(shù)據(jù)都使用JSON形式來展現(xiàn)。相對于SQL來說,更加直觀,容易理解和掌握。

Schema-less,支持嵌入子文檔:MongoDB是一個Schema-free的文檔數(shù)據(jù)庫。一個數(shù)據(jù)庫可以有多個Collection,每個Collection是Documents的集合。Collection和Document和傳統(tǒng)數(shù)據(jù)庫的Table和Row并不對等。無需事先定義Collection,隨時可以創(chuàng)建。

Collection中可以包含具有不同schema的文檔記錄。 這意味著,你上一條記錄中的文檔有3個屬性,而下一條記錄的文檔可以有10個屬性,屬性的類型既可以是基本的數(shù)據(jù)類型(如數(shù)字、字符串、日期等),也可以是數(shù)組或者散列,甚至還可以是一個子文檔(embed document)。這樣,可以實現(xiàn)逆規(guī)范化(denormalizing)的數(shù)據(jù)模型,提高查詢的速度。

圖1 MongoDB是一個Schema-free的文檔數(shù)據(jù)庫

圖2是一個例子,作品和評論可以設(shè)計為一個collection,評論作為子文檔內(nèi)嵌在art的comments屬性中,評論的回復(fù)則作為comment子文檔的子文檔內(nèi)嵌于replies屬性。按照這種設(shè)計模式,只需要按照作品id檢索一次,即可獲得所有相關(guān)的信息了。在MongoDB中,不強調(diào)一定對數(shù)據(jù)進行Normalize ,很多場合都建議De-normalize,開發(fā)人員可以扔掉傳統(tǒng)關(guān)系數(shù)據(jù)庫各種范式的限制,不需要把所有的實體都映射為一個Collection,只需定義最頂級的class。MongoDB的文檔模型可以讓我們很輕松就能將自己的Object映射到collection中實現(xiàn)存儲。

圖2 MongoDB支持嵌入子文檔

簡單易用的查詢方式:MongoDB中的查詢讓人很舒適,沒有SQL難記的語法,直接使用JSON,相當(dāng)?shù)闹庇^。對不同的開發(fā)語言,你可以使用它最基本的數(shù)組或散列格式進行查詢。配合附加的operator,MongoDB支持范圍查詢,正則表達式查詢,對子文檔內(nèi)屬性的查詢,可以取代原來大多數(shù)任務(wù)的SQL查詢。

CRUD更加簡單,支持in-place update:只要定義一個數(shù)組,然后傳遞給MongoDB的insert/update方法就可自動插入或更新;對于更新模式,MongoDB支持一個upsert選項,即:“如果記錄存在那么更新,否則插入”。MongoDB的update方法還支持Modifier,通過Modifier可實現(xiàn)在服務(wù)端即時更新,省去客戶端和服務(wù)端的通訊。這些modifer可以讓MongoDB具有和Redis、Memcached等KV類似的功能:較之MySQL,MonoDB更加簡單快速。Modifier也是MongoDB可以作為對用戶行為跟蹤的容器。在實際中使用Modifier來將用戶的交互行為快速保存到MongoDB中以便后期進行統(tǒng)計分析和個性化定制。

所有的屬性類型都支持索引,甚至數(shù)組:這可以讓某些任務(wù)實現(xiàn)起來非常的輕松。在MongoDB中,“_id”屬性是主鍵,默認(rèn)MongoDB會對_id創(chuàng)建一個唯一索引。

服務(wù)端腳本和Map/Reduce:MongoDB允許在服務(wù)端執(zhí)行腳本,可以用Javascript編寫某個函數(shù),直接在服務(wù)端執(zhí)行,也可以把函數(shù)的定義存儲在服務(wù)端,下次直接調(diào)用即可。MongoDB不支持事務(wù)級別的鎖定,對于某些需要自定義的“原子性”操作,可以使用Server side腳本來實現(xiàn),此時整個MongoDB處于鎖定狀態(tài)。Map/Reduce也是MongoDB中比較吸引人的特性。Map/Reduce可以對大數(shù)據(jù)量的表進行統(tǒng)計、分類、合并的工作,完成原先SQL的GroupBy等聚合函數(shù)的功能。并且Mapper和Reducer的定義都是用Javascript來定義服務(wù)端腳本。

性能高效,速度快: MongoDB使用c++/boost編寫,在多數(shù)場合,其查詢速度對比MySQL要快的多,對于CPU占用非常小。部署也很簡單,對大多數(shù)系統(tǒng),只需下載后二進制包解壓就可以直接運行,幾乎是零配置。

支持多種復(fù)制模式: MongoDB支持不同的服務(wù)器間進行復(fù)制,包括雙機互備的容錯方案。

Master-Slave是最常見的。通過Master-Slave可以實現(xiàn)數(shù)據(jù)的備份。在我們的實踐中,我們使用的是Master-Slave模式,Slave只用于后備,實際的讀寫都是從Master節(jié)點執(zhí)行。

Replica Pairs/Replica Sets允許2個MongoDB相互監(jiān)聽,實現(xiàn)雙機互備的容錯。

MongoDB只能支持有限的雙主模式(Master-Master),實際可用性不強,可忽略。

內(nèi)置GridFS,支持大容量的存儲:這個特點是最吸引我眼球的,也是讓我放棄其他NoSQL的一個原因。GridFS具體實現(xiàn)其實很簡單,本質(zhì)仍然是將文件分塊后存儲到files.file和files.chunk 2個collection中,在各個主流的driver實現(xiàn)中,都封裝了對于GridFS的操作。由于GridFS自身也是一個Collection,你可以直接對文件的屬性進行定義和管理,通過這些屬性就可以快速找到所需要的文件,輕松管理海量的文件,無需費神如何hash才能避免文件系統(tǒng)檢索性能問題, 結(jié)合下面的Auto-sharding,GridFS的擴展能力是足夠我們使用了。在實踐中,我們用MongoDB的GridFs存儲圖片和各種尺寸的縮略圖。

圖3 MongoDB的Auto-sharding結(jié)構(gòu)

內(nèi)置Sharding,提供基于Range的Auto Sharding機制:一個collection可按照記錄的范圍,分成若干個段,切分到不同的Shard上。Shards可以和復(fù)制結(jié)合,配合Replica sets能夠?qū)崿F(xiàn)Sharding+fail-over,不同的Shard之間可以負(fù)載均衡。查詢是對客戶端是透明的。客戶端執(zhí)行查詢,統(tǒng)計,MapReduce等操作,這些會被MongoDB自動路由到后端的數(shù)據(jù)節(jié)點。這讓我們關(guān)注于自己的業(yè)務(wù),適當(dāng)?shù)臅r候可以無痛的升級。MongoDB的Sharding設(shè)計能力最大可支持約20 petabytes,足以支撐一般應(yīng)用。

第三方支持豐富: MongoDB社區(qū)非常活躍,很多開發(fā)框架都迅速提供了對MongDB的支持。不少知名大公司和網(wǎng)站也在生產(chǎn)環(huán)境中使用MongoDB,越來越多的創(chuàng)新型企業(yè)轉(zhuǎn)而使用MongoDB作為和Django,RoR來搭配的技術(shù)方案。

實施結(jié)果

實施MonoDB的過程是令人愉快的。我們對自己的PHP開發(fā)框架進行了修改以適應(yīng)MongoDB。在PHP中,對MongoDB的查詢、更新都是圍繞Array進行的,實現(xiàn)代碼變得很簡潔。由于無需建表,MonoDB運行測試單元所需要的時間大大縮短,對于TDD敏捷開發(fā)的效率也提高了。當(dāng)然,由于MongoDB的文檔模型和關(guān)系數(shù)據(jù)庫有很大不同,在實踐中也有很多的困惑,幸運的是,MongoDB開源社區(qū)給了我們很大幫助。最終,我們使用了2周就完成了從MySQL到MongoDB的代碼移植比預(yù)期的開發(fā)時間大大縮短。從我們的測試結(jié)果看也是非常驚人,數(shù)據(jù)量約2千萬,數(shù)據(jù)庫300G的情況下,讀寫2000rps,CPU等系統(tǒng)消耗是相當(dāng)?shù)牡停ㄎ覀兊臄?shù)據(jù)量還偏小,目前陸續(xù)有些公司也展示了他們的經(jīng)典案例:MongoDB存儲的數(shù)據(jù)量已超過 50億,>1.5TB)。目前,我們將MongoDB和其他服務(wù)共同部署在一起,大大節(jié)約了資源。

一些小提示

切實領(lǐng)會MongoDB的Document模型,從實際出發(fā),扔掉關(guān)系數(shù)據(jù)庫的范式思維定義,重新設(shè)計類;在服務(wù)端運行的JavaScript代碼避免使用遍歷記錄這種耗時的操作,相反要用Map/Reduce來完成這種表數(shù)據(jù)的處理;屬性的類型插入和查詢時應(yīng)該保持一致。若插入時是字符串“1”,則查詢時用數(shù)字1是不匹配的;優(yōu)化MongoDB的性能可以從磁盤速度和內(nèi)存著手;MongoDB對每個Document的限制是最大不超過4MB;在符合上述條件下多啟用Embed Document, 避免使用DatabaseReference;內(nèi)部緩存可以避免N+1次查詢問題(MongoDB不支持joins)。

用Capped Collection解決需要高速寫入的場合,如實時日志;大數(shù)據(jù)量情況下,新建同步時要調(diào)高oplogSize的大小,并且自己預(yù)先生成數(shù)據(jù)文件,避免出現(xiàn)客戶端超時;Collection+Index合計數(shù)量默認(rèn)不能超過24000;當(dāng)前版本(<v1.6)刪除數(shù)據(jù)的空間不能被回收,如果你頻繁刪除數(shù)據(jù),那么需要定期執(zhí)行repairDatabase,釋放這些空間。

結(jié)束語

MongoDB的里程碑是1.6版本,預(yù)計今年7月份發(fā)布,屆時,MongoDB的Sharding將首次具備在生產(chǎn)環(huán)境中使用的條件。作為MongoDB的受益者,我們目前也在積極參與MongoDB社區(qū)活動,改進Perl/PHP對于MongoDB的技術(shù)方案。在1.6版本后也將年內(nèi)推出基于MongoDB的一些開源項目。

對于那些剛剛起步,或者正在開發(fā)創(chuàng)新型互聯(lián)網(wǎng)應(yīng)用的公司來說,MongoDB的快速、靈活、輕量和強大擴展性,正適合我們快速開發(fā)產(chǎn)品,快速迭代,適應(yīng)用戶迅速變化和更新的種種需求。

總而言之,MongoDB是一個最適合替代MySQL的全功能的NoSQL產(chǎn)品,使用MongoDB+Perl/PHP/Django/RoR的組合將很快成為開發(fā)Web2.0、3.0的產(chǎn)品的最佳組合,就像當(dāng)年MySQL替代Oracle/DB2/Informix一樣,歷史總是驚人的相似,讓我們拭目以待吧!

作者簡介:

潘凡(nightsailer,N.S.), 網(wǎng)站技術(shù)總監(jiān),聯(lián)合創(chuàng)始人,家有1狗2貓。目前負(fù)責(zé)網(wǎng)站平臺設(shè)計和底層產(chǎn)品研發(fā)工作。當(dāng)前關(guān)注:Apps平臺設(shè)計、分布式文件存儲、NoSQL、高性能后現(xiàn)代的Perl編程。Twitter:@nightsailer  Blog:http://nightsailer.com/

(本文來自《程序員》雜志10年06期)

《程序員》10月刊最新上市:http://www.programmer.com.cn/4128/
《程序員》訂閱:http://dingyue.programmer.com.cn/

3 Responses to “的NoSQL之路:從MySQL到MongoDB”

  1. a 說:

    MongoDB占內(nèi)存實在太大,在不改官方代碼的前提下有沒有好辦法解決?

  2. elvis 說:

    如果可能,說說mongodb的缺點吧。它又如何取代關(guān)系型的東西。我們也做了一些測試。性能還是不錯的。但取代關(guān)系型。似乎是兩碼事。我們的應(yīng)用都是兩者結(jié)合的。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
mongodb與mysql相比的優(yōu)缺點(轉(zhuǎn))
為什么 MongoDB 使用 B 樹?
淺析MongoDB數(shù)據(jù)庫的海量數(shù)據(jù)存儲應(yīng)用
一文讀懂 MongoDB 和 MySQL 的差異
什么是集群,集群的概念介紹
詳解mongodb——架構(gòu)模式、持久化原理和數(shù)據(jù)文件存儲原理 值得收藏
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服