Interpretation of the spike business: How Redis helps the high-concurrency spike system and perfectly solves the problem of oversell

Spike business

In the field of e-commerce, there are typical spike business scenarios, so what is a spike scenario? Simply put, the number of buyers of a product is far greater than the inventory of the product, and the product will be sold out in a short period of time. For example, business scenarios such as the annual 618, Double 11 big promotion, and Xiaomi's new product promotion are typical spike business scenarios.

The biggest feature of the spike business is the high instantaneous concurrent traffic. In the e-commerce system, the inventory quantity is often much smaller than the concurrent traffic. For example: Tmall’s spike activity may only have a few hundred or thousands of items in stock, and the influx of them instantly Concurrent purchases may reach tens to millions of traffic.

Therefore, we can summarize the business characteristics of the spike system as follows.

Insert picture description here

Friends who need more Java knowledge and interview questions can click the link below to get it for free

Link: 1103806531 Password: CSDN

Insert picture description here

(1) Limited time, limited quantity, price limit

In the specified time; the quantity of goods in the spike activity is limited; the price of the goods will be much lower than the original price, that is, in the spike activity, the goods will be sold at a price much lower than the original price.

For example, the time of the spike activity is limited to 10 am to 10:30 a.m., the quantity of goods is only 100,000 pieces, and the price of the goods is very low, such as: 1 yuan purchase and other business scenarios.

Time limit, limit and price can exist alone or in combination.

(2) Preheating activities

The event needs to be configured in advance; before the event has started, users can view the related information of the event; before the spike event starts, the event will be vigorously promoted.

(3) Short duration

The number of people buying is huge; goods will quickly sell out.

In the presentation of system traffic, there will be a sudden spike phenomenon. At this time, the number of concurrent visits is very high. In most spike scenarios, the goods will be sold out in a very short time.

Three spikes

Usually, from the beginning to the end of the spike, there are often three stages:

  • Preparation stage: This stage is also called the system warm-up stage. At this time, the business data of the spike system will be warmed up in advance. At this time, users will constantly refresh the spike page to check whether the spike activity has started. To a certain extent, some data can be stored in Redis for preheating through the user's continuous page refresh operation.
  • Spike phase: This phase is mainly the process of spike activity, which will generate instantaneous high concurrent traffic, which will have a huge impact on system resources. Therefore, system protection must be done in the spike phase.
  • Settlement stage: Data processing after the spike is completed, such as data consistency problem processing, abnormal situation processing, and commodity return processing.

Redis helps the spike system

We can design a Hash data structure in Redis to support the deduction of commodity inventory, as shown below.

seckill:goodsStock:${
    
    goodsId}{
    
    
    totalCount:200,
    initStatus:0,
    seckillCount:0
}

In the Hash data structure we designed, there are three very main attributes.

  • totalCount: indicates the total number of products participating in the spike. Before the spike activity starts, we need to load this value into the Redis cache in advance.
  • initStatus: We design this value as a Boolean value. Before the spike starts, this value is 0, which means that the spike has not started. You can modify this value to 1 through timed tasks or background operations to indicate that the spike starts.
  • seckillCount: Indicates the number of products that are seckilled. During the seckill process, the upper limit of this value is totalCount. When this value reaches totalCount, it means that the seckill of the product has been completed.

We can use the following code snippet to cache the product data loading that will participate in the spike during the preheating phase of the spike.

/**
 * @author binghe
 * @description 秒杀前构建商品缓存代码示例
 */
public class SeckillCacheBuilder{
    
    
    private static final String GOODS_CACHE = "seckill:goodsStock:"; 
    private String getCacheKey(String id) {
    
     
        return  GOODS_CACHE.concat(id);
    } 
    public void prepare(String id, int totalCount) {
    
     
        String key = getCacheKey(id); 
        Map<String, Integer> goods = new HashMap<>(); 
        goods.put("totalCount", totalCount); 
        goods.put("initStatus", 0); 
        goods.put("seckillCount", 0); 
        redisTemplate.opsForHash().putAll(key, goods); 
     }
}

When the spike starts, we need to first determine in the code whether the seckillCount value in the cache is less than the totalCount value. If the seckillCount value is indeed less than the totalCount value, we can lock the inventory. In our program, these two steps are not actually atomic. If in a distributed environment, we use multiple machines to operate the Redis cache at the same time, synchronization problems will occur, which will cause serious consequences of "oversold".

In the field of e-commerce, there is a professional term called "oversold". As the name implies: "Oversold" means that the number of goods sold is more than the number of goods in stock, which is a very serious problem in the field of e-commerce. So, how do we solve the "oversold" problem?

Lua script perfectly solves the oversold problem

How do we solve the synchronization problem of multiple machines operating Redis at the same time? A better solution is to use Lua scripts. We can use Lua scripts to encapsulate the inventory deduction operation in Redis into an atomic operation, so that the atomicity of the operation can be guaranteed, thereby solving the synchronization problem in a high-concurrency environment.

For example, we can write the following Lua script code to perform the inventory deduction operation in Redis.

local resultFlag = "0" 
local n = tonumber(ARGV[1]) 
local key = KEYS[1] 
local goodsInfo = redis.call("HMGET",key,"totalCount","seckillCount") 
local total = tonumber(goodsInfo[1]) 
local alloc = tonumber(goodsInfo[2]) 
if not total then 
    return resultFlag 
end 
if total >= alloc + n  then 
    local ret = redis.call("HINCRBY",key,"seckillCount",n) 
    return tostring(ret) 
end 
return resultFlag

We can use the following Java code to call the above Lua script.

public int secKill(String id, int number) {
    
     
    String key = getCacheKey(id); 
    Object seckillCount =  redisTemplate.execute(script, Arrays.asList(key), String.valueOf(number)); 
    return Integer.valueOf(seckillCount.toString()); 
}

In this way, when we perform the spike activity, we can ensure the atomicity of the operation, thereby effectively avoiding the problem of data synchronization, and effectively solving the "oversold" problem.

to sum up

I have compiled various knowledge points, modules, documents and more real interview questions from major companies. Friends in need can click the link below to get them for free

Link: 1103806531 Password: CSDN

Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_48655626/article/details/109223584