高性能架構(gòu)模式

數(shù)據(jù)庫集群

讀寫分離速种,將訪問壓力分散到集群中的多個(gè)節(jié)點(diǎn),但是沒有分散存儲(chǔ)壓力

分庫分表径缅,既可以分散訪問壓力,又可以分散存儲(chǔ)壓力

另外可以先做以下處理后再進(jìn)行分庫分表設(shè)計(jì)

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

K-V 存儲(chǔ)(redis)

文檔數(shù)據(jù)庫(mongdb)

列式數(shù)據(jù)庫(hbase)

全文搜索引擎(elasticsearch)

高性能緩存架構(gòu)

緩存穿透

緩存雪崩

緩存熱點(diǎn)

單服務(wù)器高性能模式

PPC

TPC

Reactor

Proactor

高性能負(fù)載均衡

DNS 負(fù)載均衡

硬件負(fù)載均衡

軟件負(fù)載均衡

典型架構(gòu)

日活千萬的論壇舉例

算法

輪詢

加權(quán)輪詢

負(fù)載最低優(yōu)先

性能最優(yōu)

Hash類

數(shù)據(jù)庫集群

讀寫分離烙肺,將訪問壓力分散到集群中的多個(gè)節(jié)點(diǎn)纳猪,但是沒有分散存儲(chǔ)壓力

一般采用主從集群,寫在主桃笙,讀在從氏堤;但是引入了主從復(fù)制延遲和分配機(jī)制

主從復(fù)制延遲:主從數(shù)據(jù)同步總是有時(shí)間間隔;解決方法:

1. 寫操作后的讀操作指定發(fā)給數(shù)據(jù)庫主服務(wù)器

2. 讀從機(jī)失敗后再讀一次主機(jī)

3. 關(guān)鍵業(yè)務(wù)讀寫操作全部指向主機(jī)怎栽,非關(guān)鍵業(yè)務(wù)采用讀寫分離

分配機(jī)制:將讀寫操作區(qū)分開來丽猬,然后訪問不同的數(shù)據(jù)庫服務(wù)器,

1熏瞄、程序代碼封裝脚祟,指在代碼中抽象一個(gè)數(shù)據(jù)訪問層(所以有的文章也稱這種方式為“中間層封裝”),實(shí)現(xiàn)讀寫操作分離和數(shù)據(jù)庫服務(wù)器連接的管理强饮。比如Hibernate由桌,配置不同的數(shù)據(jù)庫連接池,淘寶的 TDDL

2. 中間件封裝,指的是獨(dú)立一套系統(tǒng)出來行您,實(shí)現(xiàn)讀寫操作分離和數(shù)據(jù)庫服務(wù)器連接的管理铭乾。比如MySQL Router,奇虎360的Atlas娃循,Atlas 是基于 MySQL Proxy

讀寫分離炕檩,分散了數(shù)據(jù)庫讀寫操作的壓力,但沒有分散存儲(chǔ)壓力捌斧,當(dāng)數(shù)據(jù)量達(dá)到千萬甚至上億條的時(shí)候笛质,單臺(tái)數(shù)據(jù)庫服務(wù)器的存儲(chǔ)能力會(huì)成為系統(tǒng)的瓶頸。

分庫分表捞蚂,既可以分散訪問壓力妇押,又可以分散存儲(chǔ)壓力

業(yè)務(wù)分庫,指的是按照業(yè)務(wù)模塊將數(shù)據(jù)分散到不同的數(shù)據(jù)庫服務(wù)器姓迅,分散了存儲(chǔ)帶來的壓力敲霍,也帶來了新的問題

1.join 操作問題

2. 事務(wù)問題

3. 成本問題

分表,將不同業(yè)務(wù)數(shù)據(jù)分散存儲(chǔ)到不同的數(shù)據(jù)庫服務(wù)器丁存,能夠支撐百萬甚至千萬用戶規(guī)模的業(yè)務(wù)肩杈。單表數(shù)據(jù)拆分有兩種方式:垂直分表和水平分表

垂直分表適合將表中某些不常用且占了大量空間的列拆分出去,引入的復(fù)雜性主要體現(xiàn)在表操作的數(shù)量要增加

水平分表適合表行數(shù)特別大的表柱嫌,有的公司要求單表行數(shù)超過 5000 萬就必須進(jìn)行分表锋恬,這個(gè)數(shù)字可以作為參考屯换,但并不是絕對標(biāo)準(zhǔn)编丘,關(guān)鍵還是要看表的訪問性能,需要引入路由

范圍路由:選取有序的數(shù)據(jù)列(例如彤悔,整形嘉抓、時(shí)間戳等)作為路由的條件,不同分段分散到不同的數(shù)據(jù)庫表中晕窑。

