redis實現限速器的幾種方式

redis實現限速器的幾種方式

redis?實現限速器的幾種方式。

GET + INCR + EXPIRE

先獲取?key?的當前值,如果沒有超出限制再執行?INCR?增1,如果?key?不存在,使用?redis?的事務初始化?key?和過期時間。

(推薦:redis視頻教程

偽代碼:

count?=?redis.GET(key) if?redis?return?nil?{ ??redis.MULTI ??	redis.INCR(key) ??	redis.EXPIRE(key,?expire_time) ??redis.EXEC ??count?=?1 } if?count?>?limit?{ ??return?超出限制 }?else?{ ??redis.INCR(key) }

并發下的問題:

如果同時10個并發程序執行?GET?返回了?nil, 那么這10個并發程序都會執行?redis?的事務將?key?增一,但每個程序的?count?值都為1,如果?limit?設置的值小于10,那么真正執行的程序就超過限制了。如果執行完事務后再查一次?redis?賦值給?count,那么每個程序可能都會返回10,從而沒有程序能夠繼續執行。

key?已經存在的情況下,先?GET?后?INCR?的邏輯也可能會出現實際執行的程序數多于?limit?的情況。

INCR + EXPIRE

先?INCR, 如果值為1說明是?key?剛設置的,此時再執行?EXPIRE

偽代碼:

count?=?redis.INCR(key) if?count?==?1?{ ??redis.EXPIRE(key,?expire_time) } if?count?>?limit?{ ??return?超出限制 }

慎用

如果?INCR?之后程序掛掉了,沒有執行?EXPIRE, 那么這個?key?就沒有過期時間了,具體的影響視需求而定。

lua腳本

local?current current?=?redis.call("incr",KEYS[1]) if?tonumber(current)?==?1?then ????redis.call("expire",KEYS[1],1) end

更多redis知識請關注redis視頻教程欄目。

以上就是

? 版權聲明
THE END
喜歡就支持一下吧
點贊6 分享