自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高可用可伸縮架構(gòu)實用經(jīng)驗談

開發(fā) 架構(gòu)
移動互聯(lián)網(wǎng)、云計算和大數(shù)據(jù)的成熟和發(fā)展,讓更多的好想法得以在很短的時間內(nèi)實現(xiàn)為產(chǎn)品。此時,如果用戶需求抓得準,用戶數(shù)量將很可能獲得爆發(fā)式增 長,而不需要像以往一樣需要精心運營幾年的時間。然而用戶數(shù)量的快速增長(尤其是短時間內(nèi)的爆發(fā)式增長),通常會讓應(yīng)用開發(fā)者有些吃不消,不得不面臨一些 嚴峻的技術(shù)挑戰(zhàn):如何避免因為單臺機器當(dāng)機導(dǎo)致服務(wù)不可用;如何避免在服務(wù)容量不足時,用戶體驗下降,等等。在系統(tǒng)構(gòu)建之初就采用高可用和可伸縮架構(gòu),將 能有效避免這些問題。

移動互聯(lián)網(wǎng)、云計算和大數(shù)據(jù)的成熟和發(fā)展,讓更多的好想法得以在很短的時間內(nèi)實現(xiàn)為產(chǎn)品。此時,如果用戶需求抓得準,用戶數(shù)量將很可能獲得爆發(fā)式增 長,而不需要像以往一樣需要精心運營幾年的時間。然而用戶數(shù)量的快速增長(尤其是短時間內(nèi)的爆發(fā)式增長),通常會讓應(yīng)用開發(fā)者有些吃不消,不得不面臨一些 嚴峻的技術(shù)挑戰(zhàn):如何避免因為單臺機器當(dāng)機導(dǎo)致服務(wù)不可用;如何避免在服務(wù)容量不足時,用戶體驗下降,等等。在系統(tǒng)構(gòu)建之初就采用高可用和可伸縮架構(gòu),將 能有效避免這些問題。

如何構(gòu)建高可用和可伸縮架構(gòu)呢?七牛云存儲首席架構(gòu)師李道兵在3月22的「開發(fā)者最佳實踐日」第十期沙龍活動上給出了自己的想法。他結(jié)合自己多年的 實踐經(jīng)驗,針對一些不太復(fù)雜的業(yè)務(wù)場景,從入口層、業(yè)務(wù)層、緩存層和數(shù)據(jù)庫層四個層面細致講述了如何構(gòu)建高可用和可伸縮系統(tǒng)。希望大家讀完這篇文章,能覺 得高可用和可伸縮不是一個高不可攀的東西,投入不高的成本就能在項目早期把高可用和可伸縮納入架構(gòu)設(shè)計之中。

如何實現(xiàn)高可用

入口層

入口層,通常指Nginx和Apache等層面的東西,負責(zé)應(yīng)用(不管是Web應(yīng)用還是移動應(yīng)用)的服務(wù)入口。我們通常會將服務(wù)定位在一個IP,如 果這個IP對應(yīng)的服務(wù)器當(dāng)機了,那么用戶的訪問肯定會中斷。此時,可以用keepalived來實現(xiàn)入口層的高可用。例如,機器A 的IP是 1.2.3.4,機器 B 的 IP 是 1.2.3.5, 那么再申請一個 IP 1.2.3.6(稱為⼼跳IP), 平時綁定在機器A上,如果A當(dāng)機,IP會自動綁定在機器B上;如果B當(dāng)機,IP會自動綁定在機器A上。對于這種形式,我們將DNS綁定到心跳IP上,即可 實現(xiàn)入口層的高可用。

但這個方案有一點小問題。第一,它的切換可能會有一到兩秒的中斷,也就是說,如果不是要求到非常嚴格的毫秒級就不會有問題。第二,對入口的機器會有 些浪費,因為買了兩臺機器的入口,可能就只有一臺機器用上。對一些長連接的應(yīng)用可能會導(dǎo)致服務(wù)中斷,這時候就需要客戶端做配合做一些重新創(chuàng)建連接的工作。 簡單來說,對于比較普通的業(yè)務(wù)來說,這個方案就能解決一部分問題。

