Rumah  >  Artikel  >  pangkalan data  >  Cara menggunakan redis untuk membuat demo sokongan jualan kilat

Cara menggunakan redis untuk membuat demo sokongan jualan kilat

WBOY
WBOYke hadapan
2023-05-27 08:22:481498semak imbas

Gunakan redis untuk potongan inventori jualan kilat, mengehadkan setiap akaun kepada satu snap-up sahaja ini menggunakan tiga jenis asas: rentetan, cincang dan senarai

  • Gunakan rentetan Taip nilai int untuk menyimpan baki inventori dan kurangkan 1 selepas snap-up berjaya

  • Gunakan cincangan untuk menyimpan id ahli "snap-up" (anda boleh pastikan bahawa id pengguna adalah satu-satunya dalam sifat medan). Nota: Uid yang sepadan dengan medan cincang ini mungkin tidak semestinya pembelian yang berjaya

  • Gunakan senarai untuk menyimpan senarai ID ahli yang sebenarnya berjaya dibeli, sebagai baris gilir untuk pemprosesan pesanan seterusnya

Apabila saya mula-mula menulisnya, saya cuba menggunakan peta bit rentetan untuk menyimpan sama ada ahli itu mempunyai berjaya dibeli, tetapi ini akan menyebabkan masalah dalam keselarasan tinggi, jadi saya kemudian menukarnya kepada cincang medan unik

2 fail:

  • init.php: pemula inventori, data statistik, senarai ahli yang berjaya, dsb.

  • beli.php: Beli

Permulaan

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

Laksanakan fail ini dan mulakan kuantiti.

Laksanakan "mget rush_stock rush_fail rush_success rush_got_uid" di bawah redis-cli untuk mengesahkan data permulaan

Instaki

Logik penghakiman:


  1. Sama ada inventori ialah 0, jika inventori ialah >0, ia akan memasuki baris gilir membeli tergesa-gesa


    1. Data gilir pembelian tergesa-gesa (hash) ditulis dengan jayanya , dan inventori sedia untuk ditolak


    1. Jika potongan inventori berjaya (baki >=0), pembelian tergesa-gesa berjaya dan memasuki baris gilir pemprosesan pesanan (senarai)

      Pada masa ini, string int digunakan untuk menyimpan inventori dan item senarai juga boleh digunakan, tetapi tiada jenis rentetan semasa pemula. baris gilir mungkin tidak berjaya dalam pembelian tergesa-gesa mereka yang tidak memasuki baris gilir beli tergesa-gesa tidak akan berada dalam hash ini dan akan ditolak terus kerana inventori adalah 0.

      Ujian tekanan AB: Buat 500 permintaan serentak yang ringkas dan cuba sebanyak 2,000 permintaan (semasa ujian, Nginx menutup telefon selepas 600 permintaan serentak di bawah win10)
    2. //随机生成会员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;);
      }
    Laksanakan "mget rush_stock rush_fail rush_success rush_got_uid" di bawah redis redis . Semak bilangan kemungkinan lebihan terbitan melalui nilai rush_stock

    Laksanakan "hvals rush_queue_h" untuk menyemak ID pengguna yang memasuki baris gilir tergesa-gesa >= bilangan pengguna yang telah berjaya tergesa-gesa

    Untuk baris gilir senarai Untuk operasi data, anda boleh menggunakan perintah

    , yang boleh melaksanakan urutan pemprosesan data FIFO

    Atas ialah kandungan terperinci Cara menggunakan redis untuk membuat demo sokongan jualan kilat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam