Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Realization of distributed current limiter by Redis and Lua

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article shows you Redis and Lua to achieve distributed current limiter, the content is concise and easy to understand, can definitely make your eyes bright, through the detailed introduction of this article, I hope you can get something.

Principle

The counter algorithm refers to the fixed number of requests allowed to pass over a period of time, such as 10 / s, 500 / 30 seconds.

If the set time granularity is finer, then the current limit will be smoother.

Realize

The Lua script used

-- counter current limit-the minimum unit time supported here is seconds, and millisecond granularity can be supported if expire is changed to pexpire.-- key-- ARGV [1] int current limits of KEYS [1] string current limits-- ARGV [2] int unit time (seconds) local cnt = tonumber (redis.call ("incr", KEYS [1]) if (cnt = 1) then-cnt value 1 means that this value does not exist before Therefore, you need to set its expiration time redis.call ("expire", KEYS [1], tonumber (ARGV [2])) elseif (cnt > tonumber (ARGV [1])) then return-1end return cnt

Return-1 indicates that the current limit is exceeded, otherwise the number of requests that have passed per unit time is returned.

Key can, but is not limited to, the following situations

Ip + interface

User_id + interface

Advantages

Easy to implement

Shortcoming

If the granularity is not fine enough, double the number of requests will occur in the same window time.

Be careful

Try to keep the time granularity fine.

Scene analysis

Eg. Current limit of 1000,000,3s

Extreme case 1:

Number of requests in 1 second 10

Number of requests in the second second 10

Number of requests in the 3rd second 980

Number of requests in the 4th second 900

Number of requests in the 5th second 100

Number of requests in the 6th second 0

Note that the total number of requests in 3-5 seconds is as high as 1980.

Extreme case 2:

Number of requests in the first second 1000

Number of requests in the second second 0

Number of requests in the 3rd second 0

At this point, there will be a large number of rejected requests in the next 2 ~ 3 seconds.

Token bucket mode

Principle

Token bucket

There is a token in the bucket, there is an upper limit, and it is full at first.

Tokens are consumed for each request (different tokens can be consumed according to different requests)

Tokens are placed in the bucket at regular intervals (at a fixed rate).

The implementation of the bucket is also divided into:

Pre-consumable

Advance tokens: predecessors dig holes, posterity jumps

Unpredictable consumption

There are not enough tokens to refuse directly.

Realize

The non-pre-consumable token bucket implemented here, specific Lua code:

-- token bucket current limit: pre-consumption is not supported Initial bucket is full-KEYS [1] string current limited key-- ARGV [1] int bucket maximum capacity-ARGV [2] int token addition interval-ARGV [3] int token addition interval (seconds)-ARGV [4] int current timestamp local bucket_capacity = tonumber (ARGV [1]) local add_token = tonumber (ARGV [2]) local add_interval = tonumber (ARGV [3]) local now = tonumber (ARGV [4]) ])-- keylocal LAST_TIME_KEY = KEYS [1] when the bucket was last updated. "_ time" -- get the number of tokens in the current bucket local token_cnt = redis.call ("get", KEYS [1])-- the maximum length of time required for full recovery of the bucket local reset_time = math.ceil (bucket_capacity / add_token) * add_interval If token_cnt then-token bucket exists-time the bucket was last updated local last_time = redis.call ('get', LAST_TIME_KEY)-recovery multiple local multiple = math.floor ((now-last_time) / add_interval)-restore token number local recovery_cnt = multiple * add_token-ensure that the bucket capacity is not exceeded local token_cnt = math.min (bucket_capacity Token_cnt + recovery_cnt)-1 if token_cnt < 0 then return-1 End-- reset expiration time to avoid key expiration redis.call ('set', KEYS [1], token_cnt,' EX', reset_time) redis.call ('set', LAST_TIME_KEY, last_time + multiple * add_interval,' EX', reset_time) return token_cnt else-- token bucket does not exist token_cnt = bucket_capacity-1-- set expiration time to prevent key from persisting redis.call ('set') KEYS [1], token_cnt, 'EX', reset_time) Redis.call ('set', LAST_TIME_KEY, now,' EX', reset_time + 1); return token_cnt end

The key to the token bucket is the following parameters:

Maximum capacity of barrel

Number of tokens placed at a time

The interval between placing tokens

The implementation of token bucket will not cause the problem of double traffic per unit time in counter mode.

The above is the implementation of distributed current limiter by Redis and Lua. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report