Web負(fù)載均衡

Web負(fù)載均衡

Web負(fù)載均衡(Load Balancing)隶糕,簡單地說就是給我們的服務(wù)器集群分配“工作任務(wù)”坝疼,而采用恰當(dāng)?shù)姆峙浞绞酱浼穑瑢τ诒Wo(hù)處于后端的Web服務(wù)器來說,非常重要虑灰。

Paste_Image.png
1. HTTP重定向

當(dāng)用戶發(fā)來請求的時候吨瞎,Web服務(wù)器通過修改HTTP響應(yīng)頭中的Location標(biāo)記來返回一個新的url,然后瀏覽器再繼續(xù)請求這個新url穆咐,實(shí)際上就是頁面重定向颤诀。通過重定向字旭,來達(dá)到“負(fù)載均衡”的目標(biāo)。例如着绊,我們在下載PHP源碼包的時候谐算,點(diǎn)擊下載鏈接時,為了解決不同國家和地域下載速度的問題归露,它會返回一個離我們近的下載地址洲脂。重定向的HTTP返回碼是302,如下圖:


如果使用PHP代碼來實(shí)現(xiàn)這個功能剧包,方式如下:

Paste_Image.png

這個重定向非常容易實(shí)現(xiàn)恐锦,并且可以自定義各種策略。但是疆液,它在大規(guī)模訪問量下一铅,性能不佳。而且堕油,給用戶的體驗也不好潘飘,實(shí)際請求發(fā)生重定向,增加了網(wǎng)絡(luò)延時掉缺。

2. 反向代理負(fù)載均衡

反向代理服務(wù)的核心工作主要是轉(zhuǎn)發(fā)HTTP請求卜录,扮演了瀏覽器端和后臺Web服務(wù)器中轉(zhuǎn)的角色。因為它工作在HTTP層(應(yīng)用層)眶明,也就是網(wǎng)絡(luò)七層結(jié)構(gòu)中的第七層艰毒,因此也被稱為“七層負(fù)載均衡”∷汛眩可以做反向代理的軟件很多丑瞧,比較常見的一種是Nginx。


Nginx是一種非常靈活的反向代理軟件蜀肘,可以自由定制化轉(zhuǎn)發(fā)策略绊汹,分配服務(wù)器流量的權(quán)重等。反向代理中扮宠,常見的一個問題灸促,就是Web服務(wù)器存儲的session數(shù)據(jù),因為一般負(fù)載均衡的策略都是隨機(jī)分配請求的涵卵。同一個登錄用戶的請求,無法保證一定分配到相同的Web機(jī)器上荒叼,會導(dǎo)致無法找到session的問題轿偎。
解決方案主要有兩種:
配置反向代理的轉(zhuǎn)發(fā)規(guī)則,讓同一個用戶的請求一定落到同一臺機(jī)器上(通過分析cookie)被廓,復(fù)雜的轉(zhuǎn)發(fā)規(guī)則將會消耗更多的CPU坏晦,也增加了代理服務(wù)器的負(fù)擔(dān)。
將session這類的信息,專門用某個獨(dú)立服務(wù)來存儲昆婿,例如redis/memchache球碉,這個方案是比較推薦的。

反向代理服務(wù)仓蛆,也是可以開啟緩存的睁冬,如果開啟了,會增加反向代理的負(fù)擔(dān)看疙,需要謹(jǐn)慎使用豆拨。這種負(fù)載均衡策略實(shí)現(xiàn)和部署非常簡單,而且性能表現(xiàn)也比較好能庆。但是施禾,它有“單點(diǎn)故障”的問題,如果掛了搁胆,會帶來很多的麻煩弥搞。而且,到了后期Web服務(wù)器繼續(xù)增加渠旁,它本身可能成為系統(tǒng)的瓶頸攀例。

3. IP負(fù)載均衡

IP負(fù)載均衡服務(wù)是工作在網(wǎng)絡(luò)層(修改IP)和傳輸層(修改端口,第四層)一死,比起工作在應(yīng)用層(第七層)性能要高出非常多肛度。原理是,他是對IP層的數(shù)據(jù)包的IP地址和端口信息進(jìn)行修改投慈,達(dá)到負(fù)載均衡的目的承耿。這種方式,也被稱為“四層負(fù)載均衡”伪煤。常見的負(fù)載均衡方式加袋,是LVS(Linux Virtual Server,Linux虛擬服務(wù))抱既,通過IPVS(IP Virtual Server职烧,IP虛擬服務(wù))來實(shí)現(xiàn)。


在負(fù)載均衡服務(wù)器收到客戶端的IP包的時候防泵,會修改IP包的目標(biāo)IP地址或端口蚀之,然后原封不動地投遞到內(nèi)部網(wǎng)絡(luò)中,數(shù)據(jù)包會流入到實(shí)際Web服務(wù)器捷泞。實(shí)際服務(wù)器處理完成后足删,又會將數(shù)據(jù)包投遞回給負(fù)載均衡服務(wù)器,它再修改目標(biāo)IP地址為用戶IP地址锁右,最終回到客戶端失受。
億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

上述的方式叫LVS-NAT讶泰,除此之外,還有LVS-RD(直接路由)拂到,LVS-TUN(IP隧道)痪署,三者之間都屬于LVS的方式,但是有一定的區(qū)別兄旬,篇幅問題狼犯,不贅敘。
IP負(fù)載均衡的性能要高出Nginx的反向代理很多辖试,它只處理到傳輸層為止的數(shù)據(jù)包辜王,并不做進(jìn)一步的組包,然后直接轉(zhuǎn)發(fā)給實(shí)際服務(wù)器罐孝。不過呐馆,它的配置和搭建比較復(fù)雜。

4. DNS負(fù)載均衡

DNS(Domain Name System)負(fù)責(zé)域名解析的服務(wù)莲兢,域名url實(shí)際上是服務(wù)器的別名汹来,實(shí)際映射是一個IP地址,解析過程改艇,就是DNS完成域名到IP的映射收班。而一個域名是可以配置成對應(yīng)多個IP的。因此谒兄,DNS也就可以作為負(fù)載均衡服務(wù)摔桦。


這種負(fù)載均衡策略,配置簡單承疲,性能極佳邻耕。但是,不能自由定義規(guī)則燕鸽,而且兄世,變更被映射的IP或者機(jī)器故障時很麻煩,還存在DNS生效延遲的問題啊研。

5. DNS/GSLB負(fù)載均衡

我們常用的CDN(Content Delivery Network御滩,內(nèi)容分發(fā)網(wǎng)絡(luò))實(shí)現(xiàn)方式疼燥,其實(shí)就是在同一個域名映射為多IP的基礎(chǔ)上更進(jìn)一步榨崩,通過GSLB(Global Server Load Balance,全局負(fù)載均衡)按照指定規(guī)則映射域名的IP灵嫌。一般情況下都是按照地理位置沟娱,將離用戶近的IP返回給用戶钠绍,減少網(wǎng)絡(luò)傳輸中的路由節(jié)點(diǎn)之間的跳躍消耗。


圖中的“向上尋找”花沉,實(shí)際過程是LDNS(Local DNS)先向根域名服務(wù)(Root Name Server)獲取到頂級根的Name Server(例如.com的)柳爽,然后得到指定域名的授權(quán)DNS,然后再獲得實(shí)際服務(wù)器IP碱屁。
億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

CDN在Web系統(tǒng)中磷脯,一般情況下是用來解決大小較大的靜態(tài)資源(html/Js/Css/圖片等)的加載問題,讓這些比較依賴網(wǎng)絡(luò)下載的內(nèi)容娩脾,盡可能離用戶更近赵誓,提升用戶體驗。
例如柿赊,我訪問了一張imgcache.gtimg.cn上的圖片(騰訊的自建CDN俩功,不使用qq.com域名的原因是防止http請求的時候,帶上了多余的cookie信息)碰声,我獲得的IP是183.60.217.90诡蜓。
億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

這種方式,和前面的DNS負(fù)載均衡一樣胰挑,不僅性能極佳蔓罚,而且支持配置多種策略。但是瞻颂,搭建和維護(hù)成本非常高豺谈。互聯(lián)網(wǎng)一線公司贡这,會自建CDN服務(wù)茬末,中小型公司一般使用第三方提供的CDN。

Web系統(tǒng)的緩存機(jī)制的建立和優(yōu)化

剛剛我們講完了Web系統(tǒng)的外部網(wǎng)絡(luò)環(huán)境盖矫,現(xiàn)在我們開始關(guān)注我們Web系統(tǒng)自身的性能問題丽惭。我們的Web站點(diǎn)隨著訪問量的上升,會遇到很多的挑戰(zhàn)炼彪,解決這些問題不僅僅是擴(kuò)容機(jī)器這么簡單吐根,建立和使用合適的緩存機(jī)制才是根本。
最開始辐马,我們的Web系統(tǒng)架構(gòu)可能是這樣的拷橘,每個環(huán)節(jié),都可能只有1臺機(jī)器喜爷。


我們從最根本的數(shù)據(jù)存儲開始看哈冗疮。

一、 MySQL數(shù)據(jù)庫內(nèi)部緩存使用

MySQL的緩存機(jī)制檩帐,就從先從MySQL內(nèi)部開始术幔,下面的內(nèi)容將以最常見的InnoDB存儲引擎為主。

1. 建立恰當(dāng)?shù)乃饕?/h6>

最簡單的是建立索引湃密,索引在表數(shù)據(jù)比較大的時候诅挑,起到快速檢索數(shù)據(jù)的作用四敞,但是成本也是有的。首先拔妥,占用了一定的磁盤空間忿危,其中組合索引最突出,使用需要謹(jǐn)慎没龙,它產(chǎn)生的索引甚至?xí)仍磾?shù)據(jù)更大铺厨。其次,建立索引之后的數(shù)據(jù)insert/update/delete等操作硬纤,因為需要更新原來的索引解滓,耗時會增加。當(dāng)然筝家,實(shí)際上我們的系統(tǒng)從總體來說洼裤,是以select查詢操作居多,因此肛鹏,索引的使用仍然對系統(tǒng)性能有大幅提升的作用逸邦。

2. 數(shù)據(jù)庫連接線程池緩存

如果,每一個數(shù)據(jù)庫操作請求都需要創(chuàng)建和銷毀連接的話在扰,對數(shù)據(jù)庫來說缕减,無疑也是一種巨大的開銷。為了減少這類型的開銷芒珠,可以在MySQL中配置thread_cache_size來表示保留多少線程用于復(fù)用桥狡。線程不夠的時候,再創(chuàng)建皱卓,空閑過多的時候裹芝,則銷毀。


其實(shí)娜汁,還有更為激進(jìn)一點(diǎn)的做法嫂易,使用pconnect(數(shù)據(jù)庫長連接),線程一旦創(chuàng)建在很長時間內(nèi)都保持著掐禁。但是怜械,在訪問量比較大,機(jī)器比較多的情況下傅事,這種用法很可能會導(dǎo)致“數(shù)據(jù)庫連接數(shù)耗盡”缕允,因為建立連接并不回收,最終達(dá)到數(shù)據(jù)庫的max_connections(最大連接數(shù))蹭越。因此障本,長連接的用法通常需要在CGI和MySQL之間實(shí)現(xiàn)一個“連接池”服務(wù),控制CGI機(jī)器“盲目”創(chuàng)建連接數(shù)。
億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

