漏桶算法&令牌桶算法理解及常用的算法

令牌與漏桶的區(qū)別

 1. 漏桶是出,令牌是進
 2. 令牌是允許伸縮
漏桶算法

漏桶算法(Leaky Bucket)是網(wǎng)絡世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)時經(jīng)常使用的一種算法,它的主要目的是控制數(shù)據(jù)注入到網(wǎng)絡的速率交汤,平滑網(wǎng)絡上的突發(fā)流量琴许。漏桶算法提供了一種機制,通過它晾浴,突發(fā)流量可以被整形以便為網(wǎng)絡提供一個穩(wěn)定的流量负乡。

漏桶可以看作是一個帶有常量服務時間的單服務器隊列,如果漏桶(包緩存)溢出脊凰,那么數(shù)據(jù)包會被丟棄抖棘。 在網(wǎng)絡中,漏桶算法可以控制端口的流量輸出速率狸涌,平滑網(wǎng)絡上的突發(fā)流量切省,實現(xiàn)流量整形,從而為網(wǎng)絡提供一個穩(wěn)定的流量杈抢。

如圖所示数尿,把請求比作是水,水來了都先放進桶里惶楼,并以限定的速度出水右蹦,當水來得過猛而出水不夠快時就會導致水直接溢出,即拒絕服務歼捐。

image.png

可以看出何陆,漏桶算法可以很好的控制流量的訪問速度,一旦超過該速度就拒絕服務豹储。

令牌桶算法

令牌桶算法是網(wǎng)絡流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一種算法贷盲。典型情況下,令牌桶算法用來控制發(fā)送到網(wǎng)絡上的數(shù)據(jù)的數(shù)目,并允許突發(fā)數(shù)據(jù)的發(fā)送巩剖。

令牌桶算法的原理是系統(tǒng)會以一個恒定的速度往桶里放入令牌铝穷,而如果請求需要被處理,則需要先從桶里獲取一個令牌佳魔,當桶里沒有令牌可取時曙聂,則拒絕服務。從原理上看鞠鲜,令牌桶算法和漏桶算法是相反的宁脊,一個“進水”,一個是“漏水”贤姆。

image.png

Google的Guava包中的RateLimiter類就是令牌桶算法的解決方案榆苞。

漏桶算法和令牌桶算法的選擇

漏桶算法與令牌桶算法在表面看起來類似,很容易將兩者混淆霞捡。但事實上坐漏,這兩者具有截然不同的特性,且為不同的目的而使用弄砍。

漏桶算法與令牌桶算法的區(qū)別在于仙畦,漏桶算法能夠強行限制數(shù)據(jù)的傳輸速率,令牌桶算法能夠在限制數(shù)據(jù)的平均傳輸速率的同時還允許某種程度的突發(fā)傳輸音婶。

需要注意的是慨畸,在某些情況下,漏桶算法不能夠有效地使用網(wǎng)絡資源衣式,因為漏桶的漏出速率是固定的寸士,所以即使網(wǎng)絡中沒有發(fā)生擁塞,漏桶算法也不能使某一個單獨的數(shù)據(jù)流達到端口速率碴卧。因此弱卡,漏桶算法對于存在突發(fā)特性的流量來說缺乏效率。而令牌桶算法則能夠滿足這些具有突發(fā)特性的流量住册。通常婶博,漏桶算法與令牌桶算法結(jié)合起來為網(wǎng)絡流量提供更高效的控制。

常用的算法介紹

從簡單到復雜依次介紹了如下幾種算法:

  1. Leaky Bucket
  2. Fixed Window
  3. Sliding Log
  4. Sliding Window

Leaky Bucket

桶算法荧飞,做法是預先設置一個請求數(shù)的上限凡人,小于這個上限的時候會接收請求, 大于這個上限的話會直接拒絕叹阔,只有等到系統(tǒng)處理掉了一些在桶里的請求挠轴, 桶里有新的坑位了,才會接收新的請求耳幢。

image

優(yōu)點:

  1. 能夠平滑請求數(shù)岸晦,使系統(tǒng)以一個均勻的速率處理請求
  2. 容易實現(xiàn),可以用一個隊列/FIFO 來做
  3. 可以只用很小的內(nèi)存做到為每個用戶限流

缺點:

  1. 桶滿了以后,新的請求都會被扔掉启上,系統(tǒng)忙著處理舊請求
  2. 無法保證請求能夠在一個固定的時間內(nèi)處理完

Fixed Window

固定窗口算法邢隧,設置一個時間段內(nèi)(窗口)接收的請求數(shù),超過的這個請求數(shù)的請求會被丟棄冈在。

  • 窗口通常選擇人們熟悉的時間段:1 分鐘/1小時
  • 窗口的起始時間通常是當前時間取地板(floor)府框,比如 12:00:03 所在的窗口 (以一分鐘的窗口為例)就是 12:00:00 - 12:01:00
image

優(yōu)點:

  1. 和漏桶相比,能夠讓新來的請求也能夠被處理到

缺點:

  1. 在窗口的起始時間讥邻,最差情況下可能會帶來 2 倍的流量
  2. 很多消費者可能都在等待窗口被重置,造成驚群效應

Sliding Log

滑動日志算法院峡,利用記錄下來的用戶的請求時間兴使,請求數(shù),當該用戶的一個新的 請求進來時照激,比較這個用戶在這個窗口內(nèi)的請求數(shù)是否超過了限定值发魄,超過的話 就拒絕這個請求。

image

優(yōu)點:

  1. 避免了固定窗口算法在窗口邊界可能出現(xiàn)的兩倍流量問題
  2. 由于是針對每個用戶進行統(tǒng)計的俩垃,不會引發(fā)驚群效應

缺點:

  1. 需要保存大量的請求日志
  2. 每個請求都需要考慮該用戶之前的請求情況励幼,在分布式系統(tǒng)中尤其難做到

Sliding Window

滑動窗口算法,結(jié)合了固定窗口算法的低開銷和滑動日志算法能夠解決的邊界情 況口柳。

  1. 為每個窗口進行請求量的計數(shù)
  2. 結(jié)合上一個窗口的請求量和這一個窗口已經(jīng)經(jīng)過的時間來計算出上限苹粟,以此 平滑請求尖鋒

舉例來說,限流的上限是每分鐘 10 個請求跃闹,窗口大小為 1 分鐘嵌削,上一個 窗口中總共處理了 6 個請求。現(xiàn)在假設這個新的窗口已經(jīng)經(jīng)過了 20 秒望艺,那么 到目前為止允許的請求上限就是 10 - 6 * (1 - 20 / 60) = 8苛秕。

image

滑動窗口算法是這些算法中最實用的算法:

  1. 有很好的性能
  2. 避免了漏桶算法帶來的饑餓問題
  3. 避免了固定窗口算法的請求量突增的問題

分布式實現(xiàn)

同步的策略

難點在于限流上限都是針對全站的流量設置的,那么每個節(jié)點該如何協(xié)調(diào)各自處理的量呢找默?

解決的方法通常都是使用一個統(tǒng)一的數(shù)據(jù)庫來存放計數(shù)艇劫,比如 Redis 或者 Cassandra。 數(shù)據(jù)庫中將存放每個窗口和用戶的計數(shù)值惩激。這種方法的主要問題是需要多訪問一次數(shù)據(jù)庫店煞, 以及競爭問題。

競爭問題

image

競爭問題就是當有兩個以上的線程同時執(zhí)行 i += 1 的時候咧欣,如果沒有同步這 些操作的話浅缸,i 的值可能會有多種情況。

處理競爭問題可以通過加鎖來做魄咕,不過在限流的場景下衩椒,這樣做肯定會成為系統(tǒng)的瓶頸, 畢竟限流時每個請求都會來競爭這個鎖。

更好的辦法是通過 set-then-get 的方法毛萌,限流場景中用到的只是計數(shù) +1苟弛, 利用這一點以及數(shù)據(jù)庫實現(xiàn)的性能更好的原子操作可以達到我們的目的。

性能優(yōu)化

image

利用集中式的數(shù)據(jù)庫的另一個問題是每次請求都要查一下數(shù)據(jù)庫帶來的延遲開銷阁将, 數(shù)據(jù)庫再快也會帶來幾毫秒的延遲膏秫。

解決這個問題的方法可以通過在內(nèi)存里面維護一個計數(shù)值,代價是稍微的放松限 流的精確度做盅。通過設置一個定時任務從數(shù)據(jù)庫拿計數(shù)值缤削,周期內(nèi)在內(nèi)存中維護這 個計數(shù),周期結(jié)束時把計數(shù)同步到數(shù)據(jù)庫并拿取新的計數(shù)吹榴,如此往復亭敢。

這個同步周期往往是做成可以配置的,小的周期能夠帶來更精確的限流图筹, 大的周期則能減輕數(shù)據(jù)庫的 I/O 壓力帅刀。

python 可用limits庫

https://github.com/hugoren/limits

可選用的limit策略

image.png
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市远剩,隨后出現(xiàn)的幾起案子扣溺,更是在濱河造成了極大的恐慌,老刑警劉巖瓜晤,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锥余,死亡現(xiàn)場離奇詭異,居然都是意外死亡活鹰,警方通過查閱死者的電腦和手機哈恰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來志群,“玉大人着绷,你說我怎么就攤上這事⌒吭疲” “怎么了荠医?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桑涎。 經(jīng)常有香客問我彬向,道長,這世上最難降的妖魔是什么攻冷? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任娃胆,我火速辦了婚禮,結(jié)果婚禮上等曼,老公的妹妹穿的比我還像新娘里烦。我一直安慰自己凿蒜,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布胁黑。 她就那樣靜靜地躺著废封,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丧蘸。 梳的紋絲不亂的頭發(fā)上漂洋,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音力喷,去河邊找鬼刽漂。 笑死,一個胖子當著我的面吹牛弟孟,可吹牛的內(nèi)容都是我干的爽冕。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼披蕉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乌奇?” 一聲冷哼從身側(cè)響起没讲,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎礁苗,沒想到半個月后爬凑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡试伙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年嘁信,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疏叨。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡潘靖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚤蔓,到底是詐尸還是另有隱情卦溢,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布秀又,位于F島的核電站单寂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吐辙。R本人自食惡果不足惜宣决,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昏苏。 院中可真熱鬧尊沸,春花似錦威沫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至壶熏,卻和暖如春句柠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棒假。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工溯职, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帽哑。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓谜酒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親妻枕。 傳聞我的和親對象是個殘疾皇子僻族,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

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