Jadual Kandungan
回复内容:
Rumah pembangunan bahagian belakang tutorial php 使用redis秒杀出现产品超发现象求解?

使用redis秒杀出现产品超发现象求解?

Oct 17, 2016 am 09:30 AM
php redis

最近在做一个秒杀活动,处于性能和响应速度的考虑,使用了redis。写的时候就特别注意了杜绝超发现象,基于redis理论的cas(check and set)乐观锁,想着应该能够杜绝该问题,但是还是出现了,很疑惑求大神帮助,具体的代码大致如下:

<code><?php header("content-type:text/html;charset=utf-8");  
$redis = new redis();  
$result = $redis->connect('10.10.10.119', 6379);  
$mywatchkey = $redis->get("mywatchkey");  
$rob_total = 100;   //抢购数量  
if($mywatchkeywatch("mywatchkey");  
    $redis->multi();  
      
    //设置延迟,方便测试效果。  
    sleep(5);  
    //插入抢购数据  
    $redis->hSet("mywatchlist","user_id_".mt_rand(1, 9999),time());  
    $redis->set("mywatchkey",$mywatchkey+1);  
    $rob_result = $redis->exec();  
    if($rob_result){  
        $mywatchlist = $redis->hGetAll("mywatchlist");  
        echo "抢购成功!<br>";  
        echo "剩余数量:".($rob_total-$mywatchkey-1)."<br>";  
        echo "用户列表:<pre class="brush:php;toolbar:false">";  
        var_dump($mywatchlist);  
    }else{  
        echo "手气不好,再抢购!";exit;  
    }  
}  
?>  
Salin selepas log masuk
Salin selepas log masuk

回复内容:

最近在做一个秒杀活动,处于性能和响应速度的考虑,使用了redis。写的时候就特别注意了杜绝超发现象,基于redis理论的cas(check and set)乐观锁,想着应该能够杜绝该问题,但是还是出现了,很疑惑求大神帮助,具体的代码大致如下:

<code><?php header("content-type:text/html;charset=utf-8");  
$redis = new redis();  
$result = $redis->connect('10.10.10.119', 6379);  
$mywatchkey = $redis->get("mywatchkey");  
$rob_total = 100;   //抢购数量  
if($mywatchkeywatch("mywatchkey");  
    $redis->multi();  
      
    //设置延迟,方便测试效果。  
    sleep(5);  
    //插入抢购数据  
    $redis->hSet("mywatchlist","user_id_".mt_rand(1, 9999),time());  
    $redis->set("mywatchkey",$mywatchkey+1);  
    $rob_result = $redis->exec();  
    if($rob_result){  
        $mywatchlist = $redis->hGetAll("mywatchlist");  
        echo "抢购成功!<br>";  
        echo "剩余数量:".($rob_total-$mywatchkey-1)."<br>";  
        echo "用户列表:<pre class="brush:php;toolbar:false">";  
        var_dump($mywatchlist);  
    }else{  
        echo "手气不好,再抢购!";exit;  
    }  
}  
?>  
Salin selepas log masuk
Salin selepas log masuk

我觉得这个代码在高并发的情况,仍然会出现超卖现象。假如:只剩 1个奖品的时候,有三个人同时执行 $redis->watch("mywatchkey") 拿到的数据是 99 ,那么就出现超卖现象了。

由于redis是单线程读取,那么就用最简单的队列实现吧。

  1. 在抽奖前先把奖品数量,写入redis队列award:100 // 长度为100的 list ,值只是作为是否中奖

  2. 并发抽奖

<code>$award = $redis->lpop('award:100'); // 由于队列只有100个值,可以确保只有100个人中奖
if(!$award){
    echo "手气不好,再抢购!";exit;  
}

// 剩下就是中奖操作的事情了</code>
Salin selepas log masuk

sleep(5);
你公司还收不收人?

考虑一下这种情况。
mywatchkey=99
用户A请求mywatchkey得到99,
用户B请求mywatchkey得到99,
当A,B请求完成之后,mywatchkey应该为多少呢。。101,还是100?

你这个是经典的Check-then-Act错误

首先问一下你这个代码的“超卖”结果是$mywatchkey > 100了 (我认为不可能出现)
还是$mywatchkey =100时候同时有两个页面出现“抢购成功!“
我没有对这个代码进行测试,我只是猜测会不会是以下的情况:

1.Session A : 进行mywatchkey检查,此时mywatchkey = 99

2.Session B : 处理完 mywatchkey以后,此时mywatchkey=100 但是并不影响Session A的后续操作

补充两个连接,看看吧,或许有收获

transactions-and-watch-statement-in-redis
redis-watch-multi-exec-by-one-client

如果这事要从根本上解决,请先学习:

1.锁。

2.传统数据库事务。

然后再学习Redis与传统数据库的区别。

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 membawa beberapa ciri baharu, peningkatan keselamatan dan peningkatan prestasi dengan jumlah penamatan dan penyingkiran ciri yang sihat. Panduan ini menerangkan cara memasang PHP 8.4 atau naik taraf kepada PHP 8.4 pada Ubuntu, Debian, atau terbitan mereka

Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Dec 20, 2024 am 11:31 AM

