Home > Database > Redis > body text

How can redis implement current limiting?

王林
Release: 2021-01-20 09:16:57
forward
2151 people have browsed it

How can redis implement current limiting?

Purpose:

  • Realize access frequency limit

  • Realize visitor $ip within a certain limit You can only access $limit times within time $time

(Learning video sharing: redis video tutorial)

Non-script implementation

private boolean accessLimit(String ip, int limit, int time, Jedis jedis) {

    boolean result = true; String key = "rate.limit:" + ip; if (jedis.exists(key)) { long afterValue = jedis.incr(key); if (afterValue > limit) { result = false; } } else { Transaction transaction = jedis.multi(); transaction.incr(key); transaction.expire(key, time); transaction.exec(); }  return result; }
Copy after login

The above code has two flaws

Racing conditions may occur: The solution is to use WATCH to monitor changes in rate.limit:$IP, but it is more troublesome; the above code does not use pipeline In this case, up to 5 instructions need to be requested from Redis, which is too much to transmit.

Lua script implementation

Redis allows Lua scripts to be transferred to the Redis server for execution, and can be called within the script Most Redis commands, and Redis guarantees the atomicity of scripts:

First you need to prepare Lua code: script.lua

--

-- Created by IntelliJ IDEA.

-- User: jifang

-- Date: 16/8/24

-- Time: 下午6:11 -- local key = "rate.limit:" .. KEYS[1] local limit = tonumber(ARGV[1]) local expire_time = ARGV[2] local is_exists = redis.call("EXISTS", key) if is_exists == 1 then if redis.call("INCR", key) > limit then return 0 else return 1 end else redis.call("SET", key, 1) redis.call("EXPIRE", key, expire_time) return 1 end
Copy after login

Java

private boolean accessLimit(String ip, int limit, int timeout, Jedis connection) throws IOException { List<String> keys = Collections.singletonList(ip); List<String> argv = Arrays.asList(String.valueOf(limit), String.valueOf(timeout)); return 1 == (long) connection.eval(loadScriptString("script.lua"), keys, argv); } // 加载Lua代码 private String loadScriptString(String fileName) throws IOException { Reader reader = new InputStreamReader(Client.class.getClassLoader().getResourceAsStream(fileName)); return CharStreams.toString(reader); }
Copy after login

Lua embedded Redis advantages:

Reduce network overhead: Code that does not use Lua needs to send multiple requests to Redis, but the script only needs to be sent once, reducing network transmission; Atomic operations: Redis executes the entire script as an atomic, no need to worry Concurrency means there is no need for transactions; reuse: the script will be permanently saved in Redis and other clients can continue to use it.

Related recommendations: redis database tutorial

The above is the detailed content of How can redis implement current limiting?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:csdn.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!