Hash 路由:選取某個(gè)列(或者某幾個(gè)列組合也可以)的值進(jìn)行 Hash 運(yùn)算抑片,然后根據(jù) Hash 結(jié)果分散到不同的數(shù)據(jù)庫表中。

配置路由:配置路由就是路由表杨赤,用一張獨(dú)立的表來記錄路由信息

分庫分表具體的實(shí)現(xiàn)方式也是“程序代碼封裝”和“中間件封裝”敞斋,但實(shí)現(xiàn)會(huì)更復(fù)雜。讀寫分離實(shí)現(xiàn)時(shí)只要識別 SQL 操作是讀操作還是寫操作疾牲,通過簡單的判斷 SELECT植捎、UPDATE、INSERT阳柔、DELETE 幾個(gè)關(guān)鍵字就可以做到焰枢,而分庫分表的實(shí)現(xiàn)除了要判斷操作類型外,還要判斷 SQL 中具體需要操作的表、操作函數(shù)(例如 count 函數(shù))济锄、order by暑椰、group by 操作等,然后再根據(jù)不同的操作進(jìn)行不同的處理荐绝。例如 order by 操作一汽,需要先從多個(gè)庫查詢到各個(gè)庫的數(shù)據(jù),然后再重新 order by 才能得到最終的結(jié)果低滩。

另外可以先做以下處理后再進(jìn)行分庫分表設(shè)計(jì)

1.做硬件優(yōu)化角虫,例如從機(jī)械硬盤改成使用固態(tài)硬盤,當(dāng)然固態(tài)硬盤不適合服務(wù)器使用委造,只是舉個(gè)例子2.先做數(shù)據(jù)庫服務(wù)器的調(diào)優(yōu)操作戳鹅,例如增加索引,oracle有很多的參數(shù)調(diào)整;3.引入緩存技術(shù)昏兆,例如Redis枫虏,減少數(shù)據(jù)庫壓力4.程序與數(shù)據(jù)庫表優(yōu)化,重構(gòu)爬虱,例如根據(jù)業(yè)務(wù)邏輯對程序邏輯做優(yōu)化隶债,減少不必要的查詢;5.在這些操作都不能大幅度優(yōu)化性能的情況下,不能滿足將來的發(fā)展跑筝,再考慮分庫分表死讹,也要有預(yù)估性

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

關(guān)系數(shù)據(jù)庫缺點(diǎn):

1、關(guān)系數(shù)據(jù)庫存儲(chǔ)的是行記錄曲梗,無法存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)

2赞警、關(guān)系數(shù)據(jù)庫的 schema 擴(kuò)展很不方便

3、關(guān)系數(shù)據(jù)庫在大數(shù)據(jù)場景下 I/O 較高

4虏两、關(guān)系數(shù)據(jù)庫的全文搜索功能比較弱

K-V 存儲(chǔ)(redis)

Redis 的 Value 是具體的數(shù)據(jù)結(jié)構(gòu)愧旦,包括 string、hash定罢、list笤虫、set、sorted set祖凫、bitmap 和 hyperloglog琼蚯,所以常常被稱為數(shù)據(jù)結(jié)構(gòu)服務(wù)器。

Redis 的缺點(diǎn)主要體現(xiàn)在并不支持完整的 ACID 事務(wù),Redis 雖然提供事務(wù)功能,但 Redis 的事務(wù)和關(guān)系數(shù)據(jù)庫的事務(wù)不可同日而語计贰,Redis 的事務(wù)只能保證隔離性和一致性(I 和 C)操禀,無法保證原子性和持久性(A 和 D)。

文檔數(shù)據(jù)庫(mongdb)

為了解決關(guān)系數(shù)據(jù)庫 schema 帶來的問題付魔,文檔數(shù)據(jù)庫應(yīng)運(yùn)而生愤兵。文檔數(shù)據(jù)庫最大的特點(diǎn)就是 no-schema铁蹈,可以存儲(chǔ)和讀取任意的數(shù)據(jù)

1. 新增字段簡單

2. 歷史數(shù)據(jù)不會(huì)出錯(cuò)

3. 可以很容易存儲(chǔ)復(fù)雜數(shù)據(jù)

它最主要的代價(jià)就是不支持事務(wù)赐俗,另外一個(gè)缺點(diǎn)就是無法實(shí)現(xiàn)關(guān)系數(shù)據(jù)庫的 join 操作拉队。

列式數(shù)據(jù)庫(hbase)