這里要注意,keepalived在使用上會有一些限制。

  • 兩臺機器必須在同一個網(wǎng)段,不是在同一個網(wǎng)段,沒有辦法實現(xiàn)互相搶IP。

  • 內(nèi)網(wǎng)服務(wù)也可以做心跳,但需要注意的是,以前為了安全我們會把內(nèi)網(wǎng)服務(wù)綁定在內(nèi)網(wǎng)IP上,避免出現(xiàn)安全問題。但為了使用keepalived,必 須監(jiān)聽在所有IP上(如果監(jiān)聽在心跳IP上,那么機器沒有持有該IP時,服務(wù)無法啟動),簡單的方案是啟用 iptables, 避免內(nèi)網(wǎng)服務(wù)被外網(wǎng)訪問。

  • 服務(wù)器利用率下降,這時可以考慮做混合部署來改善這一點。

比較常見的一個錯誤是,如果有兩臺機器,兩個公網(wǎng)IP,DNS上把域名同時定位到兩個IP,就覺得已經(jīng)做了高可用了。這完全不是高可用,因為如果一臺機器當(dāng)機,那么就有一半左右的用戶無法訪問。

除了keepalive,lvs也能用來解決入口層的高可用問題。不過,與keepalived相比,lvs會更復(fù)雜一些,門檻也會高一些。

業(yè)務(wù)層

業(yè)務(wù)層通常是由PHP、Java、Python、Go等寫的邏輯代碼構(gòu)成的,需要依賴于后臺數(shù)據(jù)庫及一些緩存層面的東西。如何實現(xiàn)業(yè)務(wù)層的高可用呢?最核心的就是,業(yè)務(wù)層不要有狀態(tài),將狀態(tài)分散到緩存層和數(shù)據(jù)庫。目前大家通常喜歡將以下幾種數(shù)據(jù)放入業(yè)務(wù)層。

第一個是session,即用戶登錄相關(guān)的數(shù)據(jù),但好的做法是將session放在數(shù)據(jù)庫里,或者一個比較穩(wěn)定的緩存系統(tǒng)中。

第二個是緩存,在訪問數(shù)據(jù)庫時,如果一個查詢很慢,就希望將這些結(jié)果暫時放到進程里,下次再做查詢時就不用再訪問數(shù)據(jù)庫了。這種做法帶來的問題是,當(dāng)業(yè)務(wù)層服務(wù)器不只一臺時,數(shù)據(jù)很難做到一致,從緩存拿到的數(shù)據(jù)就可能是錯誤的。。

一個簡單的原則就是業(yè)務(wù)層不要有狀態(tài)。在業(yè)務(wù)層沒有狀態(tài)時,一臺業(yè)務(wù)層服務(wù)器當(dāng)?shù)袅酥?,Nginx/Apache會自動將所有的請求打到另外一臺 業(yè)務(wù)層的服務(wù)器上。由于沒有狀態(tài),兩臺服務(wù)器沒有任何差異,所以用戶完全感受不到。如果把session放在業(yè)務(wù)層里面的話,那么面臨的問題是,這個用戶 以前是登錄在一臺機器上的,這個進程死掉后,用戶就會被登出了。

友情提醒:有一段時間比較流行cookie session,就是將session中的數(shù)據(jù)加密之后放在客戶的cookie里,然后下發(fā)到客戶端,這樣也能做到與服務(wù)端完全無狀態(tài)。但這里面有很多 坑,如果能繞過這些坑就可以這樣使用。第一個坑是怎么保證加密的密鑰不泄露,一旦泄露就意味著攻擊者可以偽造任何人的身份。第二個坑是重放攻擊,如何避免 別人通過保存 cookie 去不停地嘗試的驗證碼,當(dāng)然也還有其他一些攻擊手段。如果沒有好辦法解決這兩方面的問題,那么cookie session盡量慎用。最好是將session放在一個性能比較好的數(shù)據(jù)庫中。如果數(shù)據(jù)庫性能不行,那么將session放在緩存中也比放在 cookie里要好一點。

緩存層

非常簡單的架構(gòu)里是沒有緩存這個概念的。但在訪問量上來之后,MySQL之類的數(shù)據(jù)庫扛不住了,比如在SATA盤里跑MySQL,QPS到達200、300甚至500時,MySQL的性能會大幅下降,這時就可以考慮用緩存層來擋住絕大部分服務(wù)請求,提升系統(tǒng)整體的容量。

