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

QPS 的計算是怎么實(shí)現(xiàn)的?

開發(fā) 前端
如果你是個已經(jīng)工作有幾年的程序員,那想必這個問題難不倒你。但如果,我是說如果,面試官問你,你知道 QPS 的計算是怎么實(shí)現(xiàn)的不,能詳細(xì)說下思路嗎?

面試的時候,面試官看著你做的項(xiàng)目,大概率會問一句,這個項(xiàng)目(API)能支持多大 QPS?

如果你是個已經(jīng)工作有幾年的程序員,那想必這個問題難不倒你。但如果,我是說如果,面試官問你,你知道 QPS 的計算是怎么實(shí)現(xiàn)的不,能詳細(xì)說下思路嗎? 閣下又該如何應(yīng)對呢?這是個很有意思的問題,我們今天就來聊聊這個話題??紤]到有不少讀者還是學(xué)生,我們先來看下 QPS 的含義。

QPS 是什么

QPS(Queries Per Second),也就是“每秒查詢數(shù)”,它表示服務(wù)器每秒能夠處理的請求數(shù)量,是一個衡量服務(wù)器性能的重要指標(biāo)。

QPS是什么QPS是什么

比如說服務(wù)的用戶查詢 API 支持 100 QPS,就是指這個接口可以做到每秒查 100 次。你務(wù)必牢牢記住這個概念,因?yàn)楣ぷ髦蠼?jīng)常會聽別人提起它。很多面試官就特別愛問:"你的這個項(xiàng)目(API)的讀寫性能怎么樣,單個實(shí)例能支持多少 QPS?"。這個問題就是個照妖鏡。面試官可以通過這個問題了解你對項(xiàng)目的了解程度。 如果你答不出來,那你在這個項(xiàng)目中很可能就不是核心開發(fā),或者說你這個項(xiàng)目既不核心也不重要,甚至可能你就沒做過這個項(xiàng)目。。。 并且這個 QPS 數(shù)值還會有一個合理范圍,有經(jīng)驗(yàn)的開發(fā)能通過這個值判斷這個服務(wù) API 底層大概是咋樣的。如果你回答的數(shù)值過小或過大,那又可以繼續(xù)細(xì)聊過小和過大的原因。

我說下我目前接觸下來比較合理的 QPS 范圍:帶了數(shù)據(jù)庫的服務(wù)一般寫性能在 5k 以下,讀性能一般在 10k 以下,能到 10k 以上的話,那很可能是在數(shù)據(jù)庫前面加了層緩存。如果你的服務(wù)還帶了個文本算法模型,那使用了 gpu 的情況下 API 一般支持 100~400QPS 左右,如果是個同時支持文本和圖片的模型,也就是所謂的多模態(tài)模型,那一般在 100QPS 以內(nèi)。

qps經(jīng)驗(yàn)值qps經(jīng)驗(yàn)值

比如候選人上來就說服務(wù)單實(shí)例 API 讀寫性能都有上萬 QPS, 那我可以大概猜到這應(yīng)該是個純 cpu+內(nèi)存的 API 鏈路。但如果候選人還說這里面沒做緩存且有數(shù)據(jù)庫調(diào)用,那我可能會追問這里頭用的是哪款數(shù)據(jù)庫,底層是什么存儲引擎?如果候選人還說這里面帶了個文本檢測的算法模型,那有點(diǎn)違反經(jīng)驗(yàn),那我會多聊聊細(xì)節(jié),說不定這對我來說是個開眼界的機(jī)會。

如何計算 QPS ?

現(xiàn)在了解完 QPS 了,假設(shè)我們想要獲得某個函數(shù) 的 QPS,該怎么做呢?這一般分兩個情況:

  • ? 1.實(shí)時性要求較低的監(jiān)控場景。
  • ? 2.實(shí)時性要求較高的服務(wù)治理場景。

計算qps的兩個場景計算qps的兩個場景

監(jiān)控場景

監(jiān)控服務(wù) QPS 是最常見的場景,它對實(shí)時性要求不高。如果我們想要查看服務(wù)的 QPS,可以在服務(wù)代碼內(nèi)部接入 Prometheus 的代碼庫,然后在每個需要計算 QPS 的地方,加入類似Counter.Inc()這樣的代碼,意思是函數(shù)執(zhí)行次數(shù)加 1。這個過程也就是所謂的打點(diǎn)。

當(dāng)函數(shù)執(zhí)行到打點(diǎn)函數(shù)時,Prometheus 代碼庫內(nèi)部會計算這個函數(shù)的調(diào)用次數(shù),將數(shù)據(jù)寫入到 counter_xx.db 的文件中,再同步到公司的時序數(shù)據(jù)庫中,然后我們可以通過一些監(jiān)控面板,比如 grafana調(diào)取時序數(shù)據(jù)庫里的打點(diǎn)數(shù)據(jù),在監(jiān)控面板上通過特殊的表達(dá)式,也就是PromQL,對某段時間里的打點(diǎn)進(jìn)行求導(dǎo)計算速率,這樣就能看到這個函數(shù)的調(diào)用 QPS 啦。

監(jiān)控場景中獲取qps監(jiān)控場景中獲取qps

服務(wù)治理場景

跟監(jiān)控面板查看服務(wù) QPS 不同的是,我們有時候需要以更高的實(shí)時性獲取 QPS。比如在服務(wù)治理這一塊,我們需要在服務(wù)內(nèi)部加入一些中間層,實(shí)時計算服務(wù) api 當(dāng)前的 QPS,當(dāng)它大于某個閾值時,可以做一些自定義邏輯,比如是直接拒絕掉一些請求,還是將請求排隊(duì)等一段時間后再處理等等,也就是所謂的限流。這樣的場景都要求我們實(shí)時計算出準(zhǔn)確的 QPS,那么接下來就來看下這是怎么實(shí)現(xiàn)的?

基本思路

計算某個函數(shù)的執(zhí)行 QPS 說白了就是計算每秒內(nèi)這個函數(shù)被執(zhí)行了多少次。我們可以參考監(jiān)控場景的思路,用一個臨時變量 cnt 記錄某個函數(shù)的執(zhí)行次數(shù),每執(zhí)行一次就給變量+1,然后計算單位時間內(nèi)的變化速率。公式就像這樣:

QPS = (cnt(t) - cnt(t - Δt)) / Δt

其中 cnt(t) 表示在時間 t 的請求數(shù),Δt表示時間間隔。比如在第 9 秒的時候, cnt 是 80, 到第 10 秒的時候,cnt 是 100,那這一秒內(nèi)就執(zhí)行了 (100-80)/(10-9) = 20 次, 也就是 20QPS。

QPS怎么計算QPS怎么計算

引入 bucket

但這樣會有個問題,到了第 10 秒的時候,有時候我還想回去知道第 5 和第 6 秒的 QPS,光一個變量的話,數(shù)據(jù)老早被覆蓋了,根本不夠用。于是我們可以將臨時變量 cnt,改成了一個數(shù)組,數(shù)組里每個元素都用來存放(cnt(t) - cnt(t - Δt)) 的值。數(shù)組里的每個元素,都叫 bucket.

bucket數(shù)組bucket數(shù)組

調(diào)整 bucket 范圍粒度

我們默認(rèn)每個 bucket 都用來存放 1s 內(nèi)的數(shù)據(jù)增量,但這粒度比較粗,我們可以調(diào)整為 200ms,這樣我們可以獲得更細(xì)粒度的數(shù)據(jù)。粒度越細(xì),意味著我們計算 QPS 的組件越靈敏,那基于這個 QPS 做的服務(wù)治理能力響應(yīng)就越快。于是,原來用 1 個 bucket 存放 1s 內(nèi)的增量數(shù)量,現(xiàn)在就變成要用 5 個 bucket 了。

bucket粒度細(xì)化bucket粒度細(xì)化

引入環(huán)形數(shù)組

但這樣又引入一個新的問題,隨著時間變長,數(shù)組的長度就越長,需要的內(nèi)存就越多,最終導(dǎo)致進(jìn)程申請的內(nèi)存過多,被 oom(Out of Memory) kill 了。為了解決這個問題,我們可以為數(shù)組加入最大長度的限制,超過最大長度的部分,就從頭開始寫,覆蓋掉老的數(shù)據(jù)。這樣的數(shù)組,就是所謂的環(huán)狀數(shù)組。

雖然環(huán)狀數(shù)組聽起來挺高級了,但說白了就是一個用%取模來確定寫入位置的定長數(shù)組,沒有想象的那么高端。比如數(shù)組長度是 5,數(shù)組 index 從 0 開始,要寫 index=6 的 bucket, 計算 6%5 = 1,那就是寫入 index=1 的位置上。

bucket環(huán)形數(shù)組bucket環(huán)形數(shù)組

加入滑動窗口

有了環(huán)形數(shù)組之后,現(xiàn)在我們想要計算 qps,就需要引入滑動窗口的概念。這玩意聽著玄乎,其實(shí)就是 start 和 end 兩個變量。通過它來圈定我們要計算 qps 的 bucket 數(shù)組范圍。將當(dāng)前時間跟 bucket 的粒度做取模操作,可以大概知道 end 落在哪個 bucket 上,確定了 end 之后,將 end 的時間戳減個 1s就能大概得到 start 在哪個 bucket 上,有了這兩個值,再將 start 到 end 范圍內(nèi)的 bucket 取出。對范圍內(nèi)的 bucket 里的 cnt 求和,得到這段時間內(nèi)的總和,再除以 Δt,也就是 1s。就可以得到 qps。

引入滑動窗口引入滑動窗口

到這里 qps 的計算過程就介紹完了。

如何計算平均耗時

既然 qps 可以這么算,那同理,我們也可以計算某個函數(shù)的平均耗時,實(shí)現(xiàn)也很簡單,上面提到 bucket 有個用來統(tǒng)計調(diào)用次數(shù)的變量 cnt,現(xiàn)在再加個用來統(tǒng)計延時的變量 Latency 。每次執(zhí)行完函數(shù),就給 bucket 里的 Latency 變量 加上耗時。再通過滑動窗口獲得對應(yīng)的 bucket 數(shù)組范圍,計算 Latency 的總和,再除以這些 bucket 里的調(diào)用次數(shù) cnt 總和。就像下面這樣:

函數(shù)的平均耗時 = Latency總和/cnt總和

于是就得到了這個函數(shù)的平均耗時。

sentinel-golang

看到這里,你應(yīng)該對「怎么基于滑動窗口和 bucket 實(shí)現(xiàn)一個計算 QPS 和平均 Latency 的組件」有一定思路了。但沒代碼,說再多好像也不夠解渴,對吧?其實(shí),上面的思路,就是阿里開源的sentinel-golang中 QPS 計算組件的實(shí)現(xiàn)方式。sentinel-golang 是個著名的服務(wù)治理庫,它會基于 QPS 和 Latency 等信息提供一系列限流熔斷策略。如果你想了解具體的代碼實(shí)現(xiàn),可以去看下。鏈接是:

https://github.com/alibaba/sentinel-golang

但茫茫碼海,從何看起呢?下面給出一些關(guān)鍵詞,大家可以作為入口去搜索看下。首先可以基于 sliding_window_metric.go 里的 GetQPS 開始看起,它是實(shí)時計算 QPS 的入口函數(shù)。這里面會看到很多上面提到的內(nèi)容細(xì)節(jié),其中前面提到的滑動窗口,它在 sentinel-golang 中叫 LeapArray。 bucket環(huán)形數(shù)組,在 sentinel-golang 中叫 AtomicBucketWrapArray。環(huán)形數(shù)組里存放的 bucket 在代碼里就是 MetricBucket,但需要注意的是 MetricBucket 里的 count 并不是一個數(shù)字類型,而是一個 map 類型,它將上面提到的 cnt 和 Latency 等都作為一種 key-value 來存放。以后想要新增字段就不需要改代碼了,提高了代碼擴(kuò)展性。

最后

  • ? QPS 指“每秒查詢數(shù)”,是程序員必知必會的內(nèi)容。建議多了解你負(fù)責(zé)的項(xiàng)目的 qps,以防面試官一問你三不知。
  • ? 這篇文章介紹了代碼實(shí)時計算 QPS 的實(shí)現(xiàn)細(xì)節(jié),同時這也是著名的服務(wù)治理庫 sentinel-golang 的實(shí)現(xiàn)原理,除了 golang 版本,它還有 java,cpp,js 版本的庫,原理都大同小異,看完這篇文章等于一次性學(xué)了 4 個庫,這波不虧。
責(zé)任編輯:武曉燕 來源: 小白debug
相關(guān)推薦

2010-10-17 02:14:00

云計算IBM

2022-04-18 11:51:20

元宇宙量子計算

2020-11-30 13:45:24

邊緣計算貨運(yùn)信息處理

2021-04-07 06:58:32

邊緣計算計算云計算

2011-06-07 16:57:05

倪光南浪潮云計算

2010-03-16 15:28:22

云計算

2020-12-17 10:04:00

云計算物聯(lián)網(wǎng)存儲

2018-08-27 15:10:34

云計算云服務(wù)安全威脅

2019-02-21 17:21:52

2021-11-18 22:36:07

人工智能量子計算機(jī)器學(xué)習(xí)

2009-05-19 18:56:46

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

2011-09-22 09:58:19

2017-07-06 09:06:57

無服務(wù)計算PaaS

2023-10-26 19:15:40

2021-02-25 09:37:24

云計算云計算產(chǎn)業(yè)云應(yīng)用

2016-04-28 16:57:07

AWS

2018-01-08 14:57:03

云計算霧計算智能

2017-10-28 22:49:49

邊緣計算物聯(lián)網(wǎng)互聯(lián)網(wǎng)

2023-01-10 15:41:22

邊緣計算是工業(yè)4.0

2009-01-12 09:22:40

虛擬化高性能計算HPC
點(diǎn)贊
收藏

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