列式數(shù)據(jù)庫就是按照列來存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)庫,與之對應(yīng)的傳統(tǒng)關(guān)系數(shù)據(jù)庫被稱為“行式數(shù)據(jù)庫”阻逮,因?yàn)殛P(guān)系數(shù)據(jù)庫是按照行來存儲(chǔ)數(shù)據(jù)的粱快。

1、業(yè)務(wù)同時(shí)讀取多個(gè)列時(shí)效率高叔扼,因?yàn)檫@些列都是按行存儲(chǔ)在一起的事哭,一次磁盤操作就能夠把一行數(shù)據(jù)中的各個(gè)列都讀取到內(nèi)存中。

2瓜富、能夠一次性完成對一行中的多個(gè)列的寫操作鳍咱,保證了針對行數(shù)據(jù)寫操作的原子性和一致性;否則如果采用列存儲(chǔ)与柑,可能會(huì)出現(xiàn)某次寫操作谤辜,有的列成功了,有的列失敗了价捧,導(dǎo)致數(shù)據(jù)不一致丑念。

一般將列式存儲(chǔ)應(yīng)用在離線的大數(shù)據(jù)分析和統(tǒng)計(jì)場景中,因?yàn)檫@種場景主要是針對部分列單列進(jìn)行操作结蟋,且數(shù)據(jù)寫入后就無須再更新刪除脯倚。

全文搜索引擎(elasticsearch)

傳統(tǒng)的關(guān)系型數(shù)據(jù)庫通過索引來達(dá)到快速查詢的目的,但是在全文搜索的業(yè)務(wù)場景下嵌屎,索引也無能為力推正,主要體現(xiàn)在:

1、全文搜索的條件可以隨意排列組合编整,如果通過索引來滿足舔稀,則索引的數(shù)量會(huì)非常多乳丰。

2掌测、全文搜索的模糊匹配方式,索引無法滿足产园,只能用 like 查詢汞斧,而 like 查詢是整表掃描,效率非常低什燕。

全文搜索引擎的技術(shù)原理被稱為“倒排索引”(Inverted index)粘勒,也常被稱為反向索引、置入檔案或反向檔案屎即,是一種索引方法庙睡,其基本原理是建立單詞到文檔的索引事富。

全文搜索引擎的索引對象是單詞和文檔,而關(guān)系數(shù)據(jù)庫的索引對象是鍵和行乘陪,兩者的術(shù)語差異很大统台,不能簡單地等同起來。因此啡邑,為了讓全文搜索引擎支持關(guān)系型數(shù)據(jù)的全文搜索贱勃,需要做一些轉(zhuǎn)換操作,即將關(guān)系型數(shù)據(jù)轉(zhuǎn)換為文檔數(shù)據(jù)谤逼。

高性能緩存架構(gòu)

雖然我們可以通過各種手段來提升存儲(chǔ)系統(tǒng)的性能贵扰,但在某些復(fù)雜的業(yè)務(wù)場景下,單純依靠存儲(chǔ)系統(tǒng)的性能提升不夠的流部,典型的場景有:

a戚绕、需要經(jīng)過復(fù)雜運(yùn)算后得出的數(shù)據(jù),存儲(chǔ)系統(tǒng)無能為力

b枝冀、讀多寫少的數(shù)據(jù)列肢,存儲(chǔ)系統(tǒng)有心無力

緩存就是為了彌補(bǔ)存儲(chǔ)系統(tǒng)在這些復(fù)雜業(yè)務(wù)場景下的不足,其基本原理是將可能重復(fù)使用的數(shù)據(jù)放到內(nèi)存中宾茂,一次生成瓷马、多次使用,避免每次使用都去訪問存儲(chǔ)系統(tǒng)

緩存架構(gòu)設(shè)計(jì)要點(diǎn):

緩存穿透

緩存穿透是指緩存沒有發(fā)揮作用跨晴,業(yè)務(wù)系統(tǒng)雖然去緩存查詢數(shù)據(jù)欧聘,但緩存中沒有數(shù)據(jù),業(yè)務(wù)系統(tǒng)需要再次去存儲(chǔ)系統(tǒng)查詢數(shù)據(jù)端盆。通常情況下有兩種情況:

1. 存儲(chǔ)數(shù)據(jù)不存在怀骤。這種情況的解決辦法比較簡單,如果查詢存儲(chǔ)系統(tǒng)的數(shù)據(jù)沒有找到焕妙,則直接設(shè)置一個(gè)默認(rèn)值(可以是空值蒋伦,也可以是具體的值)存到緩存中,這樣第二次讀取緩存時(shí)就會(huì)獲取到默認(rèn)值焚鹊,而不會(huì)繼續(xù)訪問存儲(chǔ)系統(tǒng)痕届。

