Maison  >  Article  >  base de données  >  Comment réaliser un scénario de vente flash de réduction des stocks via Redis

Comment réaliser un scénario de vente flash de réduction des stocks via Redis

WBOY
WBOYavant
2023-06-02 09:04:20753parcourir

L'objectif principal de la déduction d'inventaire Redis est de réduire l'accès à la base de données.La réduction d'inventaire précédente accédait directement à la base de données et lisait l'inventaire. Lorsque des demandes simultanées élevées surviennent, une grande quantité de données lues peut entraîner l'effondrement de la base de données.

Idée d'utilisation :

  • Lorsque le système est initialisé, l'inventaire des produits est chargé dans le cache Redis et enregistré.

  • Lors de la réception de la demande, récupérez d'abord la valeur d'inventaire du produit dans Redis et pré-réduisez l'inventaire si l'inventaire est insuffisant après la réduction, une Exception logique sera renvoyée directement et il n'est pas nécessaire d'accéder au base de données pour réduire l'inventaire. Si la valeur de l'inventaire est correcte, passez à l'étape suivante.

  • Mettez la demande en file d'attente et renvoyez immédiatement une valeur au front-end, indiquant qu'elle est dans la file d'attente, puis exécutez la logique de vente flash. La file d'attente backend exécute la logique de flash kill. le backend. Si la vente flash réussit, la vente flash est renvoyée. Succès, sinon l'échec est renvoyé.

La première étape : une fois le système initialisé, mettez tout l'inventaire des produits dans le cache

/**
 * 秒杀接口优化之---   第一步:  系统初始化后就将所有商品库存放入 缓存
 */
@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 就是还有
    }
}

La deuxième étape : l'inventaire de pré-réduction est réduit du cache

/**秒杀接口优化之 ----第二步: 预减库存 从缓存中减库存
 * 利用 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);
}

La logique globale est la suivante :

1 .Mettez d'abord toutes les données, lisez-les, initialisez-les dans le cache et stockez-les dans Redis sous la forme de stock + goodid.

2. Lors de la vente flash, effectuez d'abord une détection d'inventaire avant réduction, utilisez decr pour soustraire l'inventaire du produit correspondant. Si l'inventaire est inférieur à 0, cela signifie que l'inventaire est insuffisant à ce moment-là. et il n'est pas nécessaire d'accéder à la base de données. Lancez simplement une exception directement.
Nous avons également utilisé isOverMap ci-dessus, qui est une marque mémoire.

Balise mémoire

En raison de l'optimisation de l'interface, de nombreuses opérations de cache basées sur Redis apporteront également une lourde charge au serveur Redis lorsque la concurrence est élevée. Si l'accès au serveur Redis peut être réduit, une optimisation peut également être réalisée. . Effet.

Ainsi, vous pouvez ajouter une carte mémoire pour marquer si l'inventaire du produit correspondant est toujours disponible. Avant d'accéder à Redis, vous pouvez obtenir la marque d'inventaire du produit correspondant dans la carte et vous pouvez déterminer qu'il n'y a pas d'inventaire. sans accéder à Redis.

1. Générez une carte et lors de l'initialisation, utilisez les identifiants de tous les produits comme clés, marquez-les comme faux et stockez-les dans la carte.

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. Avant de pré-réduire l'inventaire, récupérez la marque sur la carte. Si la marque est fausse, cela signifie que l'inventaire est insuffisant

Lorsque l'inventaire est insuffisant, réduisez l'inventaire du produit à l'avance et marquez-le. comme vrai, indiquant que l'inventaire du produit est insuffisant. Toutes les demandes ci-dessous seront interceptées et il n'est pas nécessaire d'accéder à Redis pour la réduction du pré-stock.

Donc, l'idée générale de l'utilisation du cache est la suivante :

Chargez les données d'inventaire du produit dans la mémoire et en même temps initialisez la balise mémoire, c'est-à-dire stockez l'identifiant de chaque produit dans la carte , qui est initialisé à false, et exécute la logique de vente flash à chaque fois. Auparavant, lorsque la valeur était récupérée de la marque mémoire, s'il y avait encore du stock, c'est-à-dire que la valeur de retour dans la carte était fausse, la logique de vente flash serait être exécuté, sinon une exception serait levée directement.

Lors de la déduction de l'inventaire en même temps, vous devez déterminer si la quantité d'inventaire dans le cache est toujours supérieure à 0. Si elle est inférieure ou égale à 0, modifiez la marque mémoire.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer