3.1 來自海豚的告白
3.2 單節(jié)點(diǎn)數(shù)據(jù)庫
3.3 一主一從架構(gòu)
3.4 Master/Slave 復(fù)制原理及方式
3.5 一主多從架構(gòu)
3.6 雙主多從架構(gòu)
3.7 Mysql Sharding
3.8 小張講解
3.9 課后作業(yè)
3.1 來自海豚的告白
"我是一只海豚,我很孤獨(dú),我遨游在我的世界里,有很多人喜歡我,也有很多人厭惡我,可是,我還是我。"
這是一只Mysql 海豚的獨(dú)白。

他是那么的清高,那么的傲慢,好像動物世界里的一朵奇葩,正是因為他的輕盈、他的開放,即使他這樣傲慢無理,
還是有很多粉絲的追捧。
幾乎大部分的互聯(lián)網(wǎng)公司都會選用Mysql做為數(shù)據(jù)庫,體現(xiàn)在它的擴(kuò)展性,mysql 可以架構(gòu)出一個分布式集群,
相對于oracle 這種大型數(shù)據(jù)庫來說,他顯得靈活,輕盈,而且他還是開源免費(fèi)的。
為什么mysql 在互聯(lián)網(wǎng)公司那么受到青睞, 因為互聯(lián)網(wǎng)公司相對于傳統(tǒng)企業(yè)來說,他的數(shù)據(jù)量增長的很快,單點(diǎn)數(shù)據(jù)庫
已經(jīng)無法滿足數(shù)據(jù)的實(shí)時查詢和存儲的要求了,所以需要擴(kuò)展數(shù)據(jù)庫架構(gòu)。
Mysql數(shù)據(jù)庫架構(gòu)的演化分為幾個階段:
單節(jié)點(diǎn)數(shù)據(jù)庫

一主一從架構(gòu)

一主多從架構(gòu)

雙主多從架構(gòu)

對比上面的架構(gòu)圖,來具體看看這幾種架構(gòu)的區(qū)別。
3.2 單節(jié)點(diǎn)數(shù)據(jù)庫
大部分的童鞋接觸到的都是這種單節(jié)點(diǎn)的數(shù)據(jù)庫架構(gòu),
一個JAVA程序使用數(shù)據(jù)庫連接池操作一個數(shù)據(jù)庫,這個是不是很熟悉,就是J2EE的典型應(yīng)用。
上點(diǎn)代碼看看,更熟悉一點(diǎn)

架構(gòu)上面來說就是 一個應(yīng)用連接一個數(shù)據(jù)庫 ,十分簡單,也就不多說了,如下圖:

3.3 一主一從架構(gòu)
隨著互聯(lián)網(wǎng)訪問量的迅速增加、以及數(shù)據(jù)量的增大,單點(diǎn)數(shù)據(jù)庫會出現(xiàn)延遲,假死,更嚴(yán)重的出現(xiàn)崩潰的情況,在用戶端看到的現(xiàn)象會是這樣的

這種情況下,數(shù)據(jù)庫已經(jīng)負(fù)擔(dān)不起這么大的壓力了,海豚自恃清高也沒用,于是有人想出用兩個海豚來解決這個問題,最簡單的就是這種一主一從的架構(gòu)

為什么要這樣子來架構(gòu)呢?
這樣我們先來分析一下 造成系統(tǒng)性能的瓶頸在哪里
從硬件計算機(jī)系統(tǒng)來說 , 系統(tǒng)的性能主要取決于
CPU, 內(nèi)存, 磁盤I/O, 網(wǎng)絡(luò)I/O




