一、现公司解决秒杀方案:

1. 利用Redis原子性自增接口incr

2. Redis缓存 + 异步同步数据到数据库

优点:解决超卖问题,库存读写都在内存中,故同时解决性能问题。

缺点:由于异步写入DB,可能存在数据不一致。另可能存在少买,也就是如果拿到号的人不真正下订单,可能库存减为0,但是订单数并没有达到库存阀值。

 

二、秒杀过程:

Uid 和 prodid 非空判断

连接redis

 拼接key

  • 库存key
  • 秒杀成功用户key

获取库存,如果库存null,秒杀还没有开始

判断用户是否重复秒杀操作:使用set集合数据结构存储

判断如果商品数量,库存数量小于1,秒杀结束

秒杀过程

  • 库存-1:  redis.decr(key)
  • 把秒杀成功用户添加清单里面: redis.sadd(userkey,uid)

 

三、Redis事务:秒杀并发

 

(一)使用工具:ab测试

  • CentOS 6默认安装
  • CentOS 7 需要手动安装

 

(二)安装

  •  联网: yum install httpd-tools
  • 无网络:

(1) 进入cd  /run/media/root/CentOS 7 x86_64/Packages(路径跟centos6不同)

(2) 顺序安装

apr-1.4.8-3.el7.x86_64.rpm
apr-util-1.5.2-6.el7.x86_64.rpm
httpd-tools-2.4.6-67.el7.centos.x86_64.rpm

 

(三)测试命令

vim postfile 模拟表单提交参数,以&符号结尾;存放当前目录。

内容:prodid=0101&

ab -n 2000 -c 200 -k -p ~/postfile -T application/x-www-form-urlencoded http://127.0.0.1:8081/Seckill/doseckill

 

 

(四)最常遇见的问题:

1. 超卖问题 : 

解决方案:通过乐观锁解决,缺点:存在库存遗留库存及连接超时 

2. 连接超时: connect-timeout

解决方案:连接池 

3. 连接限制:connection-refused

解决方案:ab测试增加-r参数:

ab -n 2000 -c 100 -r -p postfile -T 'application/x-www-form-urlencoded' http://127.0.0.1:8080/seckill/doseckill

4. 库存遗留问题:已经秒光,可是还有库存

乐观锁造成的问题,先点的没秒到,后点的可能秒到了

解决方案: LUA脚本,通过lua脚本解决争抢问题,实际上是redis 利用其单线程的特性,用任务队列的方式解决多任务并发问题

 

(五)常见秒杀解决方案:

1、前端方案:

  A:扩容

  加机器,这是最简单的方法,通过增加前端池的整体承载量来抗峰值。

  B:静态化

  将活动页面上的所有可以静态的元素全部静态化,并尽量减少动态元素。通过CDN来抗峰值。

  C:限流

  一般都会采用IP级别的限流,即针对某一个IP,限制单位时间内发起请求数量。

  或者活动入口的时候增加游戏或者问题环节进行消峰操作。

  D:禁止重复提交:用户提交之后按钮置灰,禁止重复提交

   F:有损服务

  最后一招,在接近前端池承载能力的水位上限的时候,随机拒绝部分请求来保护活动整体的可用性。

 

2、后端方案:

缓存 + 队列

Redis是一个分布式缓存系统,支持多种数据结构,我们可以利用Redis轻松实现一个强大的秒杀系统。

利用redis记录读取实时库存。一旦库存不足,立即抛出异常。反馈给前端。如果库存足够,通过rpc调用通知订单微服务系统生成订单。得到订单系统的生成成功的反馈以后,在秒杀微服务系统中生成一个本地订单记录,在数据库增销量减库存。

Redis 提供了 INCR/DECR/SETNX 命令,把RMW三个操作转变为一个原子操作

Redis 是使用单线程串行处理客户端的请求来操作命令,所以当 Redis 执行某个命令操作时,其他命令是无法执行的,这相当于命令操作是互斥执行的

 

 

 

四、Redis可能存在的问题:

 

缓存穿透: 

1、应用服务器压力变大了

2、redis命中率降低

3、一直查询数据库

 

  • 缓存穿透现象:

1、redis查询不到数据

2、出现很多非正常url访问

 

  • 缓存穿透解决方案:

1、对空值缓存(临时方案)

2、设置可访问的名单(白名单):bitmap位操作,缺点:效率不是很高

3、采用布隆过滤器,缺点:命中率不是很准备

4、进行实时监控

 

缓存击穿:

1、数据库访问压力瞬时增加

2、redis里面没有出现大量key过期

3、redis正常运行

 

  • 缓存击穿现象;

1、redis某个key过期了,大量访问使用这个key

 

  • 缓存击穿解决方案:

1、预先设置热门数据

2、实时调整

3、使用锁  缺点:降低效率

 

缓存雪崩:

1、数据库压力变大,服务器崩溃

2、在极少时间段,查询大量的key的集中过期情况

 

  • 缓存雪崩解决方案:

1、构建多级缓存架构 ; Nginx + redis + 其它缓存(ehcache)

2、使用锁和队列

3、设置过期标志更新缓存

4、将缓存失效时间分散开

 

 

 

 

三十六般武艺,七十二般变化,修练出个人品牌并发出光芒