建立數(shù)據(jù)庫連接池服務(wù)驾霜,有很多實(shí)現(xiàn)的方式案训,PHP的話,我推薦使用swoole(PHP的一個網(wǎng)絡(luò)通訊拓展)來實(shí)現(xiàn)寄悯。

  1. Innodb緩存設(shè)置(innodb_buffer_pool_size)
    innodb_buffer_pool_size這是個用來保存索引和數(shù)據(jù)的內(nèi)存緩存區(qū)萤衰,如果機(jī)器是MySQL獨(dú)占的機(jī)器,一般推薦為機(jī)器物理內(nèi)存的80%猜旬。在取表數(shù)據(jù)的場景中,它可以減少磁盤IO倦卖。一般來說洒擦,這個值設(shè)置越大,cache命中率會越高怕膛。
  2. 分庫/分表/分區(qū)熟嫩。
    MySQL數(shù)據(jù)庫表一般承受數(shù)據(jù)量在百萬級別,再往上增長褐捻,各項性能將會出現(xiàn)大幅度下降掸茅,因此,當(dāng)我們預(yù)見數(shù)據(jù)量會超過這個量級的時候柠逞,建議進(jìn)行分庫/分表/分區(qū)等操作昧狮。最好的做法,是服務(wù)在搭建之初就設(shè)計為分庫分表的存儲模式板壮,從根本上杜絕中后期的風(fēng)險逗鸣。不過,會犧牲一些便利性绰精,例如列表式的查詢撒璧,同時,也增加了維護(hù)的復(fù)雜度笨使。不過卿樱,到了數(shù)據(jù)量千萬級別或者以上的時候,我們會發(fā)現(xiàn)硫椰,它們都是值得的繁调。
    二、 MySQL數(shù)據(jù)庫多臺服務(wù)搭建
    1臺MySQL機(jī)器最爬,實(shí)際上是高風(fēng)險的單點(diǎn)涉馁,因為如果它掛了,我們Web服務(wù)就不可用了爱致。而且烤送,隨著Web系統(tǒng)訪問量繼續(xù)增加,終于有一天糠悯,我們發(fā)現(xiàn)1臺MySQL服務(wù)器無法支撐下去帮坚,我們開始需要使用更多的MySQL機(jī)器妻往。當(dāng)引入多臺MySQL機(jī)器的時候,很多新的問題又將產(chǎn)生试和。
  3. 建立MySQL主從讯泣,從庫作為備份
    這種做法純粹為了解決“單點(diǎn)故障”的問題,在主庫出故障的時候阅悍,切換到從庫好渠。不過,這種做法實(shí)際上有點(diǎn)浪費(fèi)資源节视,因為從庫實(shí)際上被閑著了拳锚。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空
  4. MySQL讀寫分離,主庫寫寻行,從庫讀霍掺。
    兩臺數(shù)據(jù)庫做讀寫分離,主庫負(fù)責(zé)寫入類的操作拌蜘,從庫負(fù)責(zé)讀的操作杆烁。并且,如果主庫發(fā)生故障简卧,仍然不影響讀的操作兔魂,同時也可以將全部讀寫都臨時切換到從庫中(需要注意流量,可能會因為流量過大贞滨,把從庫也拖垮)入热。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空
  5. 主主互備。
    兩臺MySQL之間互為彼此的從庫晓铆,同時又是主庫勺良。這種方案,既做到了訪問量的壓力分流骄噪,同時也解決了“單點(diǎn)故障”問題尚困。任何一臺故障,都還有另外一套可供使用的服務(wù)链蕊。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

    不過事甜,這種方案,只能用在兩臺機(jī)器的場景滔韵。如果業(yè)務(wù)拓展還是很快的話逻谦,可以選擇將業(yè)務(wù)分離,建立多個主主互備陪蜻。
    三邦马、 MySQL數(shù)據(jù)庫機(jī)器之間的數(shù)據(jù)同步
    每當(dāng)我們解決一個問題,新的問題必然誕生在舊的解決方案上。當(dāng)我們有多臺MySQL滋将,在業(yè)務(wù)高峰期邻悬,很可能出現(xiàn)兩個庫之間的數(shù)據(jù)有延遲的場景。并且随闽,網(wǎng)絡(luò)和機(jī)器負(fù)載等父丰,也會影響數(shù)據(jù)同步的延遲。我們曾經(jīng)遇到過掘宪,在日訪問量接近1億的特殊場景下蛾扇,出現(xiàn),從庫數(shù)據(jù)需要很多天才能同步追上主庫的數(shù)據(jù)魏滚。這種場景下屁桑,從庫基本失去效用了。
    于是栏赴,解決同步問題,就是我們下一步需要關(guān)注的點(diǎn)靖秩。
  6. MySQL自帶多線程同步
    MySQL5.6開始支持主庫和從庫數(shù)據(jù)同步须眷,走多線程。但是沟突,限制也是比較明顯的花颗,只能以庫為單位。MySQL數(shù)據(jù)同步是通過binlog日志惠拭,主庫寫入到binlog日志的操作扩劝,是具有順序的,尤其當(dāng)SQL操作中含有對于表結(jié)構(gòu)的修改等操作职辅,對于后續(xù)的SQL語句操作是有影響的棒呛。因此,從庫同步數(shù)據(jù)域携,必須走單進(jìn)程簇秒。
  7. 自己實(shí)現(xiàn)解析binlog,多線程寫入秀鞭。
    以數(shù)據(jù)庫的表為單位趋观,解析binlog多張表同時做數(shù)據(jù)同步。這樣做的話锋边,的確能夠加快數(shù)據(jù)同步的效率皱坛,但是,如果表和表之間存在結(jié)構(gòu)關(guān)系或者數(shù)據(jù)依賴的話豆巨,則同樣存在寫入順序的問題剩辟。這種方式,可用于一些比較穩(wěn)定并且相對獨(dú)立的數(shù)據(jù)表。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

    國內(nèi)一線互聯(lián)網(wǎng)公司抹沪,大部分都是通過這種方式刻肄,來加快數(shù)據(jù)同步效率。還有更為激進(jìn)的做法融欧,是直接解析binlog敏弃,忽略以表為單位,直接寫入噪馏。但是這種做法麦到,實(shí)現(xiàn)復(fù)雜,使用范圍就更受到限制欠肾,只能用于一些場景特殊的數(shù)據(jù)庫中(沒有表結(jié)構(gòu)變更瓶颠,表和表之間沒有數(shù)據(jù)依賴等特殊表)。
    四刺桃、 在Web服務(wù)器和數(shù)據(jù)庫之間建立緩存
    實(shí)際上粹淋,解決大訪問量的問題,不能僅僅著眼于數(shù)據(jù)庫層面瑟慈。根據(jù)“二八定律”桃移,80%的請求只關(guān)注在20%的熱點(diǎn)數(shù)據(jù)上。因此葛碧,我們應(yīng)該建立Web服務(wù)器和數(shù)據(jù)庫之間的緩存機(jī)制借杰。這種機(jī)制,可以用磁盤作為緩存进泼,也可以用內(nèi)存緩存的方式蔗衡。通過它們,將大部分的熱點(diǎn)數(shù)據(jù)查詢乳绕,阻擋在數(shù)據(jù)庫之前绞惦。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空
  8. 頁面靜態(tài)化
    用戶訪問網(wǎng)站的某個頁面,頁面上的大部分內(nèi)容在很長一段時間內(nèi)刷袍,可能都是沒有變化的翩隧。例如一篇新聞報道,一旦發(fā)布幾乎是不會修改內(nèi)容的呻纹。這樣的話堆生,通過CGI生成的靜態(tài)html頁面緩存到Web服務(wù)器的磁盤本地。除了第一次雷酪,是通過動態(tài)CGI查詢數(shù)據(jù)庫獲取之外淑仆,之后都直接將本地磁盤文件返回給用戶。

    在Web系統(tǒng)規(guī)模比較小的時候哥力,這種做法看似完美蔗怠。但是墩弯,一旦Web系統(tǒng)規(guī)模變大,例如當(dāng)我有100臺的Web服務(wù)器的時候寞射。那樣這些磁盤文件渔工,將會有100份,這個是資源浪費(fèi)桥温,也不好維護(hù)引矩。這個時候有人會想,可以集中一臺服務(wù)器存起來侵浸,呵呵旺韭,不如看看下面一種緩存方式吧,它就是這樣做的掏觉。
  9. 單臺內(nèi)存緩存
    通過頁面靜態(tài)化的例子中区端,我們可以知道將“緩存”搭建在Web機(jī)器本機(jī)是不好維護(hù)的,會帶來更多問題(實(shí)際上澳腹,通過PHP的apc拓展织盼,可通過Key/value操作Web服務(wù)器的本機(jī)內(nèi)存)。因此酱塔,我們選擇搭建的內(nèi)存緩存服務(wù)悔政,也必須是一個獨(dú)立的服務(wù)。
    內(nèi)存緩存的選擇延旧,主要有redis/memcache。從性能上說槽地,兩者差別不大迁沫,從功能豐富程度上說,Redis更勝一籌捌蚊。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空
  10. 內(nèi)存緩存集群
    當(dāng)我們搭建單臺內(nèi)存緩存完畢集畅,我們又會面臨單點(diǎn)故障的問題,因此缅糟,我們必須將它變成一個集群挺智。簡單的做法,是給他增加一個slave作為備份機(jī)器窗宦。但是赦颇,如果請求量真的很多,我們發(fā)現(xiàn)cache命中率不高赴涵,需要更多的機(jī)器內(nèi)存呢媒怯?因此,我們更建議將它配置成一個集群髓窜。例如扇苞,類似redis cluster欺殿。
    Redis cluster集群內(nèi)的Redis互為多組主從,同時每個節(jié)點(diǎn)都可以接受請求鳖敷,在拓展集群的時候比較方便脖苏。客戶端可以向任意一個節(jié)點(diǎn)發(fā)送請求定踱,如果是它的“負(fù)責(zé)”的內(nèi)容棍潘,則直接返回內(nèi)容。否則屋吨,查找實(shí)際負(fù)責(zé)Redis節(jié)點(diǎn)蜒谤,然后將地址告知客戶端,客戶端重新請求至扰。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

    對于使用緩存服務(wù)的客戶端來說鳍徽,這一切是透明的。
