Home  >  Article  >  Database  >  Introducing the Redis atomic counter incr to prevent concurrent requests

Introducing the Redis atomic counter incr to prevent concurrent requests

藏色散人
藏色散人forward
2020-09-04 13:50:543164browse

The following column Redis Tutorial will introduce to you the Redis atomic counter incr to prevent concurrent requests. I hope it will be helpful to friends in need!

Introducing the Redis atomic counter incr to prevent concurrent requests

1. Introduction
In some systems or functions that have restrictions on high concurrent requests, such as flash sale activities, or some websites returning too many current users, Please try later. These limit the number of requests at the same time and are generally used to protect the background system and prevent the system from crashing due to excessive traffic impact. Regarding the consequences of a system crash, it is obviously more acceptable to the maintainers to reject some requests.
Among various current limitations, in addition to the counter with a lock mechanism designed by the system itself, using Redis to implement it is obviously an efficient, safe, convenient and convenient way.

2. Incr command
The Redis Incr command increases the numerical value stored in key by one.
If key does not exist, the value of key will be initialized to 0 first, and then the INCR operation will be performed.
If the value contains the wrong type, or a value of type string cannot be represented as a number, then an error is returned.
The value of this operation is limited to 64-bit (bit) signed digital representation.
Example:

127.0.0.1:6379> set num 10
OK
127.0.0.1:6379> incr num
(integer) 11
127.0.0.1:6379> get num    # 数字值在 Redis 中以字符串的形式保存
"11"

Note: Since redis does not have a clear type to represent integer data, this operation is a string operation.
When performing this operation, the string stored corresponding to the key is parsed into decimal 64-bit signed integer data.
In fact, Redis internally uses integer representation (Integer representation) to store corresponding integer values, so this type of string value is actually stored in integer, so there is no string representation (String representation) for storing integers. the additional consumption caused.

3. Usage scenarios
1. Counter
The usage idea is: every time there is a related operation, send an incr command to the Redis server.
For example, this is a scenario: We have a web application, and we want to record the number of times each user visits this website every day.
The web application only needs to concatenate the user ID and the string representing the current time as the key, and execute the incr command on this key every time the user visits this page.

This scenario can have many extension methods:
By combining the INCR and EXPIRE commands, a counter that only records the number of visits by the user within a specified interval can be implemented
The client can pass GETSET The command gets the current counter value and resets it to 0
Through atomic increment/decrement commands such as DECR or INCRBY, certain values ​​can be increased or decreased according to the user's operations. For example, in online games, the user's game score needs to be calculated. With real-time control, scores may increase or decrease.

2. Speed ​​limiter
The speed limiter is a special scenario that can limit the execution rate of certain operations.
The traditional example is to limit the number of requests for a certain public API.
Suppose we want to solve the following problem: limit the number of requests for an API to no more than 10 per second per IP.
We can solve this problem in two ways through the incr command.

4. Java implementation of flow control
Here we will use the redis-incr feature in java to build a control code that only allows 100 requests in 1 minute. The key represents the value stored in redis. The key value being controlled.

public static boolean flowControl(String key){        //最大允许100
        int max = 100;        long total = 1L;        try {            if (jedisInstance.get(key) == null) {                //jedisInstance是Jedis连接实例,可以使单链接也可以使用链接池获取,实现方式请参考之前的blog内容                //如果redis目前没有这个key,创建并赋予0,有效时间为60s
                jedisInstance.setex(key, 60, "0");
            } else {                //获取加1后的值
                total = jedisInstance.incr(redisKey).longValue();                //Redis TTL命令以秒为单位返回key的剩余过期时间。当key不存在时,返回-2。当key存在但没有设置剩余生存时间时,返回-1。否则,以秒为单位,返回key的剩余生存时间。
                if (jedisInstance.ttl(redisKey).longValue() == -1L)
                {                    //为给定key设置生存时间,当key过期时(生存时间为0),它会被自动删除。
                    jedisInstance.expire(redisKey, 60);
                }
            }
        } catch (Exception e) {
            logger.error("流量控制组件:执行计数操作失败,无法执行计数");
        }        long keytotaltransations = max;        //判断是否已超过最大值,超过则返回false
        if (total > keytotaltransations) {            return false;
        }        return true;
    }

The above is the detailed content of Introducing the Redis atomic counter incr to prevent concurrent requests. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:cnblogs.com. If there is any infringement, please contact admin@php.cn delete