高並發限流算法
開篇
在高並發系統中,有很多手段來保護系統,如緩存、降級和限流等。
緩存:讓數據盡早進入緩存,離程序近一點,不要大量頻繁的訪問DB,可提供系統訪問速度和增大系統處理能力。
降級:當服務出問題或者影響到核心流程的性能,需要將服務暫時屏蔽掉,待高峰期過去或問題解決後再啟用。
然後,有些場景不能用緩存和降級來解決。比如電商的雙十一,用戶的購買,下單等行為,是涉及到大量寫操作,而且是核心鏈路,無法降級的。
限流:通過把並發訪問/請求進行限速或者一定時間窗口內的請求限制在一定範圍內來保護系統,一旦達到限制速率則可以拒絕服務(定向到錯誤頁面或告知資源沒有了)、排隊或等待(如秒殺),從而保證系統不被沖垮,同時盡可能提升系統的吞吐量。
限流算法
常見的限流算法:漏桶、令牌桶。計數器也可用來進行粗暴限流實現。
1.漏桶(Leaky Bucket)
漏桶算法可用於流量整形(Traffic Shaping)和流量控制(Traffic Policing)
漏桶算法描述如下:
-
一個固定容量的漏桶,按照常量固定速率流出水滴;
-
如果桶是空的,則不需流出水滴;
-
可以以任意速率流入水滴到漏桶;
-
如果流入水滴超出了桶的容量,則流入的水滴溢出了(被丟棄),而漏桶容量是不變的。
2.令牌桶(Token Bucket)
令牌桶算法是一個存放固定容量令牌(token)的桶,按照固定速率往桶裏添加令牌。
令牌桶算法基本可以用下面的幾個概念來描述:
- 假設限制10r/s,將按照每100毫秒的固定的速率往桶中添加令牌。
- 桶中最多存放b個令牌,當桶滿時,新添加的令牌被丟棄或拒絕。
- 當一個n個字節大小的數據包到達,將從桶中刪除n個令牌,接著數據包被發送到網絡上。
- 如果桶中的令牌不足n個,則不會刪除令牌,且該數據包將被限流(要麽丟棄,要麽緩沖區等待)。
令牌桶算法實際上由三部分組成:兩個流和一個桶,分別是令牌流、數據流與令牌桶。
令牌流與令牌桶
系統會以一定的速度生成令牌,並將其放置到令牌桶中,可以將令牌桶想象成一個緩沖區(可以用隊列這種數據結構來實現),當緩沖區填滿的時候,新生成的令牌會被扔掉。 這裏有兩個變量很重要:
- 第一個是生成令牌的速度,一般稱為 rate
- 第二個是令牌桶的大小,一般稱為 burst 。比如,我們設定 burst = 10 ,即令牌桶最大只能容納 10 個令牌
數據流
數據流是真正的進入系統的流量
有以下三種情形可能發生:
- 數據流的速率 等於 令牌流的速率。這種情況下,每個到來的數據包或者請求都能對應一個令牌,然後無延遲地通過隊列;
- 數據流的速率 小於 令牌流的速率。通過隊列的數據包或者請求只消耗了一部分令牌,剩下的令牌會在令牌桶裏積累下來,直到桶被裝滿。剩下的令牌可以在突發請求的時候消耗掉。
- 數據流的速率 大於 令牌流的速率。這意味著桶裏的令牌很快就會被耗盡。導致服務中斷一段時間,如果數據包或者請求持續到來,將發生丟包或者拒絕響應。
漏桶算法和令牌桶算法的比較
何時拒絕請求 | 限流策略 | |
---|---|---|
漏桶算法 | 漏桶是按照常量固定速率流出請求,流入請求速率任意,當流入的請求數累積到漏桶容量時,則新流入的請求被拒絕; | 漏桶限制的是常量流出速率(即流出速率是一個固定常量值,比如都是 1 的速率流出,而不能一次是 1 ,下次又是 2 ),從而平滑突發流入速率; |
令牌桶算法 | 令牌桶是按照固定速率往桶中添加令牌,請求是否被處理需要看桶中令牌是否足夠,當令牌數減為零時則拒絕新的請求; | 令牌桶限制的是平均流入速率(允許突發請求,只要有令牌就可以處理,支持一次拿 3 個令牌, 4 個令牌),並允許一定程度突發流量; |
參考資料
http://m635674608.iteye.com/blog/2339587 高並發系統限流《億級流量網站架構核心技術》第2部分 高可用 4.限流詳解
http://ju.outofmemory.cn/entry/102231 令牌桶算法/Token Bucket Algorithm
http://blog.51cto.com/leyew/860302 漏桶算法
高並發限流算法