redis several ways to achieve speed limiter.
GET + INCR + EXPIRE
First get the current value of the key, if not exceed the limit and then execute INCR increased by 1 if the key does not exist, the use of redis transactions and initialization key expiration time.
Fake code:
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 exceeds the limit } else { redis.INCR(key) }
Under high concurrency issues:
If both the 10 concurrent program execution GET returns nil, then this program will be 10 concurrent execution redis transaction will add a key, but the count value of each program are 1, if the limit value set is less than 10, then the real execution the program exceeded the limit. If you do complete the transaction after the investigation once redis assigned to count, so each program may all return 10, so that no program can continue.
Case key already exists, after the first GET INCR logic may also be the case more than the number of actual implementation of the program limit appears.
INCR + EXPIRE
INCR First, if the value of 1 indicates key is just set, this time to perform EXPIRE
Fake code:
count = redis.INCR(key) if count == 1 { redis.EXPIRE(key, expire_time) } if count > limit { return exceeds the limit }
Caution
If after INCR program hang, no execution EXPIRE, then the key is no expiration date, the specific effects depending on demand.
lua script
local current current = redis.call("incr",KEYS[1]) if tonumber(current) == 1 then redis.call("expire",KEYS[1],1) end
Learn more information, please visit: