Redis处理秒杀并发

 

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

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、将缓存失效时间分散开
 
 
 
 

posted @ 2022-10-21 13:21  美女爱找茬  阅读(296)  评论(0编辑  收藏  举报