我是靠谱客的博主 美好保温杯,这篇文章主要介绍redis实战-高并发抢购案例,现在分享给大家,希望可以做个参考。

先普及一下,什么叫超卖,订单商品数据量大于商品库存数量,就叫做超卖;

那么问题来了,为什么会超卖呢?

在商城抢购中,假如库存为100个,这时有100 000个并发请求过来了,最后库存只剩1个时,假如还有1000个并发请求,如果这1000个请求都成功了,那最后库存是不是变成了-999,这就是超卖。(以上仅为理论上理解超卖)

先介绍一个很有用的工具,并发测试工具ab.exe,在Apache的bin目录下打开cmd窗口,输入命令ab -n10000 -c1000 http://localhost/code/mysql.php,表示测试10000个请求,并发量为1000,测试访问地址为http://localhost/code/mysql.php

 

先建一个商品表,store为库存,以下为一些用到SQL语句

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 建表 create table product( id int(8) not null auto_increment comment '产品id', name varchar(25) not null default '' comment '产品名', price decimal(10,3) not null default 0 comment '价格', store int(8) not null default 0 comment '库存', primary key(id) )engine=innodb default charset=utf8; // 添加数据 insert into product value(1, '小米手环', 198, 10); // 查看表数据 select * from product; // 设置库存 update product set store=10 where id=1;

 

接下来,用代码解释下高并发抢购的超卖,直接在MySQL上测试,以下就是mysql.php文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php header("content-type:text/html; charset=utf-8"); // 连接数据库 $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'root') or die("数据库连接失败"); $pdo->exec("set names utf8"); $sql = "select * from product where id=1"; $res = $pdo->query($sql); $data = $res->fetch(PDO::FETCH_ASSOC); // print_r($data); if($data['store']>0){ // 开启事务 $pdo->beginTransaction(); $sql = "update product set store=store-1 where id=1"; $res = $pdo->query($sql); print_r($res); if($res){ echo "抢到啦!"; }else{ echo "抢购失败..."; $pdo->rollBack(); } $pdo->commit(); }else{ echo '商品已被抢购一空,感谢参与!'; } ?>

给它10000个请求,并发为1000

来看下商品表中的库存store

 

再来看下用redis实现的,用到了redis的事务、乐观锁,以下为redis.php

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?PHP header("content-type:text/html; charset=utf-8"); // 连接数据库 $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'root') or die("数据库连接失败"); $pdo->exec("set names utf8"); $redis = new Redis(); $redis->connect("localhost"); $redis->watch('salec'); // 虚拟销量 $salec = $redis->get('salec'); $store = 10; // 设置虚拟库存与数据库的一致 if($salec >= $store){ exit("商品已被抢购一空,感谢参与!"); } // 开启事务 $redis->multi(); $redis->incr('salec'); // 增加销量 $res = $redis->exec(); // 执行事务 如果发现自己拿到的key被修改了,事务则被打断 if($res){ // 以下代码只是为了测试,实际中是交给 MQ 去处理 // 连接数据库 $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', 'root') or die("数据库连接失败"); $pdo->exec("set names utf8"); $sql = "update product set store=store-1 where id=1"; if($pdo->query($sql)){ echo "抢到啦!"; } }else{ echo "抢购失败..."; } ?>

也给它10000个请求,并发为1000

看下商品表中的库存store

redis完美解决了高并发抢购的超卖现象。

 

最后

以上就是美好保温杯最近收集整理的关于redis实战-高并发抢购案例的全部内容,更多相关redis实战-高并发抢购案例内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部