Home > Database > Redis > body text

Let's talk about the issue of realizing flash sales with Redis

WBOY
Release: 2022-05-27 21:00:06
forward
3235 people have browsed it

This article brings you relevant knowledge about Redis, which mainly introduces the relevant content about realizing flash sales, including flash sale logic, existing link timeouts, overselling and inventory legacy Let’s take a look at the problem below. I hope it will be helpful to everyone.

Let's talk about the issue of realizing flash sales with Redis

Recommended learning: Redis video tutorial

1. Flash sale logic

Second sale : Solve the transaction operations of counters and personnel records

    ##1. Judgment that uid and proid are not empty
  1. 2. Connect to redis
  2. 3. Splicing key
    • Inventory key
    • Successful flash sale user key
  3. 4. Get the inventory. If the inventory is null, the flash sale has not started yet
  4. 5. Determine whether the user repeats the flash sale operation
  5. 6. Determine the quantity of the product. If the inventory quantity is less than 1, the flash sale ends
  6. 7. Flash sale process
    • Inventory-1
    • Add users who have successfully flash killed to the list
2. Problems

2.1. Connection timeout

Reason: Due to a large number of Creating a connection consumes a lot of performance, and sometimes the connection is not obtained in time, and the connection times out.

2.2. Overselling

occurs under concurrent conditions, that is, when the output is out of stock (flash sale) After the end), there are still goods sold, resulting in a negative inventory quantity.


Lets talk about the issue of realizing flash sales with Redis

2.3. Inventory legacy

After using optimistic lock to solve problem 2, problem 3 appears

If the inventory quantity is relatively more concurrent, due to the use of optimism Lock, after the first user succeeds in the flash sale, the version number of the inventory key will be modified. Other users who grab it will be unable to continue purchasing due to different version numbers, and there will be inventory legacy issues

3. Solution

3.1. Connection timeout

Use connection pool, the tool class is as follows:

public class JedisPoolUtil {
	private static volatile JedisPool jedisPool = null;
	private JedisPoolUtil() {
	}
	public static JedisPool getJedisPoolInstance() {
		if (null == jedisPool) {
			synchronized (JedisPoolUtil.class) {
				if (null == jedisPool) {
					JedisPoolConfig poolConfig = new JedisPoolConfig();
					poolConfig.setMaxTotal(200);
					poolConfig.setMaxIdle(32);
					poolConfig.setMaxWaitMillis(100 * 1000);
					poolConfig.setBlockWhenExhausted(true);
					poolConfig.setTestOnBorrow(true);
					jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379, 60000);
				}
			}
		}
		return jedisPool;
	}}//使用JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();Jedis jedis = jedisPoolInstance.getResource();
Copy after login
springBoot version (pom.xml introduction, application.yml configuration, and then inject the object)

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-data-redis</artifactid></dependency><dependency>
    <groupid>redis.clients</groupid>
    <artifactid>jedis</artifactid>
    <version>3.2.0</version></dependency>
Copy after login
spring:
  redis:
    host: 127.0.0.1    port: 6379
    database: 0
    timeout: 1800000
    lettuce:
      pool:
        max-active: 20
        max-wait: -1
        max-idle: 5
        min-idle: 0
Copy after login
    @Autowired
    private RedisTemplate redisTemplate;
Copy after login
3.2. Oversold problem

Use Redis transaction, optimistic lock watch

//监视库存
jedis.watch(kcKey);//中间代码忽略

//7 秒杀过程
//使用事务
Transaction multi = jedis.multi();//组队操作
multi.decr(kcKey);multi.sadd(userKey,uid);//执行
List<object> results = multi.exec();if(results == null || results.size()==0) {
    System.out.println("秒杀失败了....");
    jedis.close();
    return false;}</object>
Copy after login
3.3. Inventory legacy problems caused by optimistic lock

Use Lua embedded scripting language

    Write complex or multi-step Redis operations as a script and submit it to Redis for execution at one time to reduce the number of repeated connections to redis. Improve performance.
  1. LUA script is similar to a redis transaction. It has a certain degree of atomicity and will not be queued by other commands. It can complete redis transactional operations.
  2. LUA script function is only available in Redis 2.6 or above. You can use
  3. to use lua scripts to eliminate users and solve the overselling problem.
  4. After version 2.6 of redis, the contention problem is solved through
  5. lua script. In fact, redis uses its single-threaded feature to solve the multi-task concurrency problem using a task queue.
  6. local userid=KEYS[1];				//1、2行定义两个变量,					
    local prodid=KEYS[2];
    local qtkey="sk:"..prodid..":qt";	//3,4行定义拼接key
    local usersKey="sk:"..prodid..":usr";
    local userExists=redis.call("sismember",usersKey,userid); //5-8,判断用户是否存在,不存在return 2
    if tonumber(userExists)==1 then
        return2;
    end
    local num=redis.call("get",qtkey);	//9-11,判断商品是否存在
    if tonumber(num)
    Copy after login
The complete code is as follows:

// 定义两段Lua脚本(使用Lua脚本可以解决乐观锁带来的库存遗留问题)
	static String secKillScript =
			"local userid=KEYS[1];\r\n" +
					"local prodid=KEYS[2];\r\n" +
					"local qtkey='sk:'..prodid..\":qt\";\r\n" +
					"local usersKey='sk:'..prodid..\":usr\";\r\n" +
					"local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
					"if tonumber(userExists)==1 then \r\n" +
					"   return 2;\r\n" +
					"end\r\n" +
					"local num= redis.call(\"get\" ,qtkey);\r\n" +
					"if tonumber(num)Recommended learning: <p>Redis video tutorial<a href="https://www.php.cn/course/list/54.html" target="_blank"></a></p>
Copy after login

The above is the detailed content of Let's talk about the issue of realizing flash sales with Redis. 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!