Paste_Image.png

內(nèi)存緩存服務(wù)在切換的時候敢课,是有一定風(fēng)險的阶祭。從A集群切換到B集群的過程中,必須保證B集群提前做好“預(yù)熱”(B集群的內(nèi)存中的熱點(diǎn)數(shù)據(jù)直秆,應(yīng)該盡量與A集群相同濒募,否則,切換的一瞬間大量請求內(nèi)容圾结,在B集群的內(nèi)存緩存中查找不到瑰剃,流量直接沖擊后端的數(shù)據(jù)庫服務(wù),很可能導(dǎo)致數(shù)據(jù)庫宕機(jī))筝野。

  1. 減少數(shù)據(jù)庫“寫”
    上面的機(jī)制晌姚,都實(shí)現(xiàn)減少數(shù)據(jù)庫的“讀”的操作,但是歇竟,寫的操作也是一個大的壓力挥唠。寫的操作,雖然無法減少焕议,但是可以通過合并請求宝磨,來起到減輕壓力的效果。這個時候盅安,我們就需要在內(nèi)存緩存集群和數(shù)據(jù)庫集群之間唤锉,建立一個修改同步機(jī)制。
    先將修改請求生效在cache中别瞭,讓外界查詢顯示正常腌紧,然后將這些sql修改放入到一個隊列中存儲起來,隊列滿或者每隔一段時間畜隶,合并為一個請求到數(shù)據(jù)庫中更新數(shù)據(jù)庫壁肋。
Paste_Image.png

除了上述通過改變系統(tǒng)架構(gòu)的方式提升寫的性能外号胚,MySQL本身也可以通過配置參數(shù)innodb_flush_log_at_trx_commit來調(diào)整寫入磁盤的策略。如果機(jī)器成本允許浸遗,從硬件層面解決問題猫胁,可以選擇老一點(diǎn)的RAID(Redundant Arrays of independent Disks,磁盤列陣)或者比較新的SSD(Solid State Drives跛锌,固態(tài)硬盤)弃秆。

  1. NoSQL存儲
    不管數(shù)據(jù)庫的讀還是寫,當(dāng)流量再進(jìn)一步上漲髓帽,終會達(dá)到“人力有窮時”的場景菠赚。繼續(xù)加機(jī)器的成本比較高,并且不一定可以真正解決問題的時候郑藏。這個時候衡查,部分核心數(shù)據(jù),就可以考慮使用NoSQL的數(shù)據(jù)庫必盖。NoSQL存儲拌牲,大部分都是采用key-value的方式,這里比較推薦使用上面介紹過Redis歌粥,Redis本身是一個內(nèi)存cache塌忽,同時也可以當(dāng)做一個存儲來使用,讓它直接將數(shù)據(jù)落地到磁盤失驶。
    這樣的話土居,我們就將數(shù)據(jù)庫中某些被頻繁讀寫的數(shù)據(jù),分離出來嬉探,放在我們新搭建的Redis存儲集群中装盯,又進(jìn)一步減輕原來MySQL數(shù)據(jù)庫的壓力,同時因為Redis本身是個內(nèi)存級別的Cache甲馋,讀寫的性能都會大幅度提升。
Paste_Image.png

國內(nèi)一線互聯(lián)網(wǎng)公司迄损,架構(gòu)上采用的解決方案很多是類似于上述方案定躏,不過,使用的cache服務(wù)卻不一定是Redis芹敌,他們會有更豐富的其他選擇痊远,甚至根據(jù)自身業(yè)務(wù)特點(diǎn)開發(fā)出自己的NoSQL服務(wù)。

  1. 空節(jié)點(diǎn)查詢問題
    當(dāng)我們搭建完前面所說的全部服務(wù)氏捞,認(rèn)為Web系統(tǒng)已經(jīng)很強(qiáng)的時候碧聪。我們還是那句話,新的問題還是會來的液茎〕炎耍空節(jié)點(diǎn)查詢辞嗡,是指那些數(shù)據(jù)庫中根本不存在的數(shù)據(jù)請求。例如滞造,我請求查詢一個不存在人員信息续室,系統(tǒng)會從各級緩存逐級查找,最后查到到數(shù)據(jù)庫本身谒养,然后才得出查找不到的結(jié)論挺狰,返回給前端。因為各級cache對它無效买窟,這個請求是非常消耗系統(tǒng)資源的丰泊,而如果大量的空節(jié)點(diǎn)查詢,是可以沖擊到系統(tǒng)服務(wù)的始绍。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

    在我曾經(jīng)的工作經(jīng)歷中瞳购,曾深受其害。因此疆虚,為了維護(hù)Web系統(tǒng)的穩(wěn)定性苛败,設(shè)計適當(dāng)?shù)目展?jié)點(diǎn)過濾機(jī)制,非常有必要径簿。
    我們當(dāng)時采用的方式罢屈,就是設(shè)計一張簡單的記錄映射表。將存在的記錄存儲起來篇亭,放入到一臺內(nèi)存cache中缠捌,這樣的話,如果還有空節(jié)點(diǎn)查詢译蒂,則在緩存這一層就被阻擋了曼月。
    億級Web系統(tǒng)搭建——單機(jī)到分布式集群 - hansionxu - 技術(shù)的天空

