Rumah >pangkalan data >Redis >Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi
Untuk sesetengah tapak web e-dagang dengan bilangan pengguna tertentu, jika mereka hanya menggunakan pangkalan data hubungan (seperti MySQL, Oracle) untuk pembelian tergesa-gesa, tekanan pada pangkalan data akan menjadi sangat hebat, dan jika mekanisme kunci pangkalan data adalah tidak digunakan dengan betul, , ia juga akan membawa kepada masalah produk dan kupon terlebih jual. Syarikat saya juga menghadapi masalah yang sama Masalahnya berlaku apabila kupon terlalu dibeli Selepas masalah berlaku, kami mula memikirkan cara untuk menyelesaikan masalah ini. Oleh kerana saya banyak menggunakan redis . Gunakan ciri prestasi tinggi dan transaksi redis untuk menyelesaikan masalah kupon dalam talian yang diambil oleh stok berlebihan Di bawah saya memberikan versi pertama kod pseudo yang saya selesaikan sementara masalah ini, dengan beberapa butiran dialih keluar:
/** * 抢优惠券(秒杀) * @param int $couponId 商品ID * @param int $uid 用户ID * @return bool */ function secKill($couponId, $uid) { //1.初始化Redis连接 $redis = new Redis(); if (!$redis->connect('127.0.0.1', 6379)) { trigger_error('Redis连接出错!!!', E_USER_ERROR); } else { echo '连接正常<br>'; } //秒杀商品的库存key $key = 'secKill:'.$couponId.':stock'; $redis->watch($key); //获取库存 $stock = $redis->get($key); //秒杀未开始,表示库存为null if (!$stock && !is_numeric($stock)) { echo '秒杀未开始'; return false; } //判断库存,如果库存大于0,则减库存,将该成功秒杀用户加入哈希表,如果小于等于0,秒杀结束 if ($stock <= 0) { echo '秒杀已结束'; return false; } //用户已经成功秒杀过一次了,不允许再次参与秒杀 if ($redis->sIsMember('secKill:'.$couponId.':uid', $uid)) { echo '秒杀失败'; return false; } //代码走到这里,说明该用户是第一次参与秒杀,将库存减一,然后把这个人放到已抢到的集合表 $redisMulti = $redis->multi(); $redisMulti->decr($key); $redisMulti->sAdd('secKill:'.$couponId.':uid', $uid); $result = $redisMulti->exec(); if (empty($result)) {//事务被取消 echo '秒杀失败'; return false; } //抢券成功,将优惠券ID和UID放入到队列中,由一个单独的进程队列来消费队列里的数据,向用户推送抢到的优惠券 $redis->lPush('couponOrder', $couponId.'+'.$uid); return true; } $couponId = 11211; $uid = mt_rand(1, 100); secKill($couponId, $uid);
Mula-mula, saya mensimulasikan menetapkan inventori kupon dengan ID kupon 11211 hingga 10.
Kemudian, kami menggunakan alat ab untuk mensimulasikan 1000 permintaan dan 50 konkurensi untuk menguji
ab -n 1000 -c 50 www.test.com/
Kemudian kami menggunakan Redis Desktop Manager untuk melihat beberapa Redis Result
Sudah ada 10 maklumat pengguna dalam baris gilir kuponOrder
Dan baki bilangan kupon juga ialah 0, bukan lagi nombor negatif
Pada masa yang sama, maklumat UID 10 pengguna juga disimpan dalam koleksi kupon pengguna.
Rentetan kod di atas menyelesaikan dua masalah:
Ia menyelesaikan masalah sejumlah besar pertanyaan segera kepada pangkalan data menyebabkan banyak kerosakan pada pangkalan data. Masalah tekanan tinggi, trafik dipintas dalam lapisan cache redis
Menyelesaikan masalah kupon yang diambil oleh stok berlebihan
Walau bagaimanapun, Kod ini juga mempunyai masalah tertentu:
Kolam sambungan redis tidak digunakan dan penciptaan redis baharu yang kerap mempunyai kesan prestasi tertentu
Atas ialah kandungan terperinci Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!