Redis学习笔记-秒杀活动中Redis的作用

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis学习笔记-秒杀活动中Redis的作用

1.笔记图

2.秒杀活动三阶段

  • 秒杀活动前
  • 用户会不断刷新商品详情页,这会导致详情页的瞬时请求量剧增
  • 把商品详情页的页面元素静态化,然后使用 CDN 或是浏览器把这些静态化的元素缓存起来
  • 秒杀活动开始
  • 大量用户点击商品详情页上的秒杀按钮,会产生大量的并发请求查询库存
  • 为了支撑大量高并发的库存查验请求,我们需要在这个环节使用 Redis 保存库存量
  • 订单处理可以在数据库中执行,但库存扣减不能交给数据库处理
  • 订单处理会涉及支付、商品出库、物流等多个关联操作,这些操作本身涉及数据库中的多张数据表,要保证处理的事务性,需要在数据库中完成
  • 需要直接在 Redis 中进行库存扣减,一旦库存有余量,我们就立即在 Redis 中扣减库存
  • 杀活动结束后
  • 可能还会有部分用户刷新商品详情页,尝试等待有其他用户退单
  • 已经成功下单的用户会刷新订单详情,跟踪订单的进展
  • 这个阶段中的用户请求量已经下降很多了,服务器端一般都能支撑

3.秒杀对Redis的两个要求

  • 支持高并发
  • Redis 本身高速处理请求的特性就可以支持高并发
  • 如有多个秒杀商品,可以使用切片集群,不同的实例保存不同商品的库存,避免所有的秒杀请求都集中在一个实例上
  • 保证库存查验和库存扣减原子性执行:使用 Redis 的原子操作或是分布式锁这两个功能特性

4.高并发下Redis如何库存信息的正确

  • 基于原子操作支撑秒杀场景
  • 对应两个信息,分别是总库存量和已秒杀量,可以使用一个 Hash 类型的键值对来保存库存的这两个信息
key: itemID
value: {total: N, ordered: M}

Tips:itemID 是商品的编号,total 是总库存量,ordered 是已秒杀量

  • 使用 Redis 的原子操作
  • 使用 Lua 脚本原子性地执行这两个操作
  • lua脚本内容
#获取商品库存信息            
local counts = redis.call("HMGET", KEYS[1], "total", "ordered");
#将总库存转换为数值
local total = tonumber(counts[1])
#将已被秒杀的库存转换为数值
local ordered = tonumber(counts[2])  
#如果当前请求的库存量加上已被秒杀的库存量仍然小于总库存量,就可以更新库存         
if ordered + k <= total then
#更新已秒杀的库存量
redis.call("HINCRBY",KEYS[1],"ordered",k)                              return k;  
end               
return 0
  • 基于分布式锁来支撑秒杀场景
  • 先让客户端向 Redis 申请分布式锁,只有拿到锁的客户端才能执行库存查验和库存扣减
  • 大量的秒杀请求会在争夺分布式锁时被过滤掉
  • 库存查验和扣减不需要使用原子操作,多个并发客户端只有一个客户端能够拿到锁,已经保证了客户端并发访问的互斥性
  • 伪代码
//使用商品ID作为key
key = itemID
//使用客户端唯一标识作为value
val = clientUniqueID
//申请分布式锁,Timeout是超时时间
lock =acquireLock(key, val, Timeout)
//当拿到锁后,才能进行库存查验和扣减
if(lock == True) {
//库存查验和扣减
availStock = DECR(key, k)
//库存已经扣减完了,释放锁,返回秒杀失败
if (availStock < 0) {
  releaseLock(key, val)
  return error
}
//库存扣减成功,释放锁
else{
 releaseLock(key, val)
 //订单处理
}
}
//没有拿到锁,直接返回
else
return

5.和高并发相关的处理

  • 前端静态页面的设计:秒杀页面上能静态化处理的页面元素,我们都要尽量静态化,这样可以充分利用 CDN 或浏览器缓存服务秒杀开始前的请求
  • 请求拦截和流控:在秒杀系统的接入层,对恶意请求进行拦截,避免对系统的恶意攻击,例如使用黑名单禁止恶意 IP 进行访问。如果 Redis 实例的访问压力过大,为了避免实例崩溃,我们也需要在接入层进行限流,控制进入秒杀系统的请求数量
  • 库存信息过期时间处理Redis 中保存的库存信息其实是数据库的缓存,为了避免缓存击穿问题,我们不要给库存信息设置过期时间
  • 数据库订单异常处理:如果数据库没能成功处理订单,可以增加订单重试功能,保证订单最终能被成功处理

Tips:小建议:秒杀活动带来的请求流量巨大,我们需要把秒杀商品的库存信息用单独的实例保存,而不要和日常业务系统的数据保存在同一个实例上,这样可以避免干扰业务系统的正常运行

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
10月前
|
NoSQL Java Redis
redis-学习笔记(Jedis 通用命令)
redis-学习笔记(Jedis 通用命令)
65 1
|
6月前
|
存储 JSON NoSQL
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
这篇文章是关于Redis基本数据结构的学习笔记,包括了String、Hash、Set、List和SortedSet的介绍和常用命令。文章解释了每种数据结构的特点和使用场景,并通过命令示例演示了如何在Redis中操作这些数据结构。此外,还提供了一些练习示例,帮助读者更好地理解和应用这些数据结构。
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
|
10月前
|
Java Redis
redis-学习笔记(Jedis zset 简单命令)
redis-学习笔记(Jedis zset 简单命令)
121 3
|
10月前
|
NoSQL 网络协议 关系型数据库
redis-学习笔记(redis 单线程模型)
redis-学习笔记(redis 单线程模型)
81 3
|
10月前
|
Java Redis
redis-学习笔记(Jedis string 简单命令)
redis-学习笔记(Jedis string 简单命令)
58 2
|
10月前
|
Java Redis
redis-学习笔记(Jedis hash简单命令)
redis-学习笔记(Jedis hash简单命令)
54 1
|
10月前
|
存储 Java Redis
redis-学习笔记(Jedis set 简单命令)
redis-学习笔记(Jedis set 简单命令)
93 1
|
10月前
|
Java Redis
redis-学习笔记(Jedis list简单命令)
redis-学习笔记(Jedis list简单命令)
72 1
|
10月前
|
NoSQL Java Redis
redis-学习笔记(Jedis 前置知识)
redis-学习笔记(Jedis 前置知识)
84 1
|
10月前
|
NoSQL Java Redis
redis-学习笔记(string , hash , list , set , zset 前置知识)
redis-学习笔记(string , hash , list , set , zset 前置知识)
59 0
redis-学习笔记(string , hash , list , set , zset 前置知识)

热门文章

最新文章