再仔細(xì)分析
內(nèi)存的 讀寫速度 是 24165M/s
機(jī)械硬盤的讀寫速度 在100M/s
網(wǎng)絡(luò)帶寬一般機(jī)房可以到 千兆帶寬
很明顯我們可以看出, 硬盤的讀寫速度跟內(nèi)存 相差200多倍
很容易找出,我們系統(tǒng)的瓶頸在硬盤讀寫這一塊,當(dāng)然這里只是簡單的推理
也有一些專業(yè)的工具對其進(jìn)行測試
現(xiàn)在我們有兩個方法來解決這個問題:
1. 提高硬盤的讀寫速度,讓其達(dá)到內(nèi)存的速度
2. 分?jǐn)倝毫Γ延脖P讀寫的壓力分?jǐn)偟讲煌墓?jié)點(diǎn)上面
第一個方法那是硬盤廠商的事情了,我們控制不了,當(dāng)然現(xiàn)在市面上也有讀寫快的,例如固態(tài)硬盤可以選配
我們要說的就是如何用現(xiàn)有的硬件來解決問題,也就是第二種方法。
我們再來分析業(yè)務(wù):
數(shù)據(jù)庫的操作 insert ?, delete ,update ,select
在正式的生產(chǎn)環(huán)境中,我們會發(fā)現(xiàn),對比insert ?寫的操作,用戶更多的在 select ?查詢上面的操作.
例如: 我們經(jīng)常瀏覽新聞、逛淘寶,還在看我寫的這篇文章,這些都是在 進(jìn)行 讀查詢.

那么我們一主一從的架構(gòu) 就是 讓應(yīng)用從 2個節(jié)點(diǎn)上面讀取, 來進(jìn)行分?jǐn)倝毫Γ?br>
而這種從兩個節(jié)點(diǎn)上面讀取的策略 可以 通過 負(fù)載均衡來實(shí)現(xiàn),意思就是說 如果有10個請求過來
把5個讀的請求轉(zhuǎn)發(fā)到 A 節(jié)點(diǎn), 另外5個轉(zhuǎn)發(fā)到B節(jié)點(diǎn)上面。
那么這個一主一從是如何實(shí)現(xiàn)的呢?
可以通過 MySQL replication 復(fù)制的方式來做
選定一個節(jié)點(diǎn)的MySQL作為 master
另外一個節(jié)點(diǎn)的MySQL作為 slave
插入更新數(shù)據(jù) 我們通過 master 完成 ,
master 會通過 replication 的方式來完成 對 slave 的同步更新.
這時 slave 就會有相同的數(shù)據(jù), 應(yīng)用就可以通過 從 slave 讀取數(shù)據(jù) 來減輕 master 的壓力.
3.4 Master/Slave 復(fù)制原理及方式

