国产精品免费久久久久电影院_亚洲日韩蜜桃av无码一二三区_AV在线无码免费特黄毛片_亚洲欧美日韩电影在线专区_福利小视频午夜福利一区二区中文字幕_在线免费观看黄黄色视频_欧美菊爆视频在线观看免费_婷婷六月丁香五月_久久伊人精品中文字幕有码_强奸国产无码激情

一個(gè)好的高并發(fā)架構(gòu)應(yīng)該滿足什么條件?

2022-04-29

1243

作者:樂魚創(chuàng)新 Alex


一個(gè)好的高并發(fā)架構(gòu)應(yīng)該滿足什么條件?

讓我們來聽聽高級(jí)云原生架構(gòu)師的“高并發(fā)之道”。


什么是高并發(fā)?

“什么是高并發(fā)?”這是一個(gè)經(jīng)常出現(xiàn)在面試過程中的問題,每個(gè)人理解不一樣,有一個(gè)理解大家應(yīng)該都認(rèn)同,那就是“短時(shí)間內(nèi)處理大量請(qǐng)求”,到底時(shí)間多短算短?請(qǐng)求量多大算大?這個(gè)得根據(jù)業(yè)務(wù)自身而定,通常會(huì)有一些壓測(cè)指標(biāo)來量化它們,例如TPS、QPS、響應(yīng)時(shí)間等。那么下面就來聊聊我對(duì)高并發(fā)的理解。


時(shí)空理論

一個(gè)系統(tǒng)的高并發(fā)能力,我覺得與兩個(gè)主要因素有關(guān),那就是這個(gè)系統(tǒng)對(duì)“時(shí)間”和“空間”的處理能力,“時(shí)間”指的是系統(tǒng)的處理時(shí)間或者響應(yīng)時(shí)間,“空間”指的是這個(gè)系統(tǒng)的并行處理能力。這兩個(gè)指標(biāo)決定了一個(gè)系統(tǒng)的高并發(fā)處理能力。總體上講,并發(fā)能力的公式大概就是“并發(fā)能力≈空間÷時(shí)間”,跟空間成正比,跟時(shí)間成反比,空間越大并發(fā)能力越強(qiáng),時(shí)間越小并發(fā)能力越強(qiáng)。影響這兩個(gè)因素的因子有很多,涉及到的技術(shù)層面也很廣,接下來慢慢聊。


時(shí)間

時(shí)間指系統(tǒng)響應(yīng)時(shí)間,如果你的系統(tǒng)是實(shí)時(shí)系統(tǒng),那么這個(gè)因素對(duì)于你的系統(tǒng)來說非常重要,是需要優(yōu)先考慮的因素,也是影響系統(tǒng)并發(fā)能力的主要因素,對(duì)系統(tǒng)優(yōu)化而言,這個(gè)是最容易去優(yōu)化的。跟響應(yīng)時(shí)間有關(guān)的影響因子非常多,我們可以從底層的服務(wù)器運(yùn)行的環(huán)境著手看這個(gè)問題,從服務(wù)器硬件資源的角度講,與系統(tǒng)性能緊緊相關(guān)的有:CPU、內(nèi)存、網(wǎng)絡(luò)、磁盤。


磁盤

首先說說磁盤,磁盤IO是最昂貴的資源,對(duì)系統(tǒng)響應(yīng)時(shí)間影響最大,網(wǎng)絡(luò)次之,內(nèi)存和CPU相對(duì)較好。所以要提高系統(tǒng)的響應(yīng)時(shí)間,我們應(yīng)該避免直接使用磁盤這個(gè)系統(tǒng)資源,通過資源轉(zhuǎn)換的方式,將磁盤資源轉(zhuǎn)換成更廉價(jià),性能更好的資源,例如內(nèi)存。像一些熱點(diǎn)數(shù)據(jù),放在集中緩存里面,對(duì)系統(tǒng)的“時(shí)間”因素影響特別大,這就是用內(nèi)存換磁盤的一種方式,用更廉價(jià)效率更高的資源去優(yōu)化系統(tǒng)瓶頸。磁盤往往是一個(gè)系統(tǒng)最主要的性能瓶頸,這里說的磁盤不是說磁盤的存儲(chǔ)能力,而是磁盤的IO能力,磁盤IO要優(yōu)化的話,代價(jià)很高,做raid、SAS升級(jí)成SSD、磁盤陣列等等,要把磁盤IO提升一個(gè)等級(jí)的話,需要的資金也不少。所以如果遇到磁盤IO為瓶頸的時(shí)候,首先可以考慮使用其他系統(tǒng)資源來替代磁盤IO,從而達(dá)到優(yōu)化的目的,如果實(shí)在不行,只能考慮燒錢了。


