Maison > base de données > Redis > le corps du texte

Comment utiliser Redis pour créer une démo de support de vente flash

WBOY
Libérer: 2023-05-27 08:22:48
avant
1492 Les gens l'ont consulté

Utilisez Redis pour la déduction de l'inventaire des ventes flash, en limitant chaque compte à un seul snap-up. Cette démo simple utilise trois types de base : chaîne, hachage et liste

  • Utilisez des valeurs int de type chaîne pour stocker l'inventaire restant. , et Une fois le snap-up réussi, il sera réduit de 1

  • Utilisez le hachage pour stocker l'ID du membre "snap-up" (ce qui peut garantir l'unicité de l'ID utilisateur en tant que champ). : L'uid correspondant au champ de ce hachage n'est pas nécessairement un succès instantané

  • Utilisez la liste pour enregistrer la liste des identifiants de membre qui ont acheté avec succès, comme file d'attente pour le traitement ultérieur des commandes

Quand J'ai d'abord écrit, j'ai essayé d'utiliser une chaîne bitmap pour savoir si le membre a acheté avec succès, mais cela Il y aura des problèmes lorsque la concurrence est élevée, donc plus tard, il a été remplacé par un hachage de champ unique

2 fichiers :

  • init.php : inventaire initialisé, données statistiques, liste des membres retenus, etc.

  • buy php : rush payment

initialisation

ini.php:

$m_redis = new YourRedisClass(); //redis类很多, 可以自己写, 也可以用predis等
$m_redis->set('rush_stock', 20);//int, 可抢购的商品总数
$m_redis->set('rush_success', 0); //int, 成功的数量
$m_redis->set('rush_fail', 0); //int, 失败的数量
$m_redis->expire('rush_queue_h', 0); //hash, 已加入抢购队列的会员的hash记录表(field是唯一的, 可限制每个uid只有一次), 不一定抢购成功
$m_redis->set('rush_got_uid', ''); //string, 抢购成功的会员uid记录, 只是为了能简单的显示抢到的会员.
$m_redis->del('rush_got_uid_l'); //list, 抢购成功的会员uid(方便抢购后的订单批次处理)
echo 'success, '.date('Y-m-d H:i:s');
Copier après la connexion

Exécutez ce fichier pour initialiser la quantité.

redis-cli exécute "mget rush_stock rush_fail rush_success rush_got_uid" pour confirmer les données d'initialisation

instant kill

logique de jugement : , Que l'inventaire soit 0, l'inventaire & gt;


  • Si la déduction de l'inventaire est réussie (reste >= 0), le snap-up est réussi et la file d'attente de traitement des commandes (liste) est entrée
  • Actuellement, la chaîne int est utilisée pour stocker l'inventaire, et le nombre de les éléments de la liste peuvent également être utilisés pour compter, mais il est plus facile d'initialiser sans le type de chaîne
    1. buy.php
    //随机生成会员id
    $uid = rand(1,200);
    
    $m_redis = new YourRedisClass(); //redis类很多, 可以自己写, 也可以用predis等
    
    $key = 'rush_stock';
    $q = $m_redis->get($key);
    
    //1. 先判断库存数量
    //库存为0, 直接无法进入抢购队列
    if($q < 1){
        $m_redis->incr(&#39;rush_fail&#39;);//记录失败的数量
        die($uid.&#39;:OutOfStock&#39;);
    }
    
    //2. 判断该会员是否购买过 => 是否进入过队列
    $queued = $m_redis->hSet(&#39;rush_queue_h&#39;, $uid, $uid);//这里只能判断是否进入了抢购的队列. 如果库存为0则无法进入. 进入了队列后才能抢购
    if(!$queued){
        $m_redis->incr(&#39;rush_fail&#39;);//记录失败的数量
        die($uid.&#39;:queue failed&#39;);
    }
    
    //让cpu飞一会
    $n = rand(20000,100000);
    for($i=0; $i < $n; $i++){
        $a = rand(1,20000);
        $a = rand(1,30000);
        $a = rand(1,40000);
        $a = rand(1,50000);
        $a = rand(1,60000);
        $a = rand(1,70000);
        $a = rand(1,80000);
        $a = rand(1,90000);
    }
    
    
    //3. 扣减数量
    $q = $m_redis->decr($key, 1);//扣减数量后会返回结果值
    echo $q.&#39; left:&#39;;
    
    
    ////region 如果不判断操作后返回的结果,则可能会造成超发
    //$m_redis->incr(&#39;q_success&#39;);//记录成功的数量  ==>这个是有bug的, 不可取
    //die(&#39;:success&#39;);
    ////endregion
    
    if($q < 0){
        $m_redis->incr(&#39;rush_fail&#39;);//记录失败的数量
        die($uid.&#39;:decrease fail&#39;);
    }else{
        //记录成功的数量
        $m_redis->incr(&#39;rush_success&#39;);
        //记录该会员已购买
        $m_redis->append(&#39;rush_got_uid&#39;, $uid.&#39;,&#39;); //字符串追加
        $m_redis->rPush(&#39;rush_got_uid_l&#39;, $uid); //list
        die($uid.&#39;:success&#39;);
    }
    Copier après la connexion
  • L'uid de membre enregistré par le hachage dans le code ci-dessus est simplement l'uid de membre qui est enregistré. sont entrés dans la file d'attente d'achat. Cela ne signifie pas nécessairement que l'achat a réussi. Ceux qui ne sont simplement pas entrés dans la file d'attente d'achat précipitée ne seront pas dans ce hachage et seront directement rejetés car l'inventaire est de 0.


    AB stress test. : Faites simplement 500 requêtes simultanées et essayez un total de 2 000 fois (pendant le test, sous win10 600 Nginx simultanés raccroche)

    Apache路径bin>ab -n 2000 -c 500 http://xxx.com/buy.php
    Copier après la connexion
    Exécutez "mget rush_stock rush_fail rush_success rush_got_uid" sous redis-cli pour confirmer le résultat, et vérifiez le nombre de sur-problèmes possibles grâce à la valeur de rush_stock
    1. Exécutez "hvals rush_queue_h" pour vérifier le nombre de personnes entrant dans la file d'attente urgente ID utilisateur, ce nombre >= le nombre d'utilisateurs qui ont acheté avec succès

      Pour les opérations de données dans la liste file d'attente, vous pouvez utiliser la commande
    2. , qui peut réaliser la séquence de traitement des données FIFO.

    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!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal