>  기사  >  데이터 베이스  >  Redis를 사용하여 플래시 세일 지원 데모를 만드는 방법

Redis를 사용하여 플래시 세일 지원 데모를 만드는 방법

WBOY
WBOY앞으로
2023-05-27 08:22:481496검색

빠른 판매 재고 공제를 위해 Redis를 사용하여 각 계정을 하나의 스냅업으로 제한합니다. 이 간단한 데모는 문자열, 해시 및 목록의 세 가지 기본 유형을 사용합니다.

  • 남은 재고를 저장하려면 문자열 유형의 int 값을 사용하세요. , 스냅업이 성공하면 1

  • 해시를 사용하여 "스냅업" 구성원의 ID를 저장합니다(이를 통해 사용자 ID의 고유성을 필드로 보장할 수 있음). : 이 해시의 필드에 해당하는 uid가 반드시 스냅업 성공은 아닐 수도 있습니다

  • list를 사용하여 성공적으로 구매한 회원 ID 목록을 후속 주문 처리를 위한 대기열로 저장하세요

언제 처음에 글을 썼는데, 회원의 구매 성공 여부를 저장하기 위해 문자열 비트맵을 사용하려고 했으나 동시성이 높을 경우 문제가 발생하므로 나중에 고유 필드 해시로 대체했습니다

2개 파일:

  • init.php : 초기화 재고, 통계자료, 성공회원 목록 등

  • buy.php : 긴급구매

initialization

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');

수량을 초기화하려면 이 파일을 실행하세요.

redis-cli는 "mgetrush_stockrush_failrush_successrush_got_uid"를 실행하여 초기화 데이터를 확인합니다

instant kill

판단 논리: 인벤토리가 0인지 여부, 인벤토리 & gt;


  1. 재고 차감이 성공하면(remainder >= 0) 스냅업이 성공하고 주문 처리 대기열(목록)에 들어갑니다

    현재 문자열 int를 사용하여 재고를 저장하고 있으며, 목록의 항목을 사용하여 계산할 수도 있지만 초기화 중에 문자열 유형이 없으므로 더 쉽게 사용할 수 있습니다.

  • 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;);
    }
  • 위 코드에서 해시로 저장된 멤버 uid는 바로 멤버입니다. 구매 대기열에 들어간 uid가 반드시 구매에 성공했다는 의미는 아닙니다. 단순히 급하게 구매 대기열에 들어가지 않은 분들은 이 해시에 포함되지 않으며 재고가 0.
    1. AB이므로 바로 거부됩니다. 스트레스 테스트: 간단한 500개의 동시 요청을 만들고 총 2,000번 시도합니다(테스트 중 win10에서 600개의 동시 Nginx가 끊김)

      Apache路径bin>ab -n 2000 -c 500 http://xxx.com/buy.php

      redis-cli에서 "mgetrush_stockrush_failrush_successrush_got_uid"를 실행하여 결과를 확인하고 rush_stock 값을 통해 초과 발행 가능 개수 확인
    "hvalsrush_queue_h"를 실행하여 러시 큐에 진입한 인원수 확인 User id, 이 수치 >= 성공적으로 구매한 유저 수
  • 데이터 작업의 경우 목록 대기열에서 FIFO 데이터 처리 순서를 달성할 수 있는
    명령을 사용할 수 있습니다.

  • 위 내용은 Redis를 사용하여 플래시 세일 지원 데모를 만드는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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