>  기사  >  데이터 베이스  >  Redis를 활용한 Flash Sales 실현 문제에 대해 이야기해 보겠습니다.

Redis를 활용한 Flash Sales 실현 문제에 대해 이야기해 보겠습니다.

WBOY
WBOY앞으로
2022-05-27 11:40:343254검색

이 기사에서는 Redis에 대한 관련 지식을 주로 소개합니다. 플래시 세일 로직, 기존 링크 시간 초과, 과잉 판매 및 재고 문제를 포함하여 모두에게 도움이 되기를 바랍니다. .

Redis를 활용한 Flash Sales 실현 문제에 대해 이야기해 보겠습니다.

추천 학습: Redis 비디오 튜토리얼

1. 플래시 킬 로직

스파이크 킬: 카운터 및 인사 기록의 트랜잭션 작업 해결

  1. 1.
  2. 2. redis 연결
  3. 3. 스플라이스 키
    • 인벤토리 키
    • 플래시 세일 사용자 키 성공
  4. 4.인벤토리가 null이면 아직 플래시 세일이 시작되지 않은 것입니다
  5. 5. 사용자가 플래시 세일 작업을 반복했는지 확인
  6. 6. 제품 수량을 확인하고, 재고 수량이 1 미만이며, 플래시 세일이 끝났습니다
  7. 7. 재고 -1
    • 추가. 플래시세일에 성공한 사용자를 리스트에 추가
    2. 문제가 있습니다
2.1.연결 시간 초과

원인: 많은 연결이 생성되어 성능을 많이 소모하며 때로는 연결이 끊어지는 경우도 있습니다.

2.2, 과매도

가 동시 발생합니다. 즉, 출력이 품절된 후에도 제품이 남아 있습니다(플래시 세일 종료). 판매로 인해 마이너스 재고 수량이 발생합니다.


2.3.인벤토리 레거시Redis를 활용한 Flash Sales 실현 문제에 대해 이야기해 보겠습니다.

문제 2를 해결하기 위해 낙관적 잠금을 사용한 후 문제 3이 나타납니다

낙관적 잠금 사용으로 인해 인벤토리 수량이 상대적으로 더 많은 경우 첫 번째 사용자가 버전 번호를 수정합니다. 플래시 세일 성공 후 인벤토리 키를 획득한 다른 사용자는 버전 번호 차이로 인해 구매를 계속할 수 없으며 인벤토리 문제가 발생합니다.

3. 해결

3.1, 연결 시간 초과

연결 풀을 사용하세요. 도구 클래스는 다음과 같습니다.

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();

springBoot 버전(pom .xml 소개, application.yml 구성 후 개체 삽입)

<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>
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
    @Autowired
    private RedisTemplate redisTemplate;
3.2 과매도 문제

Redis 트랜잭션 사용, 낙관적 잠금 + 감시

//监视库存
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>

3.3 . 낙관적 잠금으로 인한 인벤토리 레거시 문제

Lua 임베딩 사용 스크립팅 언어

는 복잡하거나 다단계 Redis 작업을 스크립트로 작성하고 이를 Redis에 제출하여 한 번에 실행함으로써 Redis에 대한 반복 연결 횟수를 줄입니다. 성능을 향상시킵니다.

    LUA 스크립트는 특정 원자성을 가지며 다른 명령에 의해 대기열에 추가되지 않습니다.
  1. LUA 스크립트 기능은 Redis 버전 2.6 이상에서만 사용할 수 있습니다. 사용자를 제거하고 과매도 문제를 해결하는 스크립트입니다.
  2. Redis 버전 2.6 이상에서는
  3. lua 스크립트를 통해 경합 문제를 해결합니다. 실제로
  4. redis는 단일 스레드 기능을 사용하여 작업 대기열을 사용하여 다중 작업 동시성 문제를 해결합니다
  5. .
  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)<strong>전체 코드는 다음과 같습니다. </strong><pre class="brush:php;toolbar:false">// 定义两段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)
    추천 학습:
  7. Redis 비디오 튜토리얼

위 내용은 Redis를 활용한 Flash Sales 실현 문제에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제