>데이터 베이스 >Redis >Redis를 통해 재고 감소의 플래시 세일 시나리오를 구현하는 방법

Redis를 통해 재고 감소의 플래시 세일 시나리오를 구현하는 방법

WBOY
WBOY앞으로
2023-06-02 09:04:20795검색

Redis 인벤토리 공제의 주요 목적은 데이터베이스에 대한 액세스를 줄이는 것입니다. 기존 인벤토리 감소는 데이터베이스에 직접 액세스하여 인벤토리를 읽습니다. 동시 요청이 많을 경우 많은 양의 읽기 데이터로 인해 데이터베이스가 붕괴될 수 있습니다.

사용 아이디어:

  • 시스템이 초기화되면 제품 인벤토리가 Redis 캐시에 로드되어 저장됩니다.

  • 요청을 받으면 먼저 Redis에서 해당 제품의 재고 값을 가져오고, 축소 후 재고가 부족할 경우 논리적 예외가 직접 반환되며 액세스할 필요가 없습니다. 재고 값을 줄이기 위해 데이터베이스를 사용하세요. 재고 값이 정확하면 다음 단계로 진행하세요.

  • 요청을 대기열에 추가하고 즉시 값을 프런트 엔드에 반환하여 해당 요청이 대기열에 있음을 표시한 다음 플래시 판매 로직을 수행합니다. 백엔드 대기열은 플래시 종료 로직을 ​​수행합니다. 플래시 세일이 성공하면 성공이 반환되고, 그렇지 않으면 실패가 반환됩니다.

첫 번째 단계: 시스템 초기화 후 모든 제품 재고를 캐시에 넣습니다

/**
 * 秒杀接口优化之---   第一步:  系统初始化后就将所有商品库存放入 缓存
 */
@Override
public void afterPropertiesSet() throws Exception {
    List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {
        return;
    }
    for (GoodsVo goodsVo : goods) {
        redisService.set(GoodsKey.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);//先初始化 每个商品都是false 就是还有
    }
}

두 번째 단계: 감소 전 재고가 캐시에서 줄어듭니다

/**秒杀接口优化之 ----第二步: 预减库存 从缓存中减库存
 * 利用 redis 中的方法,减去库存,返回值为 减去1 之后的值
 * */
long stock = redisService.decr(GoodsKey.getGoodsStock, "" + goodsId);
/*这里判断不能小于等于,因为减去之后等于 说明还有是正常范围*/
if (stock < 0) {
    isOverMap.put(goodsId, true);//没有库存就设置 对应id 商品的map 为true
    return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
}

전체 로직은 다음과 같습니다.

1 먼저 모든 데이터를 읽어서 캐시에 초기화한 후, stock + goodid 형태로 Redis에 저장합니다.

2. 플래쉬 세일 중, 먼저 감소 전 재고 감지를 수행하여 redis에서 해당 상품의 재고를 차감합니다. 재고가 0 미만이면 현재 재고가 부족하다는 뜻입니다. 데이터베이스에 액세스할 필요가 없습니다. 그냥 예외를 직접 던져보세요.
위에서는 메모리 표시인 isOverMap도 사용했습니다.

메모리 태그

인터페이스 최적화로 인해 많은 Redis 기반 캐시 작업은 동시성이 높을 때 Redis 서버에 큰 부담을 주게 됩니다. Redis 서버에 대한 액세스를 줄일 수 있다면 최적화도 달성할 수 있습니다. 효과.

그래서 해당 제품의 재고가 아직 남아 있는지 표시하기 위해 메모리 맵을 추가하면 Redis에 접속하기 전에 해당 제품의 재고 표시를 맵에서 얻을 수 있으며, 재고가 없음을 확인할 수 있습니다. Redis에 액세스하지 않고.

1. 맵을 생성하고 초기화 시 모든 제품의 ID를 키로 사용하고 이를 false로 표시하여 맵에 저장합니다.

private Map<Long, Boolean> isOverMap = new HashMap<Long, Boolean>();
/**
 * 秒杀接口优化之---   第一步:  系统初始化后就将所有商品库存放入 缓存
 */
@Override
public void afterPropertiesSet() throws Exception {
    List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {
        return;
    }
    for (GoodsVo goodsVo : goods) {
        redisService.set(GoodsKey.getGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);//先初始化 每个商品都是false 就是还有
    }
}
/**再优化: 优化 库存之后的请求不访问redis 通过判断 对应 map 的值
  * */
boolean isOver = isOverMap.get(goodsId);
if (isOver) {
     return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
}

if (stock < 0) {
     isOverMap.put(goodsId, true);//没有库存就设置 对应id 商品的map 为true
}

2. 재고를 미리 줄이기 전에 지도에서 표시를 받아보세요. 표시가 거짓이면 재고가 부족하다는 의미입니다.

재고가 부족할 경우 미리 제품의 재고를 줄여서 표시하세요. 이는 해당 제품의 재고가 부족함을 나타냅니다. 아래의 모든 요청은 차단되며 사전 재고 감소를 위해 Redis에 액세스할 필요가 없습니다.

그래서 캐시를 활용하는 전체적인 아이디어는 다음과 같습니다.

제품의 재고 데이터를 메모리에 로드하는 동시에 메모리 태그를 초기화합니다. 즉, 각 제품의 ID를 맵에 저장합니다. , 이는 false로 초기화되어 매번 플래시 세일 로직을 실행했습니다. 이전에는 메모리 마크에서 값을 검색할 때 여전히 재고가 있는 경우, 즉 맵이 false를 반환하면 플래시 세일 로직이 실행되고, 그렇지 않으면 플래시 세일 로직이 실행되었습니다. 예외가 직접 발생합니다.

인벤토리 공제와 동시에 캐시에 있는 인벤토리 수량이 여전히 0보다 큰지 확인해야 합니다. 0보다 작거나 같은 경우 메모리 표시를 수정합니다.

위 내용은 Redis를 통해 재고 감소의 플래시 세일 시나리오를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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