Maison >base de données >Redis >Comment Redis résout-il les problèmes de simultanéité des stocks et parvient-il à contrôler les quantités ?

Comment Redis résout-il les problèmes de simultanéité des stocks et parvient-il à contrôler les quantités ?

PHPz
PHPzavant
2023-05-29 09:52:20964parcourir

Redis est un processus et un type de blocage uniques. Il ne peut traiter qu'une seule demande à la fois, et les demandes suivantes doivent être mises en file d'attente et attendues.

Avantages : Puisqu'il s'agit d'un processus unique, il n'est pas nécessaire de traiter les problèmes de concurrence, ce qui réduit la complexité du système.

Inconvénients : Ne convient pas à la mise en cache d'objets de grande taille (plus de 100 Ko)

Raison : Étant donné que Redis n'utilise qu'un Avec un seul cœur, Memcached peut utiliser plusieurs cœurs. Par conséquent, en moyenne, Redis sur chaque cœur a des performances plus élevées que Memcached lors du stockage de petites données.

Pour les données de plus de 100 000 données, les performances de Memcached sont supérieures à celles de Redis. Bien que Redis ait également été optimisé pour les performances de stockage du Big Data, il est encore légèrement inférieur à Memcached.

memcache est multi-processus et non bloquant S'il est utilisé uniquement comme cache, memcache est plus adapté

Comment Redis résout-il les problèmes de simultanéité des stocks et parvient-il à contrôler les quantités ?

1. La commande

existe pour vérifier si la clé clé existe déjà dans redis, par exemple. , existe mycounter

set Définir et initialiser une valeur clé telle que set mycounter 99

get Obtenir une valeur clé telle que getmycounter

incr Augmenter de 1 Par exemple, incrmycounter //Le résultat de sortie est 100

incrby Spécifier l'incrément value, telle que incrbymycounter 2 //Le résultat de sortie est 102

Spécifiez Réduire la valeur telle que incrbymycounter -2 //Le résultat de sortie est 100

setnx Lorsque la valeur n'existe pas, la valeur est définie avec succès. Par exemple, setnxmycounter 99 //Le résultat de sortie est 0, ce qui signifie que le paramètre a échoué et a été stocké dans redis

setnx key1 12 // Le résultat de sortie est 1, ce qui signifie que le paramètre a réussi Il n'existait pas auparavant dans redis.

expire Définit le cycle de vie d'une clé, par exemple expire mycounter 30 //Définit une période de validité de 30 secondes

ttl Obtenez le délai d'expiration de la clé, par exemple ttlmycounter //La sortie est 13, ce qui signifie qu'il reste encore 13 secondes . Si le retour est -1, cela signifie qu'il n'expirera jamais et existera toujours dans le cache Redis, sauf si la mémoire est insuffisante. //Si le retour est -2, cela signifie qu'il n'a pas expiré cette clé. valeur. Vous pouvez utiliser existe pour vérifier. Renvoyer 0 signifie qu'il n'y a pas de stock. 2. Scénarios courants

En raison de la précipitation pour acheter le produit, la quantité ne peut pas être contrôlée, ce qui entraîne un dépassement de la limite, ce qui entraîne des coûts insuffisants. . (Par exemple : l'inventaire est de 1 000, mais l'utilisateur a acheté avec succès 2 000 articles et l'inventaire est insuffisant.)

La loterie est limitée, si vous ne la contrôlez pas, vous dépenserez trop d'argent

Prenez des enveloppes rouges

3. Organigramme et code

Option 1 Organigramme :

Organigramme de l'option 2 :

Comment Redis résout-il les problèmes de simultanéité des stocks et parvient-il à contrôler les quantités ?

//方案1代码,测试坏境TP5
public function redisCountV1(){
    Log::record("测试版本1并发开始", Log::INFO);
    $redis = new Redis();
    //总库存数量
    $amountLimit = 100;
    //redis存储库存键名
    $keyName = "mycounter_v6";
    //假设每次消耗库存数为1
    $incrAmount = 1;
    //判断redis中是否 存在该值,如果不存在,则用set设置(问题是如果出现并发,两个或多个用户同时访问,会导致库存重新设置)
    if(!$redis->exists($keyName)){
        $redis->set($keyName, 95);
    }
    //从redis中取出当前库存数
    $currAmount = $redis->get($keyName);
    //如果当前库存数+增长的库存数>总库存,直接返回
    if($currAmount + $incrAmount > $amountLimit) {
        file_put_contents("/Users/han/Documents/www/cs/testv1.log", "bad luck \n", FILE_APPEND);
        Log::record("bad luck", Log::INFO);
        return false;
    }
    //缓存库存数量增加
    $redis->incrby($keyName, $incrAmount);
    file_put_contents("/Users/han/Documents/www/cs/testv1.log", "good luck \n", FILE_APPEND);
    Log::record("good luck", Log::INFO);
}

//测试方式:ab  -c 100 -n 200 http://www.fenleduo.com:8080/V7/Test/redisCountV1
//方案2代码,测试坏境TP5
public function redisCountV2(){
    Log::record("测试版本2并发开始", Log::INFO);
    $redis = new Redis();
    //总库存数量
    $amountLimit = 100;
    //redis存储库存键名
    $keyName = "mycounter_v12";
    //假设每次消耗库存数为1
    $incrAmount = 1;
    //判断redis中是否 存在该值,如果不存在,则用setnx设置(注:如果出现并发,两个或多个用户同时访问,不会导致库存重新设置)
    if(!$redis->exists($keyName)){
        //setnx 如果不存在该值,则设置,如果存在则不会设置
        $redis->setnx($keyName, 95);
    }
    //从redis中取出当前库存数
    $currAmount = $redis->get($keyName);
    //如果当前库存数+增长的库存数>总库存,直接返回
    if($redis->incrby($keyName, $incrAmount) > $amountLimit) {
        file_put_contents("/Users/han/Documents/www/cs/testv2.log", "bad luck \n",FILE_APPEND);
        Log::record("bad luck", Log::INFO);
        return false;
    }
    file_put_contents("/Users/han/Documents/www/cs/testv2.log", "good luck \n",FILE_APPEND);
    Log::record("good luck", Log::INFO);
}
//测试方式:ab  -c 100 -n 200 http://www.fenleduo.com:8080/V7/Test/redisCountV2

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