Redis 簡單限流

2021-09-11 21:23:06 字數 1036 閱讀 9308

首先我們來看乙個常見 的簡單的限流策略。系統要限定使用者的某個行為在指定的時間裡只能允許發生 n 次,如何使用 redis 的資料結構來實現這個限流的功能?

這個限流需求中存在乙個滑動時間視窗,想想 zset 資料結構的 score 值,是不是可以通過 score 來圈出這個時間視窗來。而且我們只需要保留這個時間視窗,視窗之外的資料都可以砍掉。那這個 zset 的 value 填什麼比較合適呢?它只需要保證唯一性即可,用 uuid 會比較浪費空間,那就改用毫秒時間戳吧。

如圖所示,用乙個 zset 結構記錄使用者的行為歷史,每乙個行為都會作為 zset 中的乙個 key 儲存下來。同乙個使用者同一種行為用乙個 zset 記錄。

為節省記憶體,我們只需要保留時間視窗內的行為記錄,同時如果使用者是冷使用者,滑動時間視窗內的行為是空記錄,那麼這個 zset 就可以從記憶體中移除,不再占用空間。

通過統計滑動視窗內的行為數量與閾值 max_count 進行比較就可以得出當前的行為是否允許。用**表示如下:

public class ******ratelimiter 

public boolean isactionallowed(string userid, string actionkey, int period, int maxcount)

public static void main(string args)

}}

整體思路就是:每乙個行為到來時,都維護一次時間視窗。將時間視窗外的記錄全部清理掉,只保留視窗內的記錄。zset 集合中只有 score 值非常重要,value 值沒有特別的意義,只需要保證它是唯一的就可以了。

因為這幾個連續的 redis 操作都是針對同乙個 key 的,使用 pipeline 可以顯著提公升 redis 訪問效率。但這種方案也有缺點,因為它要記錄時間視窗內所有的行為記錄,如果這個量很大,比如限定 60s 內操作不得超過 100w 次這樣的引數,它是不適合做這樣的限流的,因為會消耗大量的儲存空間。

redis簡單限流

需求 如果要保證乙個使用者一分鐘內只能訪問5次介面,超過就拒絕範圍。這個限流需求中存在乙個滑動時間視窗,想想 zset 資料結構的 score 值,是不是可以通過 score 來圈出這個時間視窗來。而且我們只需要保留這個時間視窗,視窗之外的資料都可以砍掉。那這個 zset 的 value 填什麼比較...

Redis 限流演算法

判斷有限時間內的數量是否超過限制上線 date default timezone set prc class limitelse elseelse else 有問題,併發上來,一直就允許5個,但是利用 pipeline 保證了各個client之間的原子性 function isactionallow...

使用Redis進行限流

通過使用註解 提供介面形式與引數形式2種方式 針對性的對介面進行限流,底層使用redis配合lua指令碼實現令牌桶。public class redisratelimiter public boolean tryacquire string flag,int maxpermits,int addra...