天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

視覺中國(guó)的NoSQL之路:從MySQL到MongoDB

  起因

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

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

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

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

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

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

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

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

  候選方案

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

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

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

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

  為什么MongoDB可以替代MySQL?

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

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

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

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

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

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

圖2 MongoDB支持嵌入子文檔

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

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

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

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

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

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

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

  Replica Pairs/Replica Sets允許2個(gè)MongoDB相互監(jiān)聽,實(shí)現(xiàn)雙機(jī)互備的容錯(cuò)。

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

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

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

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

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

  實(shí)施結(jié)果

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

  一些小提示

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

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

  結(jié)束語(yǔ)

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

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

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

  作者簡(jiǎn)介:

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

it知識(shí)庫(kù)視覺中國(guó)的NoSQL之路:從MySQL到MongoDB,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 日日噜噜夜夜爽爽 | 亚洲日韩欧美国产专区 | 国产成人精品一区二区三区视频 | 97视频国产 | 亚洲国产精品第一影院在线观看 | 久久精品热老司机 | 久久久伊人影院 | 亚洲色婷婷久久精品AV蜜桃 | 欧美GV肉片视频免费观看 | 久久精品视在线-2 | 亚洲国产在线观看免费视频 | 在线视频久久只有精品第一日韩 | 成人综合在线视频免费观看完整版 | 吃奶摸下的羞羞漫画 | 牛牛在线视频 | 天天久久影视色香综合网 | 久久九九有精品国产23百花影院 | 亚洲国产中文在线视频 | 教室里的激情电影 | 精品久久久久久综合网 | 无码区国产区在线播放 | 久久久久久久久人体 | 乱码中字在线观看一二区 | 欧美黑人巨大videos免费 | 男人国产AV天堂WWW麻豆 | 忘忧草在线社区WWW日本直播 | 国产美女久久久久久久久久久 | 飘雪在线观看免费高清完整版韩国 | 国产精品伦理一二三区伦理 | 欧美影院在线观看完整版 mp4 | 亚洲精品日韩在线观看视频 | 手机免费毛片 | 妇少水多18P蜜泬17P亚洲乱 | YY8090福利午夜理论片 | 被窝伦理午夜电影网 | 99视频网站| 国产电影午夜成年免费视频 | 九九影院午夜理论片无码 | 丝袜美腿美女被狂躁在线观看 | 国产 亚洲 另类 欧美 在线 | 精品美女国产互换人妻 |