Kod Visual Studio, juga dikenali sebagai Kod VS, ialah editor kod sumber percuma — atau persekitaran pembangunan bersepadu (IDE) — tersedia untuk semua sistem pengendalian utama. Dengan koleksi sambungan yang besar untuk banyak bahasa pengaturcaraan, Kod VS boleh menjadi c

Bagaimana anda menghuraikan dan memproses HTML/XML dalam PHP? Bagaimana anda menghuraikan dan memproses HTML/XML dalam PHP? Feb 07, 2025 am 11:57 AM

Tutorial ini menunjukkan cara memproses dokumen XML dengan cekap menggunakan PHP. XML (bahasa markup extensible) adalah bahasa markup berasaskan teks yang serba boleh yang direka untuk pembacaan manusia dan parsing mesin. Ia biasanya digunakan untuk penyimpanan data

Program PHP untuk mengira vokal dalam rentetan Program PHP untuk mengira vokal dalam rentetan Feb 07, 2025 pm 12:12 PM

Rentetan adalah urutan aksara, termasuk huruf, nombor, dan simbol. Tutorial ini akan mempelajari cara mengira bilangan vokal dalam rentetan yang diberikan dalam PHP menggunakan kaedah yang berbeza. Vokal dalam bahasa Inggeris adalah a, e, i, o, u, dan mereka boleh menjadi huruf besar atau huruf kecil. Apa itu vokal? Vokal adalah watak abjad yang mewakili sebutan tertentu. Terdapat lima vokal dalam bahasa Inggeris, termasuk huruf besar dan huruf kecil: a, e, i, o, u Contoh 1 Input: String = "TutorialSpoint" Output: 6 menjelaskan Vokal dalam rentetan "TutorialSpoint" adalah u, o, i, a, o, i. Terdapat 6 yuan sebanyak 6

7 Fungsi PHP Saya Menyesal Saya Tidak Tahu Sebelum ini 7 Fungsi PHP Saya Menyesal Saya Tidak Tahu Sebelum ini Nov 13, 2024 am 09:42 AM

Jika anda seorang pembangun PHP yang berpengalaman, anda mungkin merasakan bahawa anda telah berada di sana dan telah melakukannya. Anda telah membangunkan sejumlah besar aplikasi, menyahpenyahpepijat berjuta-juta baris kod dan mengubah suai sekumpulan skrip untuk mencapai op

10 Platform CMS PHP Terbaik Untuk Pembangun pada 2024 10 Platform CMS PHP Terbaik Untuk Pembangun pada 2024 Dec 05, 2024 am 10:29 AM

CMS bermaksud Sistem Pengurusan Kandungan. Ia adalah aplikasi perisian atau platform yang membolehkan pengguna mencipta, mengurus dan mengubah suai kandungan digital tanpa memerlukan pengetahuan teknikal lanjutan. CMS membolehkan pengguna membuat dan menyusun kandungan seperti teks, imej, video dan dokumen dengan mudah serta menerbitkannya di tapak web atau platform digital lain.

Cara menambah elemen hingga akhir array dalam php Cara menambah elemen hingga akhir array dalam php Feb 07, 2025 am 11:17 AM

Array adalah struktur data linear yang digunakan untuk memproses data dalam pengaturcaraan. Kadang -kadang apabila kita sedang memproses tatasusunan kita perlu menambah unsur -unsur baru ke array yang sedia ada. Dalam artikel ini, kami akan membincangkan beberapa cara untuk menambah unsur -unsur ke akhir array dalam PHP, dengan contoh kod, output, dan analisis kerumitan masa dan ruang untuk setiap kaedah. Berikut adalah cara yang berbeza untuk menambah elemen ke array: Gunakan kurungan persegi [] Dalam PHP, cara untuk menambah unsur -unsur ke akhir array adalah menggunakan kurungan persegi []. Sintaks ini hanya berfungsi dalam kes -kes di mana kita mahu menambah hanya satu elemen. Berikut adalah sintaks: $ array [] = nilai; Contoh

Dari negara mana pertukaran Nexo? Dari negara mana pertukaran Nexo? Mar 05, 2025 pm 05:09 PM

Nexo Exchange: Platform Pinjaman Cryptocurrency Swiss Analisis mendalam Nexo adalah platform yang menyediakan perkhidmatan pinjaman cryptocurrency, menyokong gadai janji dan pinjaman lebih daripada 40 aset crypto, mata wang fiat dan stablecoins. Ia menguasai pasaran Eropah dan Amerika dan komited untuk meningkatkan kecekapan, keselamatan dan pematuhan platform. Ramai pelabur ingin tahu di mana pertukaran Nexo didaftarkan, dan jawapannya ialah: Switzerland. Nexo ditubuhkan pada tahun 2018 oleh syarikat Swiss Fintech Credissimo. Nexo Exchange Lokasi dan Peraturan Geografi: Nexo beribu pejabat di Zug, Switzerland, rantau yang mesra cryptocurrency yang terkenal. Platform ini secara aktif bekerjasama dengan pengawasan pelbagai kerajaan dan telah berada di Rangkaian Penguatkuasaan Undang -undang Jenayah Kewangan AS (FINCEN) dan Kewangan Kanada

See all articles