La structure redis Hash stocke l'inventaire des produits de base et le problème de concurrence dans le scénario seckill

Dans le scénario de vente flash, l'utilisation de la structure Redis Hash pour stocker l'inventaire des produits peut rencontrer des problèmes de simultanéité. En effet, un grand nombre d'utilisateurs essaient d'acheter le même produit en même temps pendant le Lightning Deal, ce qui entraîne des demandes simultanées.

Voici un scénario de problème de concurrence possible :

  1. Supposons qu'il y ait 100 quantités de produits (la clé est "stock" et la valeur est 100) stockées dans la structure de hachage de Redis.
  2. L'utilisateur A et l'utilisateur B interrogent l'inventaire en même temps et trouvent tous deux que l'inventaire est de 100.
  3. L'utilisateur A soumet une commande et réduit la quantité de stock à 99.
  4. L'utilisateur B soumet également une commande, réduisant la quantité de stock à 99 (en fait, elle devrait être de 98).

Il ressort du scénario ci-dessus que, dans des conditions simultanées, plusieurs utilisateurs peuvent interroger la même quantité de stock en même temps et se précipiter pour acheter des marchandises en même temps en fonction des résultats de la requête, ce qui entraîne une réduction réelle des stocks dépassant la valeur réelle. inventaire.

Afin de résoudre le problème de concurrence, les solutions suivantes peuvent être envisagées :

  1. Utilisez les transactions Redis (Transaction) pour assurer les opérations atomiques. Grâce à des commandes telles que MULTI, HGET et HSET, les opérations d'interrogation de l'inventaire et de réduction de l'inventaire sont exécutées en une seule transaction. Cela garantit l'atomicité de plusieurs commandes et évite les problèmes de concurrence.
  2. Utilisez le verrou distribué de Redis (Distributed Lock) pour vous assurer qu'un seul utilisateur peut effectuer des opérations de réduction d'inventaire à la fois. Avant que les utilisateurs ne se précipitent pour acheter des marchandises, procurez-vous un verrou distribué pour vous assurer qu'un seul utilisateur peut entrer dans la zone de code de clé, garantissant ainsi l'atomicité et la sécurité des threads des opérations d'inventaire.
  3. Utilisez des systèmes distribués ou des files d'attente dans le code métier pour contrôler les modifications d'inventaire. En plaçant les opérations de modification de l'inventaire physique dans un système distribué ou une file d'attente, il est garanti que chaque opération se déroule dans l'ordre et qu'une seule opération réussit.

Les solutions ci-dessus peuvent être sélectionnées et utilisées en combinaison selon des scénarios et des exigences spécifiques, afin de garantir que les problèmes de concurrence sont traités dans le scénario seckill.
Voici un exemple simple implémenté en PHP, qui montre comment utiliser la structure de hachage Redis pour gérer les problèmes de concurrence dans le scénario seckill.

<?php

// 假设秒杀商品的ID为1001,库存存储在"stock"键下
$productId = 1001;

// 连接Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 秒杀函数
function seckill($productId) {
    
    
    global $redis;

    // 获取商品库存
    $stock = $redis->hget('stock', $productId);

    if ($stock > 0) {
    
    
        // 有库存,执行秒杀逻辑
        $stock -= 1;

        // 更新库存
        $redis->hset('stock', $productId, $stock);

        // 执行生成订单等其他逻辑
        echo '成功抢购商品'.$productId.PHP_EOL;
    } else {
    
    
        // 库存已售罄
        echo '商品'.$productId.'已售罄'.PHP_EOL;
    }
}

// 并发模拟
$seckillNum = 5; // 模拟同时抢购人数
$pid = pcntl_fork();

if ($pid === -1) {
    
    
    echo 'Fork进程失败';
    exit(1);
} else if ($pid === 0) {
    
    
    // 子进程执行秒杀
    for ($i = 0; $i < $seckillNum; $i++) {
    
    
        seckill($productId);
    }
} else {
    
    
    // 父进程等待子进程执行完毕
    pcntl_wait($status);
}

// 关闭Redis连接
$redis->close();

?>

Dans l'exemple de code ci-dessus, nous nous connectons d'abord à Redis et définissons une fonction seckill pour traiter la logique métier seckill. Dans la fonction seckill, nous obtenons d'abord l'inventaire des marchandises, et si l'inventaire est supérieur à 0, effectuons l'opération seckill, c'est-à-dire réduisons l'inventaire de 1 et mettons à jour la valeur de l'inventaire dans Redis. Dans le même temps, d'autres opérations telles que la génération de commandes peuvent également être effectuées. Si le stock est épuisé, affichez le message d'invite correspondant.

Ensuite, nous utilisons la fonction pcntl_fork pour créer un processus enfant via la partie de simulation simultanée, et appelons la fonction seckill dans le processus enfant pour exécuter seckill. Vous pouvez modifier le paramètre $seckillNum selon vos besoins pour définir le nombre de personnes qui s'accrochent en même temps.

Enfin, le processus parent attend que le processus enfant se termine et ferme la connexion Redis.

Remarque : L'exemple ci-dessus est un code de démonstration simplifié, et plus de détails et de problèmes de sécurité doivent être pris en compte dans les applications réelles, telles que l'interface anti-brosse, les problèmes de survente, etc.

Je suppose que tu aimes

Origine blog.csdn.net/qq_27487739/article/details/131730146
conseillé
Classement