當(dāng)服務(wù)QPS增高時(shí),我們做什么
2016-09-14 16:31:00 來(lái)源:來(lái)源:運(yùn)維幫 評(píng)論:0 點(diǎn)擊:
- 1 性能的關(guān)鍵指標(biāo)
- 2 服務(wù)化系統(tǒng)構(gòu)成模式
- 請(qǐng)求對(duì)系統(tǒng)資源的占用
- 請(qǐng)求對(duì)系統(tǒng)資源的占用
- 2.1 基礎(chǔ)服務(wù)
- 2.2 集成服務(wù)
- 2.3 混合服務(wù)
- 混合服務(wù)的資源消耗
- 2.4 系統(tǒng)資源消耗
- 3 常見(jiàn)系統(tǒng)優(yōu)化tips
- 3.1 代碼調(diào)優(yōu)
- 3.2 數(shù)據(jù)庫(kù)調(diào)優(yōu)
- References
這篇文章是在給團(tuán)隊(duì)中級(jí)初級(jí)開(kāi)發(fā)人員做的分享,相對(duì)比較淺。
很多同學(xué)在實(shí)際的開(kāi)發(fā)中害怕系統(tǒng)的QPS增高,因?yàn)橛X(jué)得QPS太高會(huì)導(dǎo)致系統(tǒng)掛掉;基于這種心理會(huì)想著盡量的降低系統(tǒng)的請(qǐng)求量,甚至有人會(huì)將很多處理放置到服務(wù)中來(lái)處理,這樣外部發(fā)一起請(qǐng)求,服務(wù)就把所有的業(yè)務(wù)處理完了(比如將for循環(huán)的計(jì)算放置到服務(wù)端)。
這種方式降低了系統(tǒng)的請(qǐng)求量,但是降低了系統(tǒng)的QPS嗎?這種做法系統(tǒng)更安全了還是更危險(xiǎn)了?
首先來(lái)介紹一下基本概念。
1 .性能的關(guān)鍵指標(biāo)
- 系統(tǒng)吞吐量(Throughput)
吞吐量指單位時(shí)間內(nèi)系統(tǒng)處理的請(qǐng)求數(shù)量,體現(xiàn)系統(tǒng)的整體處理能力。
- 響應(yīng)時(shí)間(系統(tǒng)延遲Latency)
請(qǐng)求的平均響應(yīng)時(shí)間
一般來(lái)說(shuō),一個(gè)系統(tǒng)的性能收到系統(tǒng)吞吐量和響應(yīng)時(shí)間兩個(gè)條件的約束,缺一不可。比如,我的系統(tǒng)可以頂?shù)米∫话偃f(wàn)的并發(fā),但是系統(tǒng)的延遲是2分鐘以上,那么,這個(gè)一百萬(wàn)的負(fù)載毫無(wú)意義。系統(tǒng)延遲很短,但是吞吐量很低,同樣沒(méi)有意義。
一般情況下,針對(duì)一個(gè)系統(tǒng)
• 吞吐量(Throughput)越大,系統(tǒng)延遲(Latency)越差。因?yàn)檎?qǐng)求量過(guò)大,系統(tǒng)太繁忙,所以響應(yīng)速度自然會(huì)低。
• 系統(tǒng)延遲(Latency)越好,能支持的吞吐量(Throughput)就會(huì)越高。因?yàn)長(zhǎng)atency短說(shuō)明處理速度快,于是就可以處理更多的請(qǐng)求。
• 并發(fā)數(shù)
系統(tǒng)同時(shí)能夠處理的請(qǐng)求數(shù)/事務(wù)數(shù)。
• QPS(也稱(chēng)TPS,Query per second/transaction per second)
并發(fā)數(shù)/響應(yīng)時(shí)間
整體來(lái)看QPS能夠概括系統(tǒng)吞吐量和延遲兩方面指標(biāo),因此也是系統(tǒng)最重要的指標(biāo)之一。但當(dāng)系統(tǒng)的QPS升高,到底會(huì)對(duì)系統(tǒng)產(chǎn)生哪些影響,或者在我們?nèi)绾伪苊釷PS升高而對(duì)系統(tǒng)造成的危害呢?
我們緊接這來(lái)看看服務(wù)化系統(tǒng)的主要模式及系統(tǒng)資源的消耗。
2. 服務(wù)化系統(tǒng)構(gòu)成模式
2.1 基礎(chǔ)服務(wù)

一個(gè)最基礎(chǔ)的服務(wù),一般就包含兩種操作:業(yè)務(wù)邏輯處理和DB的讀寫(xiě)。
當(dāng)一個(gè)請(qǐng)求發(fā)過(guò)來(lái)的時(shí)候,會(huì)消耗哪些系統(tǒng)資源呢?
請(qǐng)求對(duì)系統(tǒng)資源的占用

當(dāng)一個(gè)請(qǐng)求發(fā)過(guò)來(lái)之后,常規(guī)的這個(gè)請(qǐng)求會(huì)消耗一下資源:CPU(負(fù)責(zé)計(jì)算)、系統(tǒng)內(nèi)存、網(wǎng)絡(luò)鏈接等系統(tǒng)自身資源;如果我們的系統(tǒng)是基于Java的,那還涉及到JVM資源的占用,JVM的heap和stack資源,其中Heap是更重要的指標(biāo)。如果在這個(gè)請(qǐng)求需要與DB有交互,在連接DB進(jìn)行操作的過(guò)程中,會(huì)消耗系統(tǒng)的數(shù)據(jù)庫(kù)鏈接池資源。對(duì)應(yīng)的在DB側(cè),會(huì)消耗DB的計(jì)算資源,而DB的計(jì)算最重要的指標(biāo)就是DB的響應(yīng)時(shí)間和DB的連接數(shù)。
2.2 集成服務(wù)

這種服務(wù)相對(duì)基礎(chǔ)服務(wù)是另一個(gè)極端,這種服務(wù)只依賴(lài)與其他的服務(wù),并沒(méi)有自己的數(shù)據(jù)。
請(qǐng)求對(duì)系統(tǒng)資源的占用

在這個(gè)系統(tǒng)里面,我們可以將依賴(lài)服務(wù)當(dāng)作DB來(lái)看待,只不過(guò)在請(qǐng)求的過(guò)程中不再消耗系統(tǒng)的數(shù)據(jù)庫(kù)連接池資源。
2.3 混合服務(wù)

這種系統(tǒng)結(jié)構(gòu)是我們最常用的結(jié)構(gòu),既有自身的業(yè)務(wù)數(shù)據(jù),也會(huì)有部分計(jì)算依賴(lài)與其他服務(wù)。
混合服務(wù)的資源消耗

這種結(jié)構(gòu)里面會(huì)集成上面兩種結(jié)構(gòu)的系統(tǒng)消耗。
2.4 系統(tǒng)資源消耗
系統(tǒng)負(fù)載
- 系統(tǒng)CPU利用率
如果系統(tǒng)的CPU使用率已經(jīng)很高,說(shuō)明我們的系統(tǒng)是個(gè)計(jì)算度很復(fù)雜的系統(tǒng),這時(shí)候如果QPS已經(jīng)上不去了,就需要趕緊擴(kuò)容,通過(guò)增加機(jī)器分擔(dān)計(jì)算的方式來(lái)提高系統(tǒng)的吞吐量。
- 系統(tǒng)內(nèi)存
如果CPU使用率一般,但是系統(tǒng)的QPS已經(jīng)負(fù)載不了了,說(shuō)明我們的機(jī)器并沒(méi)有忙于計(jì)算,而是收到其他資源的限制,如內(nèi)存或者io。這時(shí)候首先看下內(nèi)存是不是已經(jīng)不夠了,如果內(nèi)存不夠了,那就趕緊擴(kuò)容了。
針對(duì)Java項(xiàng)目來(lái)說(shuō),JVM中Heap信息也是內(nèi)存的一個(gè)直接反應(yīng),如Java的老年代的內(nèi)存占比,是否發(fā)生Full GC的情況等。
- 系統(tǒng)IO
系統(tǒng)的IO一般是和CPU使用率相反的,CPU利用率高的時(shí)候,IO使用率就不大,而IO使用率高的時(shí)候CPU一般利用率不高。
- 網(wǎng)絡(luò)帶寬(可支持的網(wǎng)絡(luò)鏈接數(shù))
當(dāng)我們自身系統(tǒng)的網(wǎng)絡(luò)帶寬被占用完畢的時(shí)候,相當(dāng)于把系統(tǒng)的入口和出口給堵死了,這時(shí)候外界的需求排不進(jìn)來(lái)了,QPS自然上不去。
在我們的系統(tǒng)中時(shí)常會(huì)使用連接池的方式來(lái)連接DB,也會(huì)使用HTTP連接池的方式向依賴(lài)系統(tǒng)發(fā)起服務(wù),或者使用線程池的方式提供給其他服務(wù)使用。很多時(shí)候因?yàn)橄到y(tǒng)的本身連接池自身有最大連接數(shù)的限制,會(huì)導(dǎo)致系統(tǒng)連接數(shù)耗盡,單系統(tǒng)其他資源依然屬于正常情況。這時(shí)候可以適當(dāng)增加連接數(shù)的方式,來(lái)增加系統(tǒng)的吞吐能力,但這種方法需要慎重,因?yàn)檫^(guò)多的連接池,會(huì)更快的消耗系統(tǒng)資源,并且會(huì)將壓力傳遞給依賴(lài)系統(tǒng)。
依賴(lài)系統(tǒng)的性能
- DB 性能
DB性能很多時(shí)候是系統(tǒng)的根本,因?yàn)橐坏〥B出現(xiàn)了大問(wèn)題,不單單會(huì)導(dǎo)致一個(gè)系統(tǒng)出問(wèn)題,很可能會(huì)導(dǎo)致所有依賴(lài)此DB的系統(tǒng)出現(xiàn)業(yè)務(wù)邏輯問(wèn)題。
一般開(kāi)發(fā)在實(shí)踐中,遇到最多的問(wèn)題就是不當(dāng)?shù)腟QL導(dǎo)致DB讀寫(xiě)性能很低,如未使用索引的讀寫(xiě)SQL;如數(shù)據(jù)庫(kù)表不適當(dāng)?shù)逆i范圍;另外,如果DB本身的讀寫(xiě)已經(jīng)達(dá)到了自身的限度,這時(shí)候可以考慮更換機(jī)器,更換系統(tǒng)的硬盤(pán),或者增加讀庫(kù)等方法,但這方面的優(yōu)化內(nèi)容非常復(fù)雜,在后面會(huì)有專(zhuān)門(mén)的篇幅來(lái)討論。
- 依賴(lài)服務(wù)的性能 依賴(lài)別人的服務(wù),很多不確定其系統(tǒng)性能如何,在可能情況下,可以讓下游系統(tǒng)緊急擴(kuò)容的方式來(lái)解決其自身性能問(wèn)題;但對(duì)于自身系統(tǒng)而言,可以采用快速失敗和接口降級(jí)的方式來(lái)實(shí)現(xiàn)。
如果上面所說(shuō)的系統(tǒng)自身指標(biāo)和依賴(lài)系統(tǒng)的指標(biāo)都相對(duì)正常,但系統(tǒng)的QPS依然無(wú)法負(fù)載,說(shuō)明系統(tǒng)內(nèi)部出現(xiàn)問(wèn)題,如系統(tǒng)被阻塞了。
在進(jìn)行系統(tǒng)優(yōu)化之前需要進(jìn)行Profile測(cè)試分析,根據(jù)2:8原則來(lái)說(shuō),20%的代碼耗了你80%的性能,找到那20%的代碼,你就可以優(yōu)化那80%的性能。
3 常見(jiàn)系統(tǒng)優(yōu)化tips
3.1 代碼調(diào)優(yōu)
- 調(diào)用接口異步化
調(diào)用依賴(lài)服務(wù)時(shí),采用異步并行的方式調(diào)用,將多個(gè)耗時(shí)的請(qǐng)求合并發(fā)出,可以降低很多無(wú)謂的等待時(shí)間。
- IO異步化緩存化 系統(tǒng)中最常用的文件io是記錄日志,在記錄日志的時(shí)候設(shè)置合適的日志緩存,并使用異步化的方式寫(xiě)入日志文件;在必要的地方記錄日志,避免日志濫用,不僅對(duì)io造成壓力,且會(huì)浪費(fèi)系統(tǒng)硬盤(pán)空間,在一些極端情況下,會(huì)因?yàn)橛脖P(pán)空間耗盡而導(dǎo)致系統(tǒng)吞吐量顯著下降。
針對(duì)其他需要進(jìn)行文件讀寫(xiě)的操作,建議使用異步化的方式,降低阻塞的可能。
- API的request及response不使用過(guò)大的對(duì)象
過(guò)大的request和response會(huì)增加網(wǎng)絡(luò)帶寬的壓力,且過(guò)大的字節(jié)傳入容易造成數(shù)據(jù)丟失。
- 適當(dāng)使用緩存
這個(gè)是在互聯(lián)網(wǎng)服務(wù)中最常用的優(yōu)化方式了,在此不再詳述。
- 慎重使用線程
有人說(shuō),thread is evil,因?yàn)槎嗑€程瓶頸就在于互斥和同步的鎖上,以及線程上下文切換的成本,怎么樣的少用鎖或不用鎖是根本。另外在系統(tǒng)中使用線程池時(shí),避免因?yàn)槭褂镁€程池模式和數(shù)量限制設(shè)置不當(dāng),而成為系統(tǒng)瓶頸。
3.2 數(shù)據(jù)庫(kù)調(diào)優(yōu)
- 數(shù)據(jù)庫(kù)的鎖的方式。
并發(fā)情況下,鎖是非常非常影響性能的。各種隔離級(jí)別,行鎖,表鎖,頁(yè)鎖,讀寫(xiě)鎖,事務(wù)鎖,以及各種寫(xiě)優(yōu)先還是讀優(yōu)先機(jī)制。性能最高的是不要鎖,所以,分庫(kù)分表,冗余數(shù)據(jù),減少一致性事務(wù)處理,可以有效地提高性能。
- 使用索引
在讀寫(xiě)數(shù)據(jù)的時(shí)候都需要在where條件中檢查索引的使用。
- 避免在SQL級(jí)的join操作
SQL中的join操作對(duì)索引的優(yōu)化是個(gè)很復(fù)雜的問(wèn)題,因?yàn)榛ヂ?lián)網(wǎng)的項(xiàng)目經(jīng)常會(huì)發(fā)生變化,針對(duì)數(shù)據(jù)表的索引也會(huì)不斷優(yōu)化,如果使用join很可能會(huì)無(wú)法正確索引;且SQL級(jí)的索引的功能維護(hù)性也非常差。
- 部分結(jié)果集
在查詢上增加適當(dāng)?shù)膌imit
- 不要select * ,而是明確指出各個(gè)字段,如果有多個(gè)表,一定要在字段名前加上表名,不要讓引擎去算。
- 不要用Having,因?yàn)槠湟闅v所有的記錄。性能差得不能再差。
- 盡可能地使用UNION ALL 取代 UNION。
- 索引過(guò)多,insert和delete就會(huì)越慢。而update如果update多數(shù)索引,也會(huì)慢,但是如果只update一個(gè),則只會(huì)影響一個(gè)索引表。
- 關(guān)于MySQL的優(yōu)化,現(xiàn)在相關(guān)的資料也非常多,推薦高性能MySQL(第二版),這本書(shū)對(duì)MySQL的高性能有著更深入的討論。
原文:http://blog.brucefeng.info/post/high-qps-service
【編輯推薦】
上一篇:DBA線上操作要知道的那些事
下一篇:如何理解CMDB的套路

頻道總排行
- Cisco NetFlow v9為何無(wú)人問(wèn)津?
- 技術(shù)專(zhuān)題:智能化運(yùn)維
- 開(kāi)源代碼管理:如何安全地使用開(kāi)源庫(kù)?
- Facebook架構(gòu)解讀
- IT運(yùn)維分析與海量日志搜索需要注意什么(1)
- 金山運(yùn)維肖力:如何將業(yè)務(wù)遷移到虛擬化環(huán)境并穩(wěn)定運(yùn)行(1)
- Apache Ignite(四):基于Ignite的分布式ID生成器
- SDN時(shí)代的網(wǎng)絡(luò)管理系統(tǒng)會(huì)走向何方
- CrazyEye,一款國(guó)人開(kāi)源的堡壘機(jī)軟件(1)
- WOT2016吳兆松:Zabbix監(jiān)控自動(dòng)化的未來(lái)如何發(fā)展
頻道本月排行
- 8你消費(fèi)我買(mǎi)單——"漏洞"天使OneRASP...
- 7有了Jenkins,為什么還需要一個(gè)獨(dú)立...
- 6IT運(yùn)維分析與海量日志搜索需要注意什么(1)
- 5新浪微博王傳鵬:微博推薦架構(gòu)的演進(jìn)(1)
- 4云運(yùn)維如何選擇部署適合自身的IDC和...
- 4雅虎開(kāi)源可以提升流操作速度的DataSketches
- 4大眾點(diǎn)評(píng)高可用性系統(tǒng)運(yùn)維經(jīng)驗(yàn)分享
- 4開(kāi)源還是商用?十大云運(yùn)維監(jiān)控工具測(cè)...
- 4論開(kāi)發(fā)與運(yùn)維沖突的根源、表現(xiàn)形式及...
- 4史上最大機(jī)器學(xué)習(xí)數(shù)據(jù)集,雅虎對(duì)外開(kāi)...