首先應(yīng)該說的是:所有天上飛的理念都會有落地實(shí)現(xiàn)。所以我覺得還是從數(shù)據(jù)存儲處理的發(fā)展簡史來引入NoSQL更為貼切,也能讓自己有更細(xì)致的認(rèn)識。
數(shù)據(jù)存儲與處理技術(shù)的發(fā)展有這么幾個(gè)時(shí)間跨度
1.單機(jī)MySQL的美好時(shí)代
2.Memcached(緩存)+MySQL+垂直分離
3.MySQL主從讀寫分離
4.分庫分表+水平拆分+mysql集群
5.MySQL的擴(kuò)展性瓶頸
6.今天的架構(gòu)
7.為什么使用NoSQL
1.單機(jī)MySQL的美好時(shí)代
在90年代,一個(gè)網(wǎng)站的訪問量并不大,用單個(gè)數(shù)據(jù)庫完全可以輕松應(yīng)對,那個(gè)時(shí)候,更多的都是靜態(tài)網(wǎng)頁,動態(tài)交互型的網(wǎng)站并不多。
網(wǎng)站的架構(gòu)設(shè)計(jì)如下圖所示:

大學(xué)期間我們大都用的是這個(gè)簡單原始的架構(gòu)來做網(wǎng)站,在數(shù)據(jù)量不是很大的情況下,是完全應(yīng)付的來的。
那么上述架構(gòu)能帶來什么問題呢?
1.數(shù)據(jù)量太大,一個(gè)機(jī)器放不下時(shí)。
MySQL5.7單表500w數(shù)量已經(jīng)很棒,但是300w時(shí)就應(yīng)該優(yōu)化了。
2.數(shù)據(jù)的索引(B+Tree)一個(gè)機(jī)器的內(nèi)存放不下時(shí)。
索引是加速數(shù)據(jù)庫訪問效率的一種機(jī)制,但是索引是存儲在內(nèi)存當(dāng)中的,如果數(shù)據(jù)量太大,那么意味著內(nèi)存中存儲的索引也會很大,在每一次加入數(shù)據(jù)的時(shí)候,數(shù)據(jù)庫都需要維持索引,這樣假設(shè)索引跟數(shù)據(jù)量同處一個(gè)機(jī)器,而不做優(yōu)化,那么數(shù)據(jù)訪問將非常之緩慢。
3.訪問量(讀寫混合)一個(gè)實(shí)例并不能承受。
如果滿足不了上述當(dāng)中的1-3個(gè),請演化。
2.Memcached(緩存)+MySQL+垂直分離
2.1 Memcached(緩存)
隨著訪問量的上升,幾乎大部分使用MySQL架構(gòu)的網(wǎng)站在數(shù)據(jù)庫上都出現(xiàn)了性能問題,web程序不再僅僅關(guān)注在功能上,同時(shí)也開始追求性能,程序員們開始大量的使用緩存技術(shù)來緩解數(shù)據(jù)庫的壓力,優(yōu)化數(shù)據(jù)庫的結(jié)構(gòu)和索引,開始比較流行的是通過文件緩存來緩解數(shù)據(jù)庫的壓力,但是當(dāng)訪問量繼續(xù)增大的時(shí)候,多臺web服務(wù)器通過文件緩存不能共享,大量的小文件緩存也帶來了比較高的IO壓力,在這個(gè)時(shí)候,Memcached(緩存)自然成為一個(gè)非常時(shí)尚的技術(shù)產(chǎn)品。
緩存的實(shí)質(zhì)是替數(shù)據(jù)庫擋了一層。
頻繁被訪問的數(shù)據(jù)可以被放置于緩存當(dāng)中,以供頻繁訪問。
架構(gòu)圖如下所示:

2.2 垂直拆分
什么是垂直拆分?
舉個(gè)例子,淘寶的數(shù)據(jù)庫服務(wù)器是要進(jìn)行定性 的,比如說有四臺數(shù)據(jù)庫服務(wù)器,兩臺進(jìn)行買家數(shù)據(jù)的存儲,兩臺進(jìn)行賣家數(shù)據(jù)的存儲,將原本一臺數(shù)據(jù)庫實(shí)例需要做的事情,均攤給四臺服務(wù)器。DB數(shù)據(jù)操作能力會有很大提升。
3. MySQL主從讀寫分離
1 什么是主從復(fù)制?
多搞幾個(gè)數(shù)據(jù)庫來存儲數(shù)據(jù),假設(shè)有三臺數(shù)據(jù)庫,一主二仆,即一臺主服務(wù)器,兩臺從服務(wù)器,當(dāng)新增數(shù)據(jù)至主數(shù)據(jù)庫服務(wù)器的時(shí)候,那么同時(shí)復(fù)制此數(shù)據(jù)進(jìn)入到從數(shù)據(jù)庫服務(wù)器當(dāng)中。數(shù)據(jù)復(fù)制是為了容災(zāi)備份,緩存?zhèn)浞荩WC數(shù)據(jù)的完整性。
2 什么是讀寫分離?
增刪改是寫,查為讀。
讀就去職能為被查詢的數(shù)據(jù)庫服務(wù)器去讀。
寫就去職能為寫數(shù)據(jù)的數(shù)據(jù)庫服務(wù)器去寫。
分工明確,結(jié)合緩存能實(shí)現(xiàn)性能的一大提升
架構(gòu)圖如下所示:

其中的M是master 即主DB Server ,S為slaver即從屬DB Server,各有分工。
寫操作在 M,讀操作在S。S的數(shù)據(jù)是從master方復(fù)制的。
4.分庫分表+水平拆分+MySQL集群
承接主從復(fù)制,讀寫分離,以及Memcached的使用,這時(shí)MySQL主庫的寫壓力開始出現(xiàn)瓶頸,而數(shù)據(jù)量的持續(xù)猛增,由于MYISAM使用表鎖,在高并發(fā)下會出現(xiàn)嚴(yán)重的鎖問題,大量的高并發(fā)MySQL應(yīng)用開始使用InnoDB引擎代替MYISAM,由于數(shù)據(jù)量的指數(shù)級增長,只能繼續(xù)對架構(gòu)進(jìn)行演變。
與此同時(shí),開始流行使用分庫分表來緩解寫壓力和數(shù)據(jù)增長的擴(kuò)展問題。這個(gè)時(shí)候,MySQL推出了還不太穩(wěn)定的表分區(qū),這也給技術(shù)實(shí)力一般的公司帶來了希望。雖然MySQL推出了MySQL cluster集群,單性能也不能很好的滿足互聯(lián)網(wǎng)的要求,知識在高可靠性上提供了非常大的保證。
1 基本思想之什么是分庫分表?
從字面上簡單理解,就是把原本存儲于一個(gè)庫的數(shù)據(jù)分塊存儲到多個(gè)庫上,把原本存儲于一個(gè)表的數(shù)據(jù)分塊存儲到多個(gè)表上。
2 基本思想之為什么要分庫分表?
數(shù)據(jù)庫中的數(shù)據(jù)量不一定是可控的,在未進(jìn)行分庫分表的情況下,隨著時(shí)間和業(yè)務(wù)的發(fā)展,庫中的表會越來越多,表中的數(shù)據(jù)量也會越來越大,相應(yīng)地,數(shù)據(jù)操作,增刪改查的開銷也會越來越大;另外,由于無法進(jìn)行分布式式部署,而一臺服務(wù)器的資源(CPU、磁盤、內(nèi)存、IO等)是有限的,最終數(shù)據(jù)庫所能承載的數(shù)據(jù)量、數(shù)據(jù)處理能力都將遭遇瓶頸。
3 分庫分表的實(shí)施策略。
分庫分表有垂直切分和水平切分兩種。
3.1 何謂垂直切分:
即將表按照功能模塊、關(guān)系密切程度劃分出來,部署到不同的庫上。例如,我們會建立定義數(shù)據(jù)庫workDB、商品數(shù)據(jù)庫payDB、用戶數(shù)據(jù)庫userDB、日志數(shù)據(jù)庫logDB等,分別用于存儲項(xiàng)目數(shù)據(jù)定義表、商品定義表、用戶數(shù)據(jù)表、日志數(shù)據(jù)表等。
3.2 何謂水平切分:
當(dāng)一個(gè)表中的數(shù)據(jù)量過大時(shí),我們可以把該表的數(shù)據(jù)按照某種規(guī)則,例如userID散列,進(jìn)行劃分,然后存儲到多個(gè)結(jié)構(gòu)相同的表,和不同的庫上。例如,我們的userDB中的用戶數(shù)據(jù)表中,每一個(gè)表的數(shù)據(jù)量都很大,就可以把userDB切分為結(jié)構(gòu)相同的多個(gè)userDB:part0DB、part1DB等,再將userDB上的用戶數(shù)據(jù)表userTable,切分為很多userTable:userTable0、userTable1等,然后將這些表按照一定的規(guī)則存儲到多個(gè)userDB上。
5.MySQL的擴(kuò)展性瓶頸
視頻、圖片大數(shù)據(jù)量的數(shù)據(jù)時(shí)不能存儲到數(shù)據(jù)庫當(dāng)中的,假設(shè)一個(gè)視頻1.8G,MySQL中肯定是不能進(jìn)行存儲的。
下圖是淘寶分享出來的一種架構(gòu)方式:


6.今天的架構(gòu)
答案就是NoSQL。
NoSQL(NoSQL = Not Only SQL),意為"不僅僅是SQL"。泛指非關(guān)系型數(shù)據(jù)庫。隨著互聯(lián)網(wǎng)2.0網(wǎng)站的興起,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫在應(yīng)付web2.0網(wǎng)站,特別是超大規(guī)模和高并發(fā)的SNS類型的web2.0動態(tài)網(wǎng)站已經(jīng)顯得力不從心,暴露了很多難以克服的問題,而非關(guān)系型數(shù)據(jù)庫則由于其本身的特點(diǎn)得到了非常迅速的發(fā)展。NoSQL數(shù)據(jù)庫的產(chǎn)生就是為了解決大規(guī)模數(shù)據(jù)集合以及多中數(shù)據(jù)帶來的挑戰(zhàn),尤其是大數(shù)據(jù)應(yīng)用難題,包括大規(guī)模數(shù)據(jù)的存儲。
例如:谷歌活著Facebook每天為他們的用戶收集萬億比特的數(shù)據(jù)。這些數(shù)據(jù)的存儲不需要固定的模式,無需多余的操作就可以橫向擴(kuò)展。
下一節(jié)繼續(xù)!
博客搬家:大坤的個(gè)人博客
歡迎評論哦~