Rate limiter with Redis

使用redis来实现rate limiter
实现rate limiter 的想法:
1 Make sure: the gap between two requests >= 1/5

Acquire()
  If (now ­- mLastTime >= 0.2)
    mLastTime = Now;
    Return True;
  Else
    Return False;

这种方法会导致0.3s 后 0.4s 的请求失败

2 Algorithm of time-­‐bucket

Acquire() 
    s = GetCurrentSecond(); 
    If ( mCounter[s] >= 5 ) 
        Return False; 
    Else 
        mCounter[s]++; 
        Return True;

3 time-bucket with database

Expire: Set a timeout on key. After the timeout has expired, the key will automatically be deleted.

Database.Expire(s, 1); 帮助我们自动删除一个key在1s后。

Acquire() 
    s = GetCurrentSecond(); 
    counter = Database.Get(s); 
    If counter != NULL AND counter >= 5
        Return False; 
    Else 
        Database.Increase(s, 1); 
        Database.Expire(s, 1);  
        Return True;

我们使用 Redis 来做:
我们绑定ip和时间, 这样限制api的访问量。

FUNCTION LIMIT_API_CALL(ip)
ts = CURRENT_UNIX_TIME()
keyname = ip+":"+ts
current = GET(keyname)
IF current != NULL AND current > 10 THEN
    ERROR "too many requests per second"
ELSE
    MULTI                           // Marks the start of a transaction block. 
        INCR(keyname,1)   
        EXPIRE(keyname,10)  
    EXEC                          
    PERFORM_API_CALL()
END

Redis如何expire一个key

Redis通过passive 和 active 两种方式来进行的:

消极 就是当我们访问一个key时,发现它time out了,就删除它。

积极 就是我们主动随机的选出20个key在每10秒钟的间隔,然后删除过期的key。如果这个过期的比例高于25%,我们就在执行一遍积极删除。

Reference:
https://redis.io/commands/INCR
https://redis.io/commands/expire

你可能感兴趣的:(Rate limiter with Redis)