91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用redis做秒殺支撐的demo

發布時間:2022-03-25 10:17:53 來源:億速云 閱讀:140 作者:iii 欄目:大數據

本篇內容介紹了“怎么用redis做秒殺支撐的demo”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

用redis做秒殺的庫存扣除, 限制每個賬號只能搶購一次, 這個簡單的demo使用了string, hash, list三種基本類型.

  • 用string類型的int值來存儲剩余庫存, 并在搶購成功后減1

  • 用hash來存儲"已搶購到"的會員的id(可以確保用戶id作為field的唯一性). 注意: 這個hash的field對應的uid不一定搶購成功

  • 用list來保存真正搶購成功的會員id的列表, 作為后續處理訂單的隊列

第一次寫的時候, 嘗試過使用string的bitmap來保存該會員是否搶購成功過, 但是這個在高并發時會出問題, 所以后來換成了唯一field的hash

2個文件:

  • init.php: 初始化庫存, 統計數據, 搶購成功的會員列表等

  • buy.php: 搶購

初始化

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 下執行 "mget rush_stock rush_fail rush_success rush_got_uid" 確認初始化數據

秒殺

判斷的邏輯:


    1. 庫存是否為0, 庫存>0則進入搶購隊列


    1. 搶購隊列數據(hash)寫入成功, 則準備扣減庫存


    1. 庫存扣減成功(余數>=0)則搶購成功, 進入訂單處理隊列(list)
      目前是用string int存儲庫存, 也可以用list的item的個數來計數, 但是初始化時沒有string類型來得簡單.

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('rush_fail');//記錄失敗的數量
    die($uid.':OutOfStock');
}

//2. 判斷該會員是否購買過 => 是否進入過隊列
$queued = $m_redis->hSet('rush_queue_h', $uid, $uid);//這里只能判斷是否進入了搶購的隊列. 如果庫存為0則無法進入. 進入了隊列后才能搶購
if(!$queued){
    $m_redis->incr('rush_fail');//記錄失敗的數量
    die($uid.':queue failed');
}

//讓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.' left:';


////region 如果不判斷操作后返回的結果,則可能會造成超發
//$m_redis->incr('q_success');//記錄成功的數量  ==>這個是有bug的, 不可取
//die(':success');
////endregion

if($q < 0){
    $m_redis->incr('rush_fail');//記錄失敗的數量
    die($uid.':decrease fail');
}else{
    //記錄成功的數量
    $m_redis->incr('rush_success');
    //記錄該會員已購買
    $m_redis->append('rush_got_uid', $uid.','); //字符串追加
    $m_redis->rPush('rush_got_uid_l', $uid); //list
    die($uid.':success');
}

上面的代碼中的hash保存的會員uid, 只是進入搶購隊列的會員uid, 不一定搶購成功了, 那些根本沒有進入搶購隊列的, 也不會在這個hash中, 直接因為庫存為0而被拒絕了.

AB壓力測試:  做一個簡單的500個并發并總計嘗試2000次的請求(測試時, win10下600個并發Nginx就掛機了)

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

redis-cli下執行 "mget rush_stock rush_fail rush_success rush_got_uid" 確認結果, 通過 rush_stock 的值查看可能的超發的數量

執行 "hvals rush_queue_h"可查看進入搶購隊列的用戶id, 這個數量 >= 搶購成功的用戶數量

對于list隊列的數據操作, 可以使用 BLPOP 命令, 這樣可以實現FIFO的數據處理順序.

“怎么用redis做秒殺支撐的demo”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

赤峰市| 简阳市| 江油市| 嘉善县| 公安县| 咸宁市| 延吉市| 长泰县| 晋城| 定西市| 应城市| 肃宁县| 肇庆市| 休宁县| 仁怀市| 黎城县| 九龙县| 沾益县| 五大连池市| 明光市| 巴彦县| 肥西县| 三门峡市| 临高县| 怀柔区| 灯塔市| 故城县| 台北县| 鄂温| 兴海县| 独山县| 荔波县| 新昌县| 沙田区| 荣昌县| 赣榆县| 辛集市| 武陟县| 定州市| 洛宁县| 宜良县|