提高QPS方法基本思路
提高QPS方法淺談
最近看了一篇博文,題目是 《天池中間件大賽dubboMesh優(yōu)化總結(jié)(qps從1000到6850)》,點(diǎn)擊鏈接,對其中筆者優(yōu)化RPC鏈路,提高QPS的過程非常感興趣,所以就想寫一篇這樣的文章。主要就以下幾點(diǎn)談?wù)勅绾翁岣逹PS:
- QPS含義
- 高QPS的核心思想
- 常見手段
QPS含義
Queries per second (QPS) is a common measure of the amount of search traffic an information retrieval system, such as a search engine or a database, receives during one second. —— [ 維基百科 ]
簡單的來說,就是每秒能夠響應(yīng)的請求,并以此作為系統(tǒng)處理能力的標(biāo)準(zhǔn)。一般QPS的獲取,正如其定義一樣,需要通過壓測工具進(jìn)行實(shí)際的壓力測試計(jì)算,這是從結(jié)果的角度來看。但是換個思路,特別是我們需要提高QPS值的時候,我們就要思考怎么樣提高,影響QPS的因素到底是什么,能否從數(shù)學(xué)上有一個比較準(zhǔn)確的定義和描述,這個時候,我們的思路就會被打開。
QPS,顧名思義,從描述我們可以下一個基本的定義:
QPS = 1000ms/執(zhí)行RT,當(dāng)然,這是單核單線程QPS。擴(kuò)充到多線程:
QPS = 1000ms/執(zhí)行RT*線程數(shù) 其中執(zhí)行RT=thread avg waitTime + thread avg executeTime至于線程數(shù),選什么值好呢?一般來說,使用線程直接目的就是最大化CPU資源,所以 在一個執(zhí)行RT內(nèi),我們理想可以并行的線程數(shù)是
n = 執(zhí)行RT/thread avg executeTime=1+waitTime/executeTime但是往往存在上下文線程開銷、同線程之間資源切換損耗,并且我們CPU的利用率并不是100%。所以假設(shè)我們把線程開銷等等計(jì)算到 executeTime中,定義cpu%表示cpu利用率。
最后,我們的QPS的定性描述
所以,我們要提高一個服務(wù)系統(tǒng)的QPS,需要降低這個鏈路當(dāng)中 executeTime以及提高cpu利用率。
高QPS的核心思想
繼續(xù)上文的結(jié)論,要提高一個服務(wù)的QPS,我們需要實(shí)現(xiàn)兩個指標(biāo):
降低這個鏈路的 executeTime,以及提高cpu利用率。
降低鏈路的executeTime 自然而然,我們把一個鏈路的同步調(diào)用,分成好幾段,原來需要經(jīng)過三步才能拿到的返回結(jié)果,我們只需要經(jīng)過一步就能拿到結(jié)果,那么自然我們的性能就會提高很多。
至于提高cpu利用率。說到底其實(shí)就是一點(diǎn),不要在計(jì)算的時候,老進(jìn)行什么IO、網(wǎng)絡(luò)讀寫,要計(jì)算就好好的計(jì)算,專人負(fù)責(zé)專事。
把這兩點(diǎn)歸納到一起,其實(shí)際就是一種SEDA思想
SEDA
SEDA,即將原先由一個線程完成的任務(wù),分割為相對獨(dú)立的多個階段。每個階段由專用的一組線程負(fù)責(zé)執(zhí)行,階段之間用隊(duì)列交互。
將SEDA思想融入的比較完美的地方,首先想要的便是 一直被大家所推崇的高性能IO通信 netty, 使用的異步非阻塞的Reactor線程模型
如圖使用多組不同的線程池,
1.第一個NIO線程池,Acceptor pool接受dispatcher來的客戶端連接,完成auth、login、以及握手。
2.第二個NIO線程池,接替前一個結(jié)果,完成后續(xù)的IO讀寫
這樣,系統(tǒng)的每一個比較耗時的環(huán)節(jié),都有一組人在并行處理,環(huán)節(jié)之間通過NIO非阻塞通信,極大降低了等待時間,提高了利用率。所以在相同的時間內(nèi),使用SEDA思想設(shè)計(jì),將能響應(yīng)更多的請求。
disruptor無鎖設(shè)計(jì)
很快,使用SEDA,我們就會發(fā)現(xiàn)一個問題,不同的stage之間通過隊(duì)列來交互,并且在多線程環(huán)境下,入隊(duì)與出隊(duì)必然存在鎖控制,并且隊(duì)列為了起到緩存的作用,那么總會存在一定的數(shù)據(jù),隊(duì)列持有一定的數(shù)據(jù),從全局的角度來看,這是一個cpu并沒有被使用的場景,因?yàn)閿?shù)據(jù)被緩沖在隊(duì)列里。另外當(dāng)消費(fèi)者速度較快的情形下,可能出現(xiàn) 多個不同的消費(fèi)者相互競爭同類型的資源。所以disruptor 提出了一種無鎖設(shè)計(jì),干掉隊(duì)列,在同樣情形下,把能把各個stage之間聯(lián)系的隊(duì)列去掉,用一種統(tǒng)一的數(shù)據(jù)結(jié)構(gòu)來代替,統(tǒng)一的數(shù)據(jù)結(jié)構(gòu),可以使用統(tǒng)一的線程組,這樣系統(tǒng)的壓力也比較均勻。
disruptor的研究與解讀還需要慢慢品味,此處就不予以展開。
常見手段
1.異步化
即非阻塞,化繁為簡,拿到你需要處理的資源后盡快回復(fù)。適用于事務(wù)處理場景,且無需對上游返回?cái)?shù)據(jù)場景。fature callback這種模式,從數(shù)據(jù)角度來說,是一種偽異步。
2.無鎖設(shè)計(jì)
本質(zhì)上是要降低鎖沖突,而無鎖設(shè)計(jì)最佳的體現(xiàn)就在于MVVC思想,避免或者使用互斥資源,所以基于數(shù)據(jù)版本的樂觀鎖 有效的減少了互斥資源的范圍,優(yōu)點(diǎn)不言而喻。
3.batch處理
批量查詢、批量commit,基本上操作慢速設(shè)備或者不能并行化的對象或者資源時,使用batch 永遠(yuǎn)是最好的手段。
4.副本設(shè)計(jì)
使用cache、靜態(tài)化等手段,其核心思想在于 提前將結(jié)果準(zhǔn)備好,實(shí)現(xiàn)的難點(diǎn)數(shù)據(jù)的更新。
總結(jié)
以上是生活随笔為你收集整理的提高QPS方法基本思路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eds能谱图分析实例_基础理论丨一文了解
- 下一篇: 力扣有没有java_力扣 APP 全新改