異地部署(地理分布式)

完成了上述架構(gòu)建設(shè)之后,我們的系統(tǒng)是否就已經(jīng)足夠強(qiáng)大了呢柔昼?答案當(dāng)然是否定的哈哑芹,優(yōu)化是無極限的。Web系統(tǒng)雖然表面上看捕透,似乎比較強(qiáng)大了聪姿,但是給予用戶的體驗卻不一定是最好的。因為東北的同學(xué)乙嘀,訪問深圳的一個網(wǎng)站服務(wù)末购,他還是會感到一些網(wǎng)絡(luò)距離上的慢。這個時候虎谢,我們就需要做異地部署盟榴,讓W(xué)eb系統(tǒng)離用戶更近。

一婴噩、 核心集中與節(jié)點(diǎn)分散

有玩過大型網(wǎng)游的同學(xué)都會知道擎场,網(wǎng)游是有很多個區(qū)的羽德,一般都是按照地域來分檐薯,例如廣東專區(qū)伟骨,北京專區(qū)。如果一個在廣東的玩家屿岂,去北京專區(qū)玩礼饱,那么他會感覺明顯比在廣東專區(qū)卡坏为。實(shí)際上,這些大區(qū)的名稱就已經(jīng)說明了镊绪,它的服務(wù)器所在地匀伏,所以,廣東的玩家去連接地處北京的服務(wù)器蝴韭,網(wǎng)絡(luò)當(dāng)然會比較慢够颠。
當(dāng)一個系統(tǒng)和服務(wù)足夠大的時候,就必須開始考慮異地部署的問題了榄鉴。讓你的服務(wù)履磨,盡可能離用戶更近。我們前面已經(jīng)提到了Web的靜態(tài)資源庆尘,可以存放在CDN上剃诅,然后通過DNS/GSLB的方式,讓靜態(tài)資源的分散“全國各地”驶忌。但是矛辕,CDN只解決的靜態(tài)資源的問題,沒有解決后端龐大的系統(tǒng)服務(wù)還只集中在某個固定城市的問題付魔。
這個時候聊品,異地部署就開始了。異地部署一般遵循:核心集中几苍,節(jié)點(diǎn)分散翻屈。
核心集中:實(shí)際部署過程中,總有一部分的數(shù)據(jù)和服務(wù)存在不可部署多套妻坝,或者部署多套成本巨大伸眶。而對于這些服務(wù)和數(shù)據(jù),就仍然維持一套惠勒,而部署地點(diǎn)選擇一個地域比較中心的地方,通過網(wǎng)絡(luò)內(nèi)部專線來和各個節(jié)點(diǎn)通訊爬坑。
節(jié)點(diǎn)分散:將一些服務(wù)部署為多套纠屋,分布在各個城市節(jié)點(diǎn),讓用戶請求盡可能選擇近的節(jié)點(diǎn)訪問服務(wù)盾计。

例如售担,我們選擇在上海部署為核心節(jié)點(diǎn)赁遗,北京,深圳族铆,武漢岩四,上海為分散節(jié)點(diǎn)(上海自己本身也是一個分散節(jié)點(diǎn))。我們的服務(wù)架構(gòu)如圖:


需要補(bǔ)充一下的是哥攘,上圖中上海節(jié)點(diǎn)和核心節(jié)點(diǎn)是同處于一個機(jī)房的剖煌,其他分散節(jié)點(diǎn)各自獨(dú)立機(jī)房。 國內(nèi)有很多大型網(wǎng)游逝淹,都是大致遵循上述架構(gòu)耕姊。它們會把數(shù)據(jù)量不大的用戶核心賬號等放在核心節(jié)點(diǎn),而大部分的網(wǎng)游數(shù)據(jù)栅葡,例如裝備茉兰、任務(wù)等數(shù)據(jù)和服務(wù)放在地區(qū)節(jié)點(diǎn)里。當(dāng)然欣簇,核心節(jié)點(diǎn)和地域節(jié)點(diǎn)之間规脸,也有緩存機(jī)制。

