redis解决商品秒杀问题

博主最近在项目中遇到了抢购问题!现在分享下。
抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:
1 高并发对数据库产生的压力
2 竞争状态下如何解决库存的正确减少("超卖"问题)
对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis。
重点在于第二个问题
常规写法:
查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数

优化方案1:将库存字段number字段设为unsigned,当库存为0时,因为字段不能为负数,将会返回false

优化方案2:使用MySQL的事务,锁住操作的行

优化方案3:使用非阻塞的文件排他锁

优化方案4:使用redis队列,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,推荐使用(mysql事务在高并发下性能下降很厉害,文件锁的方式也是)

抢购、描述逻辑

模拟5000高并发测试
webbench -c 5000 -t 60 http://192.168.1.198/big/index.php
ab -r -n 6000 -c 5000 http://192.168.1.198/big/index.php

上述只是简单模拟高并发下的抢购,真实场景要比这复杂很多,很多注意的地方
如抢购页面做成静态的,通过ajax调用接口
再如上面的会导致一个用户抢多个,思路:
需要一个排队队列和抢购结果队列及库存队列。高并发情况,先将用户进入排队队列,用一个线程循环处理从排队队列取出一个用户,判断用户是否已在抢购结果队列,如果在,则已抢购,否则未抢购,库存减1,写数据库,将用户入结果队列。

测试数据表

转自: https://www.cnblogs.com/aksir/p/6774102.html

原文地址:https://www.cnblogs.com/xifenglou/p/8478166.html

时间: 2024-10-04 04:03:44

redis解决商品秒杀问题的相关文章

SpringBoot+RabbitMQ+Redis实现商品秒杀

业务分析 一般而言,商品秒杀大概可以拆分成以下几步: 用户校验 校验是否多次抢单,保证每个商品每个用户只能秒杀一次 下单 订单信息进入消息队列,等待消费 减少库存 消费订单消息,减少商品库存,增加订单记录 付款 十五分钟内完成支付,修改支付状态 创建表 goods_info 商品库存表 列 说明 id 主键(uuid) goods_name 商品名称 goods_stock 商品库存 package com.jason.seckill.order.entity; /** * 商品库存 */ pu

利用redis进行商品秒杀

这里是用redis的list集合开发,redis的list集合是具有原子性的,不必担心多线程时会取到重复的数据,即使请求同时到达也会排队进行数据操作 1. 先说说大概思路,关于数据库库存字段的设计.数据类型设置为非负数的unsigned,  如果秒杀的商品数量为50个. 秒杀开始前在redis里面建一个类型为list,键名为goods_num_商品id 的键,存入50个元素.元素值可随意取. 2. 建一个键名为user_id_商品id 的键,每次用户秒杀成功,把用户id存入里面,用来判断是否成功

Redis案例——商品秒杀,购物车

秒杀案例: 1 <?php 2 header("content-type:text/html;charset=utf-8"); 3 $redis = new redis(); 4 $result = $redis->connect('10.10.10.119', 6379); 5 $mywatchkey = $redis->get("mywatchkey"); 6 $rob_total = 100; //抢购数量 7 if($mywatchkey&

PHP商品秒杀计时实现(解决大流量方案)

PHP商品秒杀功能我们多半以整点或时间点为例子,这样对于php来说处理不复杂,但有一个问题就是如果流量大要如何来处理,下面我们一起来看看解决办法. 要求要有小时分钟秒的实时倒计时的显示,用户端修改日期时间不会影响到倒计时的正常显示(也就是以服务器时间为准). 其实这和很多的考试等系统的时间限制功能同样的要求. 总不能用ajax每秒都获取服务器时间吧,所以实时倒计时一定要用javascript实现.这很简单,网上一大把的例子. 现在问题是解决用户端修改日期时间对我们的显示的影响. 解决的办法是计算

利用乐观锁及redis解决电商秒杀高并发基本逻辑

解决秒杀高并发问题方法很多,如悲观锁,消息队列等…… 利用乐观锁及redis解决秒杀高并发基本逻辑 //初始化redis $redis = new Redis(); // 设置键值,起到监视作用  执行事务之前,判断被修改,回滚 $redis->watch('sales'); // 获取销量 $sales = $redis->get('sales'); // 如果销量存在,先删除,false // $redis->del('sales'); // 库存,秒杀两件产品 $store = 2

用Redis轻松实现秒杀系统

秒杀系统的架构设计 秒杀系统,是典型的短时大量突发访问类问题.对这类问题,有三种优化性能的思路: 写入内存而不是写入硬盘 异步处理而不是同步处理 分布式处理 用上这三招,不论秒杀时负载多大,都能轻松应对.更好的是,Redis能够满足上述三点.因此,用Redis就能轻松实现秒杀系统. 用我这个方案,无论是电商平台特价秒杀,12306火车票秒杀,都不是事:) 下面介绍一下为什么上述三种性能优化思路能够解决秒杀系统的性能问题: 写入内存而不是写入硬盘 传统硬盘的读写性能是相当差的.SSD硬盘比传统硬盘

一篇文章教你如何用 Redis 轻松实现秒杀系统的构思

用 Redis 轻松实现秒杀系统的构思 前言: 秒杀系统的架构设计 秒杀系统,是典型的短时大量突发访问类问题.对这类问题,有三种优化性能的思路: **1. 写入内存而不是写入硬盘. 异步处理而不是同步处理. 分布式处理**用上这三招,不论秒杀时负载多大,都能轻松应对.更好的是,Redis能够满足上述三点.因此,用Redis就能轻松实现秒杀系统. 用我这个方案,无论是电商平台特价秒杀,12306火车票秒杀,都不是事:) 下面介绍一下为什么上述三种性能优化思路能够解决秒杀系统的性能问题: 写入内存而

zookeeper实现商品秒杀抢购

package com.test; import java.io.IOException; import java.util.List; import java.util.concurrent.CyclicBarrier; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.

Java秒杀系统实战系列~商品秒杀代码实战

摘要: 本篇博文是"Java秒杀系统实战系列文章"的第六篇,本篇博文我们将进入整个秒杀系统核心功能模块的代码开发,即"商品秒杀"功能模块的代码实战. 内容: "商品秒杀"功能模块是建立在"商品详情"功能模块的基础之上,对于这一功能模块而言,其主要的核心流程在于:前端发起抢购请求,该请求将携带着一些请求数据:待秒杀Id跟当前用户Id等数据:后端接口在接收到请求之后,将执行一系列的判断与秒杀处理逻辑,最终将处理结果返回给到前端.