緩存層做高可用一個簡單的方法就是,將緩存層分得細一點兒。比如說,緩存層就一臺機器的話,那么這臺機器當(dāng)了以后,所有應(yīng)用層的壓力就會往數(shù)據(jù)庫里 壓,數(shù)據(jù)庫扛不住的話,整個網(wǎng)站(或應(yīng)用)就會隨之當(dāng)?shù)?。而如果緩存層分在四臺機器上的話,每臺只有四分之一,這臺機器當(dāng)?shù)袅艘院?,也只有總訪問量的四分 之一會壓在數(shù)據(jù)庫上面,數(shù)據(jù)庫能扛住的話,網(wǎng)站就能很穩(wěn)定地等到緩存層重新起來。在實踐中,四分之一顯然是不夠的,我們會將它分得更細,以保證單臺緩存當(dāng) 機后數(shù)據(jù)庫還能撐得住即可。在中小規(guī)模下,緩存層和業(yè)務(wù)層可以混合部署,這樣可以節(jié)省機器。

數(shù)據(jù)庫層

在數(shù)據(jù)庫層面實現(xiàn)高可用,通常是在軟件層面來做。例如,MySQL有主從模式(Master-Slave),還有主主模式(Master-Master)都能滿足需求。MongoDB也有ReplicaSet的概念,基本都能滿足大家的需求。

總之,要想實現(xiàn)高可用,需要做到這幾點:入口層做心跳,業(yè)務(wù)層服務(wù)器無狀態(tài),緩存層減小粒度,數(shù)據(jù)庫做一個主從模式。對于這種模式來講,我們做的高 可用不需要太多服務(wù)器,這些東西都可以同時部署在兩臺服務(wù)器上。這時,兩臺服務(wù)器就能滿足早期的高可用需求了。任何一臺服務(wù)器當(dāng)機用戶完全無感知。

如何實現(xiàn)可伸縮

入口層

在入口層實現(xiàn)伸縮性,可以通過直接水平擴機器,然后DNS加IP來實現(xiàn)。但需要注意,盡管一個域名解析到幾十個IP沒有問題,但是很多瀏覽器客戶端只會使用前幾個IP,部分域名供應(yīng)商對此有優(yōu)化(如每次返回的IP順序隨機),但這個優(yōu)化效果不穩(wěn)定。

推薦的做法是使用少量的Nginx機器作為入口,業(yè)務(wù)服務(wù)器隱藏在內(nèi)網(wǎng)(HTTP類型的業(yè)務(wù)這種方式居多)。另外,也可以把所有IP下發(fā)到客戶端,然后在客戶端做一些調(diào)度(特別是非HTTP型的業(yè)務(wù),如游戲、直播)。

業(yè)務(wù)層

業(yè)務(wù)層的伸縮性如何實現(xiàn)?與做高可用時的解決方案一樣,要實現(xiàn)業(yè)務(wù)層的伸縮性,保證無狀態(tài)是很好的手段。此外,加機器繼續(xù)水平部署即可。

緩存層

比較麻煩的是緩存層的伸縮性,最簡單粗暴的方式是什么呢?趁著半夜量比較低的時候,把整個緩存層全部下線,然后上線新的緩存層。新的緩存層啟動起來 之后,再等這些緩存慢慢預(yù)熱。當(dāng)然這里一個要求,你的數(shù)據(jù)庫能抗住低估期的請求量。如果扛不住呢?取決于緩存類型,下面我們先可以將緩存的類型區(qū)分一下。

  • 強一致性緩存:無法接受從緩存拿到錯誤的數(shù)據(jù) (比如用戶余額,或者會被下游繼續(xù)緩存這種情形)

  • 弱一致性緩存:能接受在一段時間內(nèi)從緩存拿到錯誤的數(shù)據(jù) (比如微博的轉(zhuǎn)發(fā)數(shù))。

  • 不變型緩存:緩存key對應(yīng)的value不會變更 (比如從SHA1推出來的密碼, 或者其他復(fù)雜公式的計算結(jié)果)。

