亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

redis隊(duì)列和秒殺應(yīng)用方式

 更新時(shí)間:2025年04月22日 09:41:23   作者:程序猿John  
這篇文章主要介紹了redis隊(duì)列和秒殺應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1.簡(jiǎn)述

redis隊(duì)列一般用于緩解數(shù)據(jù)庫(kù)壓力 ,諸如秒殺,郵件群發(fā),消息推送等等

redis的加入能很好的 幫助系統(tǒng)中 各個(gè)模塊解耦。

而Redis不僅可作為緩存服務(wù)器,還可用作消息隊(duì)列。它的列表類型天生支持用作消息隊(duì)列。如下圖所示:

對(duì)于服務(wù)器減少io 壓力 有一定的幫助

2.秒殺的原理

秒殺基本原理比較簡(jiǎn)單

用戶點(diǎn)擊搶購(gòu)按鈕 -> 把uid 和時(shí)間存入redis的隊(duì)列中 -> 服務(wù)器中有一個(gè)入庫(kù)程序不停輪詢r(jià)edis隊(duì)列是否有數(shù)據(jù) -> 如果有存入數(shù)據(jù)庫(kù)

這里面有2點(diǎn)需要注意一下:

  • 1. 插入隊(duì)列的時(shí)候 ,需要判斷庫(kù)傳,不能出現(xiàn)多插入
  • 2. 在入庫(kù)的時(shí)候 如果出現(xiàn)數(shù)據(jù)插入失敗的情況 需要進(jìn)行回滾

3.秒殺的代碼實(shí)現(xiàn)

用戶操作秒殺:

header("Content-type: text/html; charset=utf-8");
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$redis_name= "miaosha";
//庫(kù)存
$nums = 10;
//用戶id
$user_id = $_GET['uid'];
if(($redis->llen($redis_name)) <  $nums ){
	$redis->lpush($redis_name,json_encode(array('uid'=>$user_id,'time'=>microtime())));
	echo $user_id."秒殺成功!";
	exit();
}else{
	echo "秒殺失敗!";
	exit();
}
$redis->close();

后臺(tái)處理秒殺隊(duì)列:

header("Content-type: text/html; charset=utf-8");
error_reporting(E_ALL);
require_once './db.php';
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$redis_name = "miaosha";

//數(shù)據(jù)庫(kù)
$configs =array('host'=>'127.0.0.1','port'=>'3306','user'=>'***','passwd'=>'','dbname'=>'test');
$mysql = new MMysql($configs);

//處理開始
while ($count = $redis->lLen($redis_name)) {
    $task = $redis->rpop($redis_name);
	
    $taskdata = json_decode($task, true);
	$data = array(
    	'uid'=>$taskdata['uid'],
    	'time'=>$taskdata['time'],
    );

	$rs = $mysql->insert('redis',$data);
	if(!$rs){
		//由于我們是在右邊取,所以如果數(shù)據(jù)插入失敗了要從左邊放回去(重新排隊(duì)),以免影響隊(duì)列中其他元素的處理
		$redis->lpush($redis_name,$task);
		echo "處理失敗<br>";
	}else{
		echo "處理成功<br>";
	}
    
	sleep(1);
}

$redis->close();

4.關(guān)于redis里的鎖

4.1 先說(shuō)一下樂(lè)觀鎖

樂(lè)觀鎖,顧名思義,樂(lè)觀的認(rèn)為數(shù)據(jù)不會(huì)被修改,只有當(dāng)更新時(shí)才去判斷數(shù)據(jù)是否被修改過(guò),通常用版本號(hào)或時(shí)間戳來(lái)實(shí)現(xiàn)。

redis中的事務(wù)通過(guò)watch和multi來(lái)實(shí)現(xiàn)。

WATCH命令可以監(jiān)控一個(gè)或多個(gè)鍵,一旦其中有一個(gè)鍵被修改(或刪除),之后的事務(wù)就不會(huì)執(zhí)行。監(jiān)控一直持續(xù)到EXEC命令(事務(wù)中的命令是在EXEC之后才執(zhí)行的,所以在MULTI命令后可以修改WATCH監(jiān)控的鍵值)

$redis = new Redis();
$redis->connect('127.0.0.1', 6379, 60);
 
 //
$tnums = $redis->get('goods_stock_nums');

//設(shè)置商品的庫(kù)存
if($tnums==0){
	echo "活動(dòng)已經(jīng)結(jié)束,明天請(qǐng)?jiān)鏴nd!";
	exit();
}

//監(jiān)視該key
$redis->watch('goods_stock_nums');

//sleep(5);
//開啟事務(wù)
$redis->multi();
 
//修改庫(kù)存數(shù)
$redis->decr('goods_stock_nums');
 
//提交事務(wù),如果在此期間有其他請(qǐng)求修改了該key,那么事務(wù)會(huì)失敗
if ($redis->exec()) {
    echo '搶購(gòu)成功suc';
} else {
    echo '數(shù)據(jù)錯(cuò)誤,請(qǐng)重新再試fail';
}

可以看到我在程序中加入了sleep(5) 這行代碼。

這是方便我在客戶端去實(shí)驗(yàn)

如果我在運(yùn)行上面這段代碼過(guò)程中,我用客戶端修改了這個(gè)值。

那么上面這段代碼就會(huì)失敗,返回 數(shù)據(jù)錯(cuò)誤,請(qǐng)重新再試fail

4.2 再說(shuō)一下 悲觀鎖

function getRedis()
{
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379, 60);
    return $redis;
}
 
function lock($key, $random)
{
    $redis = getRedis();
    return $redis->set($key, $random, ['nx', 'ex' => 3]);
}
 
function unlock($key, $random)
{
    $redis = getRedis();
    //使用lua腳本保證原子性
    $script = 'if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end';
    return $redis->eval($script, [$key, $random], 1);
}
 
function decrGoodsStockNums()
{
    $redis = getRedis();
 
    //獲取商品庫(kù)存數(shù)
    $ret = $redis->get('goods_stock_nums');
 
    if ($ret === false) {
        return false;
    }
 
    if ($ret <= 0) {
        return false;
    }
 
    $random = mt_rand();
    //先獲取鎖
    if (lock('goods_stock_nums_lock', $random)) {
        //修改庫(kù)存數(shù)
        $redis->decr('goods_stock_nums');
 
        //釋放鎖
        unlock('goods_stock_nums_lock', $random);
        return true;
    } else {
        usleep(100);
        decrGoodsStockNums();
    }
}
 
decrGoodsStockNums();

上面這段引用別人的代碼

但是這種鎖的機(jī)制還是不能保證事務(wù)的安全

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Redis全量復(fù)制與部分復(fù)制示例詳解

    Redis全量復(fù)制與部分復(fù)制示例詳解

    這篇文章主要給大家介紹了關(guān)于Redis全量復(fù)制與部分復(fù)制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis爬蟲具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Redis數(shù)據(jù)一致性詳解

    Redis數(shù)據(jù)一致性詳解

    文章主要討論了分布式系統(tǒng)中的數(shù)據(jù)一致性模型、緩存使用場(chǎng)景以及數(shù)據(jù)同步策略,一致性模型包括強(qiáng)一致性、弱一致性和最終一致性,緩存使用場(chǎng)景主要在高并發(fā)讀取數(shù)據(jù)時(shí)提升性能,數(shù)據(jù)同步策略分為先刪除緩存再更新數(shù)據(jù)庫(kù)和先更新數(shù)據(jù)庫(kù)再刪除緩存兩種
    2024-11-11
  • redis監(jiān)聽key過(guò)期事件的詳細(xì)步驟

    redis監(jiān)聽key過(guò)期事件的詳細(xì)步驟

    本文主要介紹了redis監(jiān)聽key過(guò)期事件的詳細(xì)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • redis中RDB(Redis Data Base)的機(jī)制

    redis中RDB(Redis Data Base)的機(jī)制

    本文主要介紹了redis中RDB(Redis Data Base)的機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • redis的hash類型操作方法

    redis的hash類型操作方法

    Hash 是一個(gè) String 類型的 field(字段) 和 value(值) 的映射表,hash 特別適合用于存儲(chǔ)對(duì)象,這篇文章主要介紹了redis的hash類型的詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Redis五種數(shù)據(jù)類型詳解

    Redis五種數(shù)據(jù)類型詳解

    Redis是基于內(nèi)存的 K-V 數(shù)據(jù)庫(kù),常用于緩存、消息隊(duì)列,分布式鎖等場(chǎng)景,并且提供了常見的數(shù)據(jù)結(jié)構(gòu):字符串、哈希、列表、集合、帶排序的集合,本文主要介紹了Redis的五種數(shù)據(jù)類型,感興趣的小伙伴可以參考閱讀本文
    2023-04-04
  • redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼

    redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼

    相信大家都知道可重入鎖的作用防止在同一線程中多次獲取鎖而導(dǎo)致死鎖發(fā)生,本文通過(guò)幾個(gè)例子給大家分享redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼,對(duì)redis分布式鎖的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-05-05
  • Redis分片集群的實(shí)現(xiàn)

    Redis分片集群的實(shí)現(xiàn)

    Redis 分片集群是一種將 Redis數(shù)據(jù)庫(kù)分散到多個(gè)節(jié)點(diǎn)上的方式,以提供更高的性能和可伸縮性,本文主要介紹了Redis分片集群的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • Redis大key和多key拆分的解決方案

    Redis大key和多key拆分的解決方案

    大key會(huì)導(dǎo)致內(nèi)存使用過(guò)高,多key可能導(dǎo)致查詢效率低下,本文主要介紹了Redis大key和多key拆分的解決方案,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Redis fork進(jìn)程分配不到內(nèi)存解決方案

    Redis fork進(jìn)程分配不到內(nèi)存解決方案

    這篇文章主要介紹了Redis fork進(jìn)程分配不到內(nèi)存解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11

最新評(píng)論