2. 緩存數(shù)據(jù)生成耗費(fèi)大量時(shí)間或者資源。業(yè)務(wù)上最簡單的就是每次點(diǎn)擊分頁的時(shí)候按分頁計(jì)算和生成緩存末患。通常情況下這樣實(shí)現(xiàn)是基本滿足要求的研叫,但是如果被競爭對手用爬蟲來遍歷的時(shí)候,系統(tǒng)性能就可能出現(xiàn)問題璧针。沒有太好的解決方案嚷炉,主要還是監(jiān)控處理了。

緩存雪崩

緩存雪崩是指當(dāng)緩存失效(過期)后引起系統(tǒng)性能急劇下降的情況探橱。當(dāng)緩存過期被清除后申屹,業(yè)務(wù)系統(tǒng)需要重新生成緩存绘证,因此需要再次訪問存儲(chǔ)系統(tǒng),再次進(jìn)行運(yùn)算哗讥,這個(gè)處理步驟耗時(shí)幾十毫秒甚至上百毫秒迈窟。高并發(fā)時(shí),都去訪問存儲(chǔ)系統(tǒng)忌栅,壓力太大车酣,拖慢整個(gè)系統(tǒng)。

常見解決方法有兩種:

1. 更新鎖索绪。對緩存更新操作進(jìn)行加鎖保護(hù)湖员,保證只有一個(gè)線程能夠進(jìn)行緩存更新,未能獲取更新鎖的線程要么等待鎖釋放后重新讀取緩存瑞驱,要么就返回空值或者默認(rèn)值娘摔。分布式集群的業(yè)務(wù)系統(tǒng)要實(shí)現(xiàn)更新鎖機(jī)制,需要用到分布式鎖

2. 后臺(tái)更新唤反。由后臺(tái)線程來更新緩存凳寺,而不是由業(yè)務(wù)線程來更新緩存,緩存本身的有效期設(shè)置為永久彤侍,后臺(tái)線程定時(shí)更新緩存肠缨。

后臺(tái)線程除了定時(shí)更新緩存,還要頻繁地去讀取緩存(例如盏阶,1 秒或者 100 毫秒讀取一次)晒奕,如果發(fā)現(xiàn)緩存被“踢了”就立刻更新緩存,這種方式實(shí)現(xiàn)簡單名斟,但讀取時(shí)間間隔不能設(shè)置太長或者業(yè)務(wù)線程發(fā)現(xiàn)緩存失效后脑慧,通過消息隊(duì)列發(fā)送一條消息通知后臺(tái)線程更新緩存。

緩存熱點(diǎn)

雖然緩存系統(tǒng)本身的性能比較高砰盐,但對于一些特別熱點(diǎn)的數(shù)據(jù)闷袒,如果大部分甚至所有的業(yè)務(wù)請求都命中同一份緩存數(shù)據(jù),則這份數(shù)據(jù)所在的緩存服務(wù)器的壓力也很大岩梳。緩存熱點(diǎn)的解決方案就是復(fù)制多份緩存副本囊骤,將請求分散到多個(gè)緩存服務(wù)器上,減輕緩存熱點(diǎn)導(dǎo)致的單臺(tái)緩存服務(wù)器壓力蒋腮。

緩存副本設(shè)計(jì)有一個(gè)細(xì)節(jié)需要注意淘捡,就是不同的緩存副本不要設(shè)置統(tǒng)一的過期時(shí)間,否則就會(huì)出現(xiàn)所有緩存副本同時(shí)生成同時(shí)失效的情況池摧,從而引發(fā)緩存雪崩效應(yīng)。正確的做法是設(shè)定一個(gè)過期時(shí)間范圍激况,不同的緩存副本的過期時(shí)間是指定范圍內(nèi)的隨機(jī)值作彤。

單服務(wù)器高性能模式

高并發(fā)需要根據(jù)兩個(gè)條件劃分:連接數(shù)量膘魄,請求數(shù)量。

1. 海量連接(成千上萬)海量請求:例如搶購竭讳,雙十一等

2. 常量連接(幾十上百)海量請求:例如中間件

3. 海量連接常量請求:例如門戶網(wǎng)站

4. 常量連接常量請求:例如內(nèi)部運(yùn)營系統(tǒng)创葡,管理系統(tǒng)

性能架構(gòu)設(shè)計(jì)主要集中在兩方面:

1、盡量提升單服務(wù)器的性能绢慢,將單服務(wù)器的性能發(fā)揮到極致灿渴。

2、如果單服務(wù)器無法支撐性能胰舆,設(shè)計(jì)服務(wù)器集群方案骚露。

架構(gòu)設(shè)計(jì)決定了系統(tǒng)性能的上限,實(shí)現(xiàn)細(xì)節(jié)決定了系統(tǒng)性能的下限

單服務(wù)器高性能的關(guān)鍵之一就是服務(wù)器采取的并發(fā)模型缚窿,并發(fā)模型有如下兩個(gè)關(guān)鍵設(shè)計(jì)點(diǎn):

1棘幸、服務(wù)器如何管理連接。

2倦零、服務(wù)器如何處理請求误续。

以上兩個(gè)設(shè)計(jì)點(diǎn)最終都和操作系統(tǒng)的 I/O 模型及進(jìn)程模型相關(guān)。

I/O 模型:阻塞扫茅、非阻塞蹋嵌、同步、異步葫隙。

進(jìn)程模型:單進(jìn)程欣尼、多進(jìn)程、多線程停蕉。

PPC

Process Per Connection 的縮寫愕鼓,其含義是指每次有新的連接就新建一個(gè)進(jìn)程去專門處理這個(gè)連接的請求,這是傳統(tǒng)的 UNIX 網(wǎng)絡(luò)服務(wù)器所采用的模型慧起。比較適合服務(wù)器的連接數(shù)沒那么多的情況菇晃,例如數(shù)據(jù)庫服務(wù)器。缺點(diǎn):父進(jìn)程fork子進(jìn)程 代價(jià)高蚓挤;父子進(jìn)程通信復(fù)雜磺送;支持的并發(fā)連接數(shù)量有限。

prefork 就是提前創(chuàng)建進(jìn)程(pre-fork)灿意。系統(tǒng)在啟動(dòng)的時(shí)候就預(yù)先創(chuàng)建好進(jìn)程估灿,然后才開始接受用戶的請求,當(dāng)有新的連接進(jìn)來的時(shí)候缤剧,就可以省去 fork 進(jìn)程的操作馅袁,讓用戶訪問更快、體驗(yàn)更好荒辕。還是存在父子進(jìn)程通信復(fù)雜汗销、支持的并發(fā)連接數(shù)量有限的問題

TPC

TPC 是 Thread Per Connection 的縮寫犹褒,其含義是指每次有新的連接就新建一個(gè)線程去專門處理這個(gè)連接的請求。引入了新問題

創(chuàng)建線程雖然比創(chuàng)建進(jìn)程代價(jià)低弛针,但并不是沒有代價(jià)叠骑,高并發(fā)時(shí)(例如每秒上萬連接)還是有性能問題。無須進(jìn)程間通信削茁,但是線程間的互斥和共享又引入了復(fù)雜度宙枷,可能一不小心就導(dǎo)致了死鎖問題。多線程會(huì)出現(xiàn)互相影響的情況茧跋,某個(gè)線程出現(xiàn)異常時(shí)慰丛,可能導(dǎo)致整個(gè)進(jìn)程退出(例如內(nèi)存越界)。prethread 模式會(huì)預(yù)先創(chuàng)建線程厌衔,然后才開始接受用戶的請求璧帝,當(dāng)有新的連接進(jìn)來的時(shí)候,就可以省去創(chuàng)建線程的操作富寿,讓用戶感覺更快睬隶、體驗(yàn)更好。

Reactor

Reactor 模式的核心組成部分包括 Reactor 和處理資源池(進(jìn)程池或線程池)页徐,其中 Reactor 負(fù)責(zé)監(jiān)聽和分配事件苏潜,處理資源池負(fù)責(zé)處理事件。Reactor 模式的具體實(shí)現(xiàn)方案靈活多變变勇,主要體現(xiàn)在:

1恤左、Reactor 的數(shù)量可以變化:可以是一個(gè) Reactor,也可以是多個(gè) Reactor搀绣。

2飞袋、資源池的數(shù)量可以變化:以進(jìn)程為例,可以是單個(gè)進(jìn)程链患,也可以是多個(gè)進(jìn)程(線程類似)巧鸭。

最終 Reactor 模式有這三種典型的實(shí)現(xiàn)方案:單 Reactor 單進(jìn)程 / 線程。單 Reactor 多線程麻捻。多 Reactor 多進(jìn)程 / 線程纲仍。

單 Reactor 單進(jìn)程 / 線程整個(gè)流程:Reactor 對象通過 select 監(jiān)控連接事件,收到事件后通過 dispatch 進(jìn)行分發(fā)贸毕。如果是連接建立的事件郑叠,則由 Acceptor 處理,Acceptor 通過 accept 接受連接明棍,并創(chuàng)建一個(gè) Handler 來處理連接后續(xù)的各種事件乡革。如果不是連接建立事件,則 Reactor 會(huì)調(diào)用連接對應(yīng)的 Handler(第 2 步中創(chuàng)建的 Handler)來進(jìn)行響應(yīng)。Handler 會(huì)完成 read-> 業(yè)務(wù)處理 ->send 的完整業(yè)務(wù)流程署拟。