那什么緩存類型伸縮性比較好呢?弱一致性和不變型緩存的擴容很方便,用一致性Hash即可;強一致性情況稍微復(fù)雜一些,稍后再講。使用一致性 Hash,而不用簡單Hash的原因是緩存的失效率。如果緩存從9臺擴容到10臺,簡單Hash 情況下90%的緩存會馬上失效,而如果使用一致性Hash情況,只有10%的緩存會失效。

那么,強一致性緩存會有什么問題?第一個問題是,緩存客戶端的配置更新時間會有微小的差異,在這個時間窗內(nèi)有可能會拿到過期的數(shù)據(jù)。第二個問題是, 如果擴容之后再裁撤節(jié)點,會拿到臟數(shù)據(jù)。比如 a 這個key之前在機器1,擴容后在機器2,數(shù)據(jù)更新了,但裁撤節(jié)點后key回到機器1,這時候就會拿到臟數(shù)據(jù)。

要解決問題2比較簡單,要么保持永不減少節(jié)點,要么節(jié)點調(diào)整間隔大于數(shù)據(jù)的有效時間。問題1可以用如下的步驟來解決:

  1. 兩套hash配置都更新到客戶端,但仍然使用舊配置;

  2. 逐個客戶端改為只有兩套hash結(jié)果一致的情況下會使用緩存,其余情況從數(shù)據(jù)庫讀,但寫入緩存;

  3. 逐個客戶端通知使用新配置。

Memcache 設(shè)計得比較早,導(dǎo)致在伸縮性高可用方面的考慮得不太周到。Redis 在這方面有不少改進,特別是 @ngaut 團隊基于 redis 開發(fā)了 codis 這個軟件,一次性地解決了緩存層的絕大部分問題。推薦大家考察一下。

數(shù)據(jù)庫

在數(shù)據(jù)庫層面實現(xiàn)伸縮,方法很多,文檔也很多,此處不做過多贅述。大致方法為:水平拆分、垂直拆分和定期滾動。

總之,我們可以在入口層、業(yè)務(wù)層面、緩存層和數(shù)據(jù)庫層四個層面,使用剛才介紹的方法和技術(shù)實現(xiàn)系統(tǒng)高可用和可伸縮性。具體為:在入口層用心跳來做到 高可用,用平行部署來伸縮;在業(yè)務(wù)層做到服務(wù)無狀態(tài);在緩存層,可以減小一些粒度,以方便實現(xiàn)高可用,使用一致性Hash將有助于實現(xiàn)緩存層的伸縮性;數(shù) 據(jù)庫層的主從模式能解決高可用問題,拆分和滾動能解決可伸縮問題。

本文中分享的這些技巧和方法,主要想幫助不太復(fù)雜的業(yè)務(wù)場景或者中小型應(yīng)用快速搭建起高可用可伸縮的系統(tǒng)。關(guān)于如何構(gòu)建高可用和可伸縮系統(tǒng)還有很多更為細節(jié)的點和實踐經(jīng)驗值得探討,望以后能與大家做更充分的交流。

責(zé)任編輯:王雪燕 來源: 李道兵
相關(guān)推薦

2013-05-30 10:20:39

系統(tǒng)架構(gòu)

2011-09-09 09:50:40

Oracle

2011-04-29 10:58:22

激光打印機

2016-01-11 11:20:43

2024-05-28 07:01:29

2009-09-14 15:04:44

2023-08-25 15:11:00

2010-01-14 20:05:43

虛擬化數(shù)據(jù)中心

2018-10-29 11:41:22

架構(gòu)MVCAndroid

2011-08-15 10:27:48

2014-03-13 09:20:38

jQueryAngularJs

2011-06-21 16:26:19

SEO內(nèi)部優(yōu)化

2013-08-02 11:23:45

2017-01-20 09:43:12

日志告警挖掘

2009-06-29 15:39:53

Servlet和JSPServlet引擎

2012-07-13 14:25:59

2015-09-16 10:13:16

游戲性能

2010-08-17 13:23:49

2009-11-02 11:11:07

VB.NET OOP設(shè)

2012-06-18 10:59:12

WEB開發(fā)項目
點贊
收藏

51CTO技術(shù)棧公眾號