二熊咽、 節(jié)點(diǎn)容災(zāi)和過載保護(hù)

節(jié)點(diǎn)容災(zāi)是指莫鸭,某個節(jié)點(diǎn)如果發(fā)生故障時,我們需要建立一個機(jī)制去保證服務(wù)仍然可用网棍。毫無疑問黔龟,這里比較常見的容災(zāi)方式,是切換到附近城市節(jié)點(diǎn)滥玷。假如系統(tǒng)的天津節(jié)點(diǎn)發(fā)生故障氏身,那么我們就將網(wǎng)絡(luò)流量切換到附近的北京節(jié)點(diǎn)上』蟪耄考慮到負(fù)載均衡蛋欣,可能需要同時將流量切換到附近的幾個地域節(jié)點(diǎn)。另一方面如贷,核心節(jié)點(diǎn)自身也是需要自己做好容災(zāi)和備份的陷虎,核心節(jié)點(diǎn)一旦故障,就會影響全國服務(wù)杠袱。
過載保護(hù)尚猿,指的是一個節(jié)點(diǎn)已經(jīng)達(dá)到最大容量,無法繼續(xù)接接受更多請求了楣富,系統(tǒng)必須有一個保護(hù)的機(jī)制凿掂。一個服務(wù)已經(jīng)滿負(fù)載,還繼續(xù)接受新的請求,結(jié)果很可能就是宕機(jī)庄萎,影響整個節(jié)點(diǎn)的服務(wù)踪少,為了至少保障大部分用戶的正常使用,過載保護(hù)是必要的糠涛。
解決過載保護(hù)援奢,一般2個方向:
拒絕服務(wù),檢測到滿負(fù)載之后忍捡,就不再接受新的連接請求集漾。例如網(wǎng)游登入中的排隊。
分流到其他節(jié)點(diǎn)锉罐。這種的話帆竹,系統(tǒng)實(shí)現(xiàn)更為復(fù)雜,又涉及到負(fù)載均衡的問題脓规。

小結(jié)

Web系統(tǒng)會隨著訪問規(guī)模的增長栽连,漸漸地從1臺服務(wù)器可以滿足需求,一直成長為“龐然大物”的大集群侨舆。而這個Web系統(tǒng)變大的過程秒紧,實(shí)際上就是我們解決問題的過程。在不同的階段挨下,解決不同的問題熔恢,而新的問題又誕生在舊的解決方案之上。

系統(tǒng)的優(yōu)化是沒有極限的臭笆,軟件和系統(tǒng)架構(gòu)也一直在快速發(fā)展叙淌,新的方案解決了老的問題,同時也帶來新的挑戰(zhàn)愁铺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鹰霍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茵乱,更是在濱河造成了極大的恐慌茂洒,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓶竭,死亡現(xiàn)場離奇詭異督勺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)斤贰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門智哀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荧恍,你說我怎么就攤上這事瓷叫。” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵赞辩,是天一觀的道長。 經(jīng)常有香客問我授艰,道長辨嗽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任淮腾,我火速辦了婚禮糟需,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谷朝。我一直安慰自己洲押,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布圆凰。 她就那樣靜靜地躺著杈帐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪专钉。 梳的紋絲不亂的頭發(fā)上挑童,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機(jī)與錄音跃须,去河邊找鬼站叼。 笑死,一個胖子當(dāng)著我的面吹牛菇民,可吹牛的內(nèi)容都是我干的尽楔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼第练,長吁一口氣:“原來是場噩夢啊……” “哼阔馋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起复旬,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤垦缅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驹碍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壁涎,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年志秃,在試婚紗的時候發(fā)現(xiàn)自己被綠了怔球。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡浮还,死狀恐怖竟坛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤担汤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布涎跨,位于F島的核電站,受9級特大地震影響崭歧,放射性物質(zhì)發(fā)生泄漏隅很。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一率碾、第九天 我趴在偏房一處隱蔽的房頂上張望叔营。 院中可真熱鬧,春花似錦所宰、人聲如沸绒尊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婴谱。三九已至,卻和暖如春躯泰,著一層夾襖步出監(jiān)牢的瞬間勘究,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工斟冕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留口糕,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓磕蛇,卻偏偏與公主長得像景描,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秀撇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容