網(wǎng)絡(luò)

其次的系統(tǒng)資源是網(wǎng)絡(luò),網(wǎng)絡(luò)指的是系統(tǒng)之間交互時(shí)候的網(wǎng)絡(luò)資源,與這個(gè)資源有關(guān)的例如網(wǎng)絡(luò)帶寬、網(wǎng)卡數(shù)、網(wǎng)絡(luò)收發(fā)包數(shù)等,這個(gè)資源也是很昂貴的,一個(gè)公司的網(wǎng)絡(luò)環(huán)境始終是有個(gè)上限的,要優(yōu)化網(wǎng)絡(luò)這塊的處理能力,方式也很多,節(jié)約帶寬,可以考慮數(shù)據(jù)壓縮,目前很多數(shù)據(jù)壓縮方式效率很高,壓縮比很大,這個(gè)是通過消耗CPU資源去換網(wǎng)絡(luò)資源,如果一個(gè)系統(tǒng)的CPU不吃緊,可以考慮這種方式。如果說節(jié)約網(wǎng)絡(luò)請(qǐng)求次數(shù),可以考慮批處理的方式來進(jìn)行網(wǎng)絡(luò)請(qǐng)求發(fā)送,例如:數(shù)據(jù)庫請(qǐng)求的batch,一次處理一批數(shù)據(jù),減少網(wǎng)絡(luò)IO次數(shù);Redis通過管道的方式,一次處理多條數(shù)據(jù);數(shù)據(jù)聚合,將原本分散而又關(guān)聯(lián)的數(shù)據(jù),聚合到一起存儲(chǔ),減少請(qǐng)求次數(shù)。另外一種節(jié)約網(wǎng)絡(luò)資源的做法就是,就是用內(nèi)存資源去換網(wǎng)絡(luò)資源,在應(yīng)用實(shí)體節(jié)點(diǎn)內(nèi),啟用本地緩存的方式(例如EHCache),來存儲(chǔ)一些不易變化的數(shù)據(jù),請(qǐng)求的時(shí)候先到本地緩存找,再通過網(wǎng)絡(luò)到其他服務(wù)器上找,這種方式可以帶來很大的性能提升,當(dāng)然要實(shí)現(xiàn)這種方式,得考慮很多問題,例如每個(gè)實(shí)例內(nèi)部數(shù)據(jù)一致性的問題,數(shù)據(jù)更新問題,系統(tǒng)會(huì)變得更復(fù)雜。


CPU

CPU資源也是非常昂貴的,如果是計(jì)算密集型的系統(tǒng),那么服務(wù)器的CPU計(jì)算能力直接關(guān)系到這個(gè)系統(tǒng)的處理能力,要優(yōu)化CPU的處理能力,可以從多個(gè)角度入手,優(yōu)化的方式也很多,一般我們可以考慮從應(yīng)用本身來進(jìn)行優(yōu)化,這是一種至頂向下的優(yōu)化方式。從應(yīng)用本身的角度來講,優(yōu)化CPU的處理能力,那么就是考慮如何使用CPU資源來完成我們的任務(wù),也就是說如何設(shè)計(jì)系統(tǒng)內(nèi)部線程的執(zhí)行方式、鎖的使用等。應(yīng)用程序內(nèi)部的線程結(jié)構(gòu)設(shè)計(jì),目前有很多種比較流行的,例如基于線程、事件驅(qū)動(dòng)、SEDA等,我本身比較偏向第三種SEDA(不懂的自行百度)。我覺得SEDA更適合將系統(tǒng)模塊化,讓系統(tǒng)的復(fù)用性、擴(kuò)展性更強(qiáng),讓系統(tǒng)處理更加靈活。  


當(dāng)然應(yīng)用內(nèi)部的線程結(jié)構(gòu)只是其一,還有就是鎖的使用,這個(gè)鎖指的是應(yīng)用進(jìn)程內(nèi)的鎖,這個(gè)也是普遍比較關(guān)心的問題。鎖不能亂用、不能濫用,執(zhí)行線程被block住過后,會(huì)進(jìn)行線程切換,都知道CPU計(jì)算是基于時(shí)間片輪轉(zhuǎn)的,在線程切換會(huì)浪費(fèi)CPU時(shí)鐘,浪費(fèi)CPU資源,如果系統(tǒng)內(nèi)部經(jīng)常進(jìn)行線程切換,那并發(fā)能力會(huì)大打折扣。不管其他人怎么說,我個(gè)人倡導(dǎo),能不用鎖就不用鎖。

首先,我們要明白鎖的作用,為什么要使用鎖?這個(gè)得從底層的技術(shù)說起,我目前所用的開發(fā)語言是java,所以我說的都是基于java語言的。java語言的內(nèi)存模型中,有堆和棧兩個(gè)區(qū)域(JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)還有其他區(qū)域,例如方法區(qū)、本地方法區(qū)、程序計(jì)數(shù)區(qū)),堆是常說的主內(nèi)存,這個(gè)區(qū)域是線程共享的,棧呢,是線程間隔離的,也就是線程獨(dú)享的。我們有一個(gè)對(duì)象的屬性,是存放在堆中的,線程要使用的時(shí)候,需要進(jìn)行數(shù)據(jù)交換,把數(shù)據(jù)從堆中讀取到棧中,計(jì)算完成后,再進(jìn)行賦值,回寫到堆中,整個(gè)過程是Read-Load,Use-Assign,Store-Write。整個(gè)過程,棧上計(jì)算是獨(dú)立的,所以當(dāng)多個(gè)線程同時(shí)對(duì)一個(gè)變量進(jìn)行賦值的時(shí)候,會(huì)導(dǎo)致變量值被覆蓋。這時(shí)候,就需要對(duì)這個(gè)處理過程加鎖,鎖的作用就是控制資源競(jìng)爭(zhēng),加鎖過后,多個(gè)線程對(duì)這個(gè)資源的操作就只能串行處理,等第一個(gè)線程執(zhí)行完后,才能執(zhí)行第二個(gè)線程。明白鎖的作用后,就可以考慮從程序設(shè)計(jì)的角度,來合理的規(guī)避這個(gè)問題,例如通過引入隊(duì)列的方式將并行處理的業(yè)務(wù)串行化,讓單線程去處理。這里引入一個(gè)題外話,Disruptor在這方面做得非常好,整個(gè)高并發(fā)架構(gòu)是無鎖化的,緩存行填充、偽共享、內(nèi)存屏障用的恰到好處,有興趣的可以去觀摩一下。 


如果說在某些場(chǎng)景下,必須要使用鎖,那么使用的時(shí)候一定要謹(jǐn)慎,我大概總結(jié)了一下:  

1、最好不要在method上面加鎖,如果當(dāng)前整個(gè)method內(nèi)部都是需要同步的,那你能保證以后這個(gè)method內(nèi)部也都是需要同步的嗎?  

2、synchronized和lock的選擇,synchronized關(guān)鍵字是由JVM來控制內(nèi)部執(zhí)行的,目前也進(jìn)行了大量?jī)?yōu)化,個(gè)人感覺效率比lock要高。Lock是Concurrent包里面提供的,由JDK提供的鎖,這個(gè)使用非常靈活,適合復(fù)雜的業(yè)務(wù)場(chǎng)景,但是這個(gè)lock一定要在try-finally中關(guān)閉,防止鎖死。所以一些簡(jiǎn)單的業(yè)務(wù)場(chǎng)景,可以使用synchronized關(guān)鍵字,復(fù)雜的場(chǎng)景可以考慮使用lock。  

3、CAS的使用,CAS效率比鎖要高很多,CAS全稱是compare and swap,什么是CAS自行百度。  

4、優(yōu)化鎖的使用,如果Concurrent包中提供了一些支持高并發(fā)的容器,例如ConcurrentHashMap,適合多線程并發(fā)讀寫的場(chǎng)景,能用還是盡量用(如果基本都是讀,很少有改動(dòng),那么可以考慮COW + HashMap的方式)。  

5、可以考慮使用COW的方式來減少鎖的使用,COW即copy on write,這個(gè)適合讀多寫少的場(chǎng)景,具體實(shí)現(xiàn)自行百度。google的guava包中也提供了類似的容器,例如Lists.newCopyOnWriteArrayList,就提供了一個(gè)COW的list容器。另外Concurrent包中提供的讀寫鎖,在讀多寫少的場(chǎng)景下效率很高。當(dāng)然還有其他的一些優(yōu)化,例如volatile關(guān)鍵字的使用(內(nèi)存屏障這個(gè)比較難理解,不太適合一般開發(fā)人員,如果不懂,就不要用)、代碼中的屬性定義排序問題,相同使用的屬性應(yīng)當(dāng)寫在一起(跟CPU緩存加載機(jī)制有關(guān),可以參考disruptor的緩存行填充)等等,優(yōu)化機(jī)制非常多,推薦一本書《Java性能優(yōu)化權(quán)威指南》。

上面從線程并發(fā)結(jié)構(gòu)到鎖的使用,簡(jiǎn)單的介紹了一下應(yīng)用程序內(nèi)CPU資源的優(yōu)化,CPU這塊其實(shí)也可以優(yōu)化底層,不過一般公司都沒有這么去做,我們現(xiàn)在用的服務(wù)器,CPU一個(gè)核一般適合1-2個(gè)線程的并行執(zhí)行,所以我們?cè)谠O(shè)置計(jì)算型模塊的線程數(shù)的時(shí)候,一般為cpu的核數(shù)×2,但是甲骨文提供了SPARC T系列的CPU,支持一個(gè)核4-8個(gè)線程并行執(zhí)行,大大增強(qiáng)了CPU的并行處理能力,適合高并發(fā)的應(yīng)用。不過SPARC T系列的CPU核支持的線程再多,性價(jià)比也不如基于顯卡GPU加速來得高,一個(gè)好一點(diǎn)的顯卡,都是成千上萬個(gè)核,并發(fā)能力是CPU沒法比的,個(gè)人感覺基于GPU的計(jì)算是一個(gè)趨勢(shì),目前有很多數(shù)據(jù)庫已經(jīng)使用GPU進(jìn)行計(jì)算加速了,例如MapD。


內(nèi)存

內(nèi)存對(duì)于服務(wù)器資源來說,是最廉價(jià)的,通常用來換取其他系統(tǒng)資源,提升系統(tǒng)處理能力,例如內(nèi)存換磁盤,內(nèi)存換網(wǎng)絡(luò)??傮w來說,內(nèi)存很少成為系統(tǒng)的瓶頸。

上面說了一些關(guān)于時(shí)間因素的優(yōu)化方式,只是個(gè)人的理解和總結(jié),本人才疏學(xué)淺,不能面面俱到(例如分布式這塊,將一個(gè)大任務(wù)分布到N個(gè)節(jié)點(diǎn)上執(zhí)行,利用集群處理加快響應(yīng)時(shí)間),如果有地方寫得不對(duì),還請(qǐng)斧正。


空間