單 Reactor 單進(jìn)程的方案在實(shí)踐中應(yīng)用場景不多婉宰,只適用于業(yè)務(wù)處理非掣璨颍快速的場景推穷,目前比較著名的開源軟件中使用單 Reactor 單進(jìn)程的是 Redis。

單 Reactor 多線程:主線程中类咧,Reactor 對象通過 select 監(jiān)控連接事件馒铃,收到事件后通過 dispatch 進(jìn)行分發(fā)。如果是連接建立的事件痕惋,則由 Acceptor 處理区宇,Acceptor 通過 accept 接受連接,并創(chuàng)建一個(gè) Handler 來處理連接后續(xù)的各種事件值戳。如果不是連接建立事件议谷,則 Reactor 會(huì)調(diào)用連接對應(yīng)的 Handler(第 2 步中創(chuàng)建的 Handler)來進(jìn)行響應(yīng)。Handler 只負(fù)責(zé)響應(yīng)事件堕虹,不進(jìn)行業(yè)務(wù)處理卧晓;Handler 通過 read 讀取到數(shù)據(jù)后,會(huì)發(fā)給 Processor 進(jìn)行業(yè)務(wù)處理赴捞。Processor 會(huì)在獨(dú)立的子線程中完成真正的業(yè)務(wù)處理逼裆,然后將響應(yīng)結(jié)果發(fā)給主進(jìn)程的 Handler 處理;Handler 收到響應(yīng)后通過 send 將響應(yīng)結(jié)果返回給 client赦政。

多 Reactor 多進(jìn)程 / 線程:父進(jìn)程中 mainReactor 對象通過 select 監(jiān)控連接建立事件胜宇,收到事件后通過 Acceptor 接收,將新的連接分配給某個(gè)子進(jìn)程恢着。子進(jìn)程的 subReactor 將 mainReactor 分配的連接加入連接隊(duì)列進(jìn)行監(jiān)聽桐愉,并創(chuàng)建一個(gè) Handler 用于處理連接的各種事件。當(dāng)有新的事件發(fā)生時(shí)掰派,subReactor 會(huì)調(diào)用連接對應(yīng)的 Handler(即第 2 步中創(chuàng)建的 Handler)來進(jìn)行響應(yīng)从诲。Handler 完成 read→業(yè)務(wù)處理→send 的完整業(yè)務(wù)流程。目前著名的開源系統(tǒng) Nginx 采用的是多 Reactor 多進(jìn)程碗淌,采用多 Reactor 多線程的實(shí)現(xiàn)有 Memcache 和 Netty盏求。

Proactor

可以理解為“來了事件我來處理,處理完了我通知你”亿眠。這里的“我”就是操作系統(tǒng)內(nèi)核碎罚,“事件”就是有新連接、有數(shù)據(jù)可讀纳像、有數(shù)據(jù)可寫的這些 I/O 事件荆烈,“你”就是我們的程序代碼。


Proactor Initiator 負(fù)責(zé)創(chuàng)建 Proactor 和 Handler,并將 Proactor 和 Handler 都通過 Asynchronous Operation Processor 注冊到內(nèi)核憔购。

Asynchronous Operation Processor 負(fù)責(zé)處理注冊請求宫峦,并完成 I/O 操作。

Asynchronous Operation Processor 完成 I/O 操作后通知 Proactor玫鸟。

Proactor 根據(jù)不同的事件類型回調(diào)不同的 Handler 進(jìn)行業(yè)務(wù)處理导绷。

Handler 完成業(yè)務(wù)處理,Handler 也可以注冊新的 Handler 到內(nèi)核進(jìn)程屎飘。

高性能負(fù)載均衡

高性能集群的本質(zhì)很簡單妥曲,通過增加更多的服務(wù)器來提升系統(tǒng)整體的計(jì)算能力。它的復(fù)雜性主要體現(xiàn)在需要增加一個(gè)任務(wù)分配器钦购,以及為任務(wù)選擇一個(gè)合適的任務(wù)分配算法檐盟。對于任務(wù)分配器,現(xiàn)在更流行的通用叫法是“負(fù)載均衡器”押桃。請謹(jǐn)記負(fù)載均衡不只是為了計(jì)算單元的負(fù)載達(dá)到均衡狀態(tài)葵萎。

常見的負(fù)載均衡系統(tǒng)包括 3 種:DNS 負(fù)載均衡、硬件負(fù)載均衡和軟件負(fù)載均衡唱凯。

DNS 負(fù)載均衡

DNS 是最簡單也是最常見的負(fù)載均衡方式羡忘,一般用來實(shí)現(xiàn)地理級別的均衡。優(yōu)點(diǎn):簡單波丰、成本低壳坪,就近訪問,提升訪問速度掰烟。缺點(diǎn):更新不及時(shí)爽蝴;擴(kuò)展性差;分配策略比較簡單纫骑⌒牵可以針對業(yè)務(wù)開發(fā)自己的DNS服務(wù)

硬件負(fù)載均衡

硬件負(fù)載均衡是通過單獨(dú)的硬件設(shè)備來實(shí)現(xiàn)負(fù)載均衡功能,這類設(shè)備和路由器先馆、交換機(jī)類似发框,可以理解為一個(gè)用于負(fù)載均衡的基礎(chǔ)網(wǎng)絡(luò)設(shè)備。目前業(yè)界典型的硬件負(fù)載均衡設(shè)備有兩款:F5 和 A10煤墙。優(yōu)點(diǎn):功能強(qiáng)大梅惯;性能強(qiáng)大;穩(wěn)定性高仿野;支持安全防護(hù)铣减。缺點(diǎn):價(jià)格昂貴;擴(kuò)展能力差脚作。

軟件負(fù)載均衡

軟件負(fù)載均衡通過負(fù)載均衡軟件來實(shí)現(xiàn)負(fù)載均衡功能葫哗,常見的有 Nginx 和 LVS缔刹,其中 Nginx 是軟件的 7 層負(fù)載均衡,LVS 是 Linux 內(nèi)核的 4 層負(fù)載均衡劣针。4 層和 7 層的區(qū)別就在于協(xié)議和靈活性校镐,Nginx 支持 HTTP、E-mail 協(xié)議捺典;而 LVS 是 4 層負(fù)載均衡鸟廓,和協(xié)議無關(guān),幾乎所有應(yīng)用都可以做辣苏,例如肝箱,聊天哄褒、數(shù)據(jù)庫等稀蟋。性能比不上硬件

優(yōu)點(diǎn):簡單;便宜呐赡;靈活退客、

缺點(diǎn):性能一般;功能沒有硬件那么強(qiáng)大链嘀;一般不具備防火墻和防DDoS功能萌狂。

典型架構(gòu)

3種負(fù)載均衡組合使用;組合的基本原則為:DNS 負(fù)載均衡用于實(shí)現(xiàn)地理級別的負(fù)載均衡怀泊;硬件負(fù)載均衡用于實(shí)現(xiàn)集群級別的負(fù)載均衡茫藏;軟件負(fù)載均衡用于實(shí)現(xiàn)機(jī)器級別的負(fù)載均衡∨恚可參考下面示例


日活千萬的論壇舉例

1务傲、首先,流量評估枣申。

???????1000萬DAU售葡,換算成秒級,平均約等于116忠藤。

考慮每個(gè)用戶操作次數(shù)挟伙,假定10,換算成平均QPS=1160模孩。

???????考慮峰值是均值倍數(shù)尖阔,假定10,換算成峰值QPS=11600榨咐。

???????考慮靜態(tài)資源介却、圖片資源、服務(wù)拆分等祭芦,流量放大效應(yīng)筷笨,假定10,QPS*10=116000。

2胃夏、其次轴或,容量規(guī)劃。

???????考慮高可用仰禀、異地多活照雁,QPS*2=232000。

???????考慮未來半年增長答恶,QPS*1.5=348000饺蚊。

3、最后悬嗓,方案設(shè)計(jì)污呼。

???????三級導(dǎo)流。

???????第一級包竹,DNS燕酷,確定機(jī)房,以目前量級周瞎,可以不考慮苗缩。

???????第二級,確定集群声诸,擴(kuò)展優(yōu)先酱讶,則選Haproxy/LVS,穩(wěn)定優(yōu)先則選F5彼乌。

???????第三級泻肯,Nginx+KeepAlived,確定實(shí)例囤攀。

算法

負(fù)載均衡算法數(shù)量較多软免,而且可以根據(jù)一些業(yè)務(wù)特性進(jìn)行定制開發(fā),拋開細(xì)節(jié)上的差異焚挠,根據(jù)算法期望達(dá)到的目的膏萧,大體上可以分為下面幾類:任務(wù)平分類;負(fù)載均衡類蝌衔;性能最優(yōu)類榛泛;Hash類。

輪詢

負(fù)載均衡系統(tǒng)收到請求后噩斟,按照順序輪流分配到服務(wù)器上曹锨。只要服務(wù)器在運(yùn)行,運(yùn)行狀態(tài)是不關(guān)注的剃允∨婕颍總而言之齐鲤,“簡單”是輪詢算法的優(yōu)點(diǎn),也是它的缺點(diǎn)椒楣。

