Search code examples
javaredis

Redis Rate limiter


In the official redis documentation, the INCR command has the following operations:

FUNCTION LIMIT_API_CALL(ip)
current = LLEN(ip)
IF current > 10 THEN
    ERROR "too many requests per second"
ELSE
    IF EXISTS(ip) == FALSE
        MULTI
            RPUSH(ip,ip)
            EXPIRE(ip,1)
        EXEC
    ELSE
        RPUSHX(ip,ip)
    END
    PERFORM_API_CALL()
END

Official redis documentation describes that:Note that we have a race here, but it is not a problem: EXISTS may return false but the key may be created by another client before we create it inside the MULTI / EXEC block. However this race will just miss an API call under rare conditions, so the rate limiting will still work correctly.

I have a question. If I send 1w requests at the same time, won't it miss 9999 requests? Is this still working normally?

I hope some people can solve my problem.


Solution

  • How can you send such amount of requests at the same time? You need this amount of apps sending this amount of the exact same request at the exact same time. All with the exact distance from the server without any noise changing the pace of the request in such accuracy that all of them getting to the if before any of them got into the MULTI block.

    But the accurate and deterministic answer — Redis is single threaded, and each app can send one command at a specific point of time, meaning the problem can happen just if you have sharded server were more than one node in the shard is accepting write commands, meaning the rare case of exact same time can end with missing requests same as MIN(number of nodes accept writes in the shard, apps number).

    But it is an answer for algorithms exam at uni, in the real world one miss will happen one in billion, nonetheless more than one.