空間,指的是一個(gè)系統(tǒng)請(qǐng)求的并行執(zhí)行能力,相當(dāng)于網(wǎng)絡(luò)的帶寬一樣,一次能同時(shí)處理多少個(gè)請(qǐng)求。目前空間的優(yōu)化機(jī)制非常多,最常用的肯定是做集群,通過負(fù)載均衡+集群進(jìn)行橫向擴(kuò)展,支持集群的應(yīng)用系統(tǒng)最好是無狀態(tài)的。當(dāng)然縱向擴(kuò)展也行,通過升級(jí)服務(wù)器的硬件設(shè)備,也能達(dá)到增加并行處理的能力。增加服務(wù)器數(shù)量、升級(jí)服務(wù)器配置的方式,是擴(kuò)展整個(gè)系統(tǒng)應(yīng)用并發(fā)能力最直接的方式,也是最普遍的方式。如果一個(gè)應(yīng)用程序有狀態(tài),例如我之前做過一個(gè)應(yīng)用程序,應(yīng)用的請(qǐng)求是有狀態(tài)的,每個(gè)用戶的請(qǐng)求必須要按順序依次處理,這時(shí)候就需要做進(jìn)程間的并發(fā)控制了,讓請(qǐng)求在多個(gè)進(jìn)程中有序的處理。如果是這樣的系統(tǒng)架構(gòu),那么服務(wù)器的橫向擴(kuò)展或者縱向擴(kuò)展對(duì)于整個(gè)系統(tǒng)的并發(fā)能力的影響程度有多大,還得看系統(tǒng)架構(gòu)是怎么設(shè)計(jì)的了,具體的設(shè)計(jì)不在此討論,另外寫一篇文章專門討論跨進(jìn)程的并發(fā)控制。  通過服務(wù)器節(jié)點(diǎn)橫向擴(kuò)展,服務(wù)器硬件縱向擴(kuò)展,可以直接擴(kuò)展整個(gè)集群的并行處理能力,這個(gè)是最簡(jiǎn)單的方式,當(dāng)然也可以通過優(yōu)化應(yīng)用程序本身來提高應(yīng)用程序的并行處理能力,這個(gè)涉及到應(yīng)用程序內(nèi)部的線程結(jié)構(gòu)設(shè)計(jì),在上面CPU部分談了一下,如果是IO型的應(yīng)用,那么適合基于線程的并發(fā)結(jié)構(gòu),如果是計(jì)算密集型的,那么適合SEDA這種線程并發(fā)結(jié)構(gòu)。例如SpringBoot提供了對(duì)應(yīng)的兩種處理框架,SpringBoot1.x,提供的SpringMVC,就是基于線程的并發(fā)結(jié)構(gòu),適合常規(guī)的基于請(qǐng)求-IO操作-應(yīng)答的IO型應(yīng)用程序,Springboot2.x提供的webflux,是基于reactor設(shè)計(jì)的高并發(fā)結(jié)構(gòu),內(nèi)部控制的線程的使用,提供了多種場(chǎng)景的scheduler,適合對(duì)cpu敏感的計(jì)算密集型應(yīng)用。注意,并不是說一個(gè)應(yīng)用程序內(nèi)部,線程越多越好,線程切換會(huì)消耗CPU時(shí)鐘,反而浪費(fèi)CPU資源,這個(gè)得結(jié)合自身應(yīng)用合理的設(shè)計(jì)。


總結(jié)

影響整個(gè)系統(tǒng)的并發(fā)能力有很多,以上都是個(gè)人見解,不代表權(quán)威,如果有地方寫得不合理或者有問題。就算一個(gè)系統(tǒng),在時(shí)間和空間上都處理的很好,一個(gè)好的高并發(fā)架構(gòu)應(yīng)用,還必須同時(shí)具備其他的能力,比如穩(wěn)定性、可靠性、魯棒性、擴(kuò)展性、自我恢復(fù)能力等等。同時(shí)現(xiàn)在還流行虛擬化、容器化,應(yīng)用程序的設(shè)計(jì)能否適應(yīng)潮流的發(fā)展?架構(gòu)之路,坎坷崎嶇,任重而道遠(yuǎn)。


技術(shù)交流
我們建立了多個(gè)云原生技術(shù)交流群,其中有來自O(shè)racle、Citrix、華為、騰訊等國(guó)內(nèi)外云計(jì)算專家,立即掃碼,拉你進(jìn)群。目前已有2000+開發(fā)者加入我們......
云原生廠商 云原生技術(shù)服務(wù)商
在云原生時(shí)代,樂魚創(chuàng)新致力于通過賦能開發(fā)者,實(shí)現(xiàn)企業(yè)快速迭代與交付,大幅提升創(chuàng)新效率。
產(chǎn)品下載