加權(quán)輪詢

負(fù)載均衡系統(tǒng)根據(jù)服務(wù)器權(quán)重進(jìn)行任務(wù)分配给郊,這里的權(quán)重一般是根據(jù)硬件配置進(jìn)行靜態(tài)配置的,采用動(dòng)態(tài)的方式計(jì)算會(huì)更加契合業(yè)務(wù)捧灰,但復(fù)雜度也會(huì)更高淆九。加權(quán)輪詢是輪詢的一種特殊形式,其主要目的就是為了解決不同服務(wù)器處理能力有差異的問題毛俏。

負(fù)載最低優(yōu)先

負(fù)載均衡系統(tǒng)將任務(wù)分配給當(dāng)前負(fù)載最低的服務(wù)器炭庙,這里的負(fù)載根據(jù)不同的任務(wù)類型和業(yè)務(wù)場景,可以用不同的指標(biāo)來衡量煌寇。負(fù)載最低優(yōu)先的算法解決了輪詢算法中無法感知服務(wù)器狀態(tài)的問題焕蹄,由此帶來的代價(jià)是復(fù)雜度要增加很多。負(fù)載最低優(yōu)先算法如果本身沒有設(shè)計(jì)好唧席,或者不適合業(yè)務(wù)的運(yùn)行特點(diǎn)擦盾,算法本身就可能成為性能的瓶頸,或者引發(fā)很多莫名其妙的問題淌哟。所以負(fù)載最低優(yōu)先算法雖然效果看起來很美好,但實(shí)際上真正應(yīng)用的場景反而沒有輪詢(包括加權(quán)輪詢)那么多辽故。

性能最優(yōu)

負(fù)載最低優(yōu)先類算法是站在服務(wù)器的角度來進(jìn)行分配的徒仓,而性能最優(yōu)優(yōu)先類算法則是站在客戶端的角度來進(jìn)行分配的,優(yōu)先將任務(wù)分配給處理速度最快的服務(wù)器誊垢,通過這種方式達(dá)到最快響應(yīng)客戶端的目的掉弛。和負(fù)載最低優(yōu)先類算法類似,性能最優(yōu)優(yōu)先類算法本質(zhì)上也是感知了服務(wù)器的狀態(tài)喂走,只是通過響應(yīng)時(shí)間這個(gè)外部標(biāo)準(zhǔn)來衡量服務(wù)器狀態(tài)而已

Hash類

負(fù)載均衡系統(tǒng)根據(jù)任務(wù)中的某些關(guān)鍵信息進(jìn)行 Hash 運(yùn)算殃饿,將相同 Hash 值的請求分配到同一臺(tái)服務(wù)器上,這樣做的目的主要是為了滿足特定的業(yè)務(wù)需求芋肠。常用的有源地址IPhash乎芳,ID hash等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市帖池,隨后出現(xiàn)的幾起案子奈惑,更是在濱河造成了極大的恐慌,老刑警劉巖睡汹,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肴甸,死亡現(xiàn)場離奇詭異,居然都是意外死亡囚巴,警方通過查閱死者的電腦和手機(jī)原在,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門友扰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人庶柿,你說我怎么就攤上這事焕檬。” “怎么了澳泵?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵实愚,是天一觀的道長。 經(jīng)常有香客問我兔辅,道長腊敲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任维苔,我火速辦了婚禮碰辅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘介时。我一直安慰自己没宾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布沸柔。 她就那樣靜靜地躺著循衰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪褐澎。 梳的紋絲不亂的頭發(fā)上会钝,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音工三,去河邊找鬼迁酸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛俭正,可吹牛的內(nèi)容都是我干的奸鬓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼掸读,長吁一口氣:“原來是場噩夢啊……” “哼串远!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寺枉,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤抑淫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后姥闪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體始苇,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年筐喳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了催式。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片函喉。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖荣月,靈堂內(nèi)的尸體忽然破棺而出管呵,到底是詐尸還是另有隱情,我是刑警寧澤哺窄,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布捐下,位于F島的核電站,受9級特大地震影響萌业,放射性物質(zhì)發(fā)生泄漏坷襟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一生年、第九天 我趴在偏房一處隱蔽的房頂上張望婴程。 院中可真熱鬧,春花似錦抱婉、人聲如沸档叔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衙四。三九已至,卻和暖如春侵贵,著一層夾襖步出監(jiān)牢的瞬間届搁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工窍育, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宴胧。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓漱抓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恕齐。 傳聞我的和親對象是個(gè)殘疾皇子乞娄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

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