1. Master 所有的數(shù)據(jù)更新會記錄到 日志 binlog 中,Master A 把binlog日志傳給 Slave B
2. B 先把 A 的binlog日志 放到 稱為 relaylog 中繼日志的 地方
3. 最后 B 通過relaylog 日志中的內(nèi)容對自己的binlog 進(jìn)行更新,復(fù)制數(shù)據(jù)。
從這種機(jī)制上我們可以看出,可以保證A 和 B 的數(shù)據(jù)一致,但是同步或許會有延時(不考慮網(wǎng)絡(luò)因素)
A 的執(zhí)行可以并發(fā)執(zhí)行, 等A 的 binlog 日志寫 到 B 的 relaylog ,然后 B 從relaylog 讀取復(fù)制到binlog
這個過程中會發(fā)生延時.
于是出現(xiàn)了
同步復(fù)制 的方式 :
同步復(fù)制 是 ?用戶在前端訪問,Master收到 insert 請求,這個時候 需要 等待 slave 復(fù)制完成后確認(rèn),
才能返回結(jié)果給用戶,
顯然這種方式不可取,因為會造成用戶請求變的很慢的情況。
而這種方式也不是 MySQL的默認(rèn)方式。
異步復(fù)制:
Master 只要完成自己的數(shù)據(jù)更新就返回結(jié)果給 用戶,
而同步在異步狀態(tài)下進(jìn)行。 MySQL 默認(rèn)設(shè)置。
半同步復(fù)制:
即是 如果slave 有很多個 , 也是后面講的 一主多從的 架構(gòu)下, master只要保證 其中一個slave 同步復(fù)制成功,
就返回結(jié)果給用戶端。
3.5 一主多從架構(gòu)
一主一從 是 一主多從 架構(gòu)中的特例, 一主一從學(xué)會了,很容易理解 一主多從的架構(gòu)了
在Mysql 的配置上面區(qū)別不大,后面實(shí)戰(zhàn)進(jìn)行架構(gòu)的搭建會講到。
這里就不衍生開了。
3.6 雙主多從架構(gòu)
為什么會有雙主多從架構(gòu)出現(xiàn)呢,肯定是為了解決某種問題而產(chǎn)生的。
是的,當(dāng)我們用了一主多從架構(gòu)以后,我們會發(fā)現(xiàn)一個致命的問題, 當(dāng)我有5個節(jié)點(diǎn),
肯定是 1個Master ,另外4 個是 slave , 這個時候 master 就相當(dāng)于是中心領(lǐng)導(dǎo)的地位,
他這么重要,如果master 崩掉了怎么辦,整個系統(tǒng)就不能正常運(yùn)行了,
這個時候采用 雙主多從,來用副領(lǐng)導(dǎo)保證。
就像master1 是一個總經(jīng)理, 如果總經(jīng)理不舒服或者有事走開了
這個時候就由 master2 副總 來接替他的工作。
3.7 Mysql Sharding
master-slave 這種架構(gòu),不管是 一主多從 還是 雙主多從,我們發(fā)現(xiàn)他的性能瓶頸是在
master 上面,整個系統(tǒng)也并不是可以通過增加master 來達(dá)到性能的倍數(shù)增長的。
slave 越多,master 復(fù)制到 slave 的 日志越多,master 的負(fù)擔(dān)就越重,同步的延時就越大
會出現(xiàn)讀取到臟數(shù)據(jù),以及數(shù)據(jù)不一致的問題。
問題出現(xiàn)了,新的架構(gòu)也隨之而來。
一種分表分庫的分布式架構(gòu)就出現(xiàn)了。
簡單來講,分表分庫 不是 在master 和 slave 之間進(jìn)行數(shù)據(jù)復(fù)制 以減輕 讀的壓力。
而是把數(shù)據(jù)內(nèi)容進(jìn)行切分,分別放到不同的節(jié)點(diǎn)上 ?。
例如 : 現(xiàn)在有10個用戶的數(shù)據(jù)
master-slave 的做法是 復(fù)制10個用戶的數(shù)據(jù)到 slave 下面去,這個時候整個系統(tǒng)就有10 * N個slave的數(shù)據(jù)量了。
而 分表分庫則是 ?其中5個用戶數(shù)據(jù)放到 A 節(jié)點(diǎn)上 , 另外5個用戶數(shù)據(jù)放到B節(jié)點(diǎn)上,整個系統(tǒng)數(shù)據(jù)還是10個數(shù)據(jù)量。
這里簡單講這些,詳細(xì)的放到后面章節(jié)中來講。
在分表分庫我們用Mycat 中間件, 在每個節(jié)點(diǎn)的分庫中 ,我們還可以采用Master-Slave 這種架構(gòu) 作為 混合架構(gòu)使用。
3.8 小張講解
讀寫分離
通過MySQL replication 我們可以復(fù)制數(shù)據(jù)到不同的數(shù)據(jù)庫中, 但是上面講到讀取需要從不同的節(jié)點(diǎn)中讀取,
還要有策略作負(fù)載均衡,這個功能邏輯就需要應(yīng)用來進(jìn)行實(shí)現(xiàn)。(應(yīng)用要連接不同的數(shù)據(jù)庫節(jié)點(diǎn),分離讀寫)
市面上有很多成熟的中間件可以實(shí)現(xiàn) 負(fù)載均衡、讀寫分離,例如:MySQL-Proxy ,
應(yīng)用層可以像 剛開始那樣代碼不變,所有的 讀寫分離工作交給 MySQL-Proxy中間件來實(shí)現(xiàn)。
MySQL replication
下一節(jié)中 ,我們具體來動手來做一個一主一從這種架構(gòu),通過配置MySQL的 replication ,以及在應(yīng)用層進(jìn)行
負(fù)載均衡、讀寫分離的實(shí)現(xiàn),用最輕的方式來進(jìn)行性能的最大提升。
3.9 課后作業(yè)
1. 什么是一主一從?
2. 同步有哪幾種方式?
3. 實(shí)驗:
> 安裝centos 7 操作系統(tǒng)
> 安裝mysql5.7 數(shù)據(jù)庫
> 進(jìn)行一主一從的Mysql 數(shù)據(jù)庫架構(gòu)
> 應(yīng)用層實(shí)現(xiàn)一個DEMO , 進(jìn)行讀寫分離以及負(fù)載均衡