记录每次学习的过程,总结学习的内容,希望能给到自己和别人帮助。

Redis学习之秒杀案例

基础设计思路
1.uid和prodid的非空判断
2.连接redis
3.拼接key,包括库存的和成功秒杀的用户的
4.获取库存,如果库存null,表示秒杀还没开始
5.判断用户是否重复秒杀操作(使用set集合 中的sismember)
6.判断如果商品数量,库存数量小于1,秒杀结束
7.每当有一次秒杀成功,库存-1,并且把秒杀成功用户添加到清单里面
基础代码如下:

public class doSecKill {//秒杀实例public static boolean doSecKill(String uid, String prodid) throws IOException {//1.uid和prodid的非空判断if (uid == null || prodid == null) {return false;}//2.连接reidsJedis jedis = new Jedis("192.168.92.131", 6379);//3.拼接key//3.1库存keyString kcKey = "sk:" + prodid + ":qt";//3.2秒杀成功用户keyString userKey = "sk:" + prodid + ":user";//4.获取库存,如果库存null,表示秒杀还没开始String kc = jedis.get(kcKey);if (kc == null) {System.out.println("秒杀还没有开始,请等待");jedis.close();return false;}//5.判断用户是否重复秒杀操作(使用set集合 中的sismember)Boolean sismember = jedis.sismember(userKey, uid);if (sismember) {System.out.println("已经秒杀成功了,不能重复秒杀");jedis.close();return false;}//6.判断如果商品数量,库存数量小于1,秒杀结束if (Integer.parseInt(kc) <= 0) {System.out.println("秒杀已经结束了");jedis.close();return false;}//7.秒杀过程//7.1库存-1jedis.decr(kcKey);//7.2把秒杀成功用户添加到清单里面jedis.sadd(userKey, uid);System.out.println("秒杀成功");jedis.close();return true;}
}

秒杀中会遇到的问题

问题1:连接超时的问题
----解决方法:通过连接池处理超时的问题
问题2:超卖的问题
----解决方法:通过乐观锁的方式,使用事务

问题1:连接超时的问题
----解决方法:通过连接池处理超时的问题

配置一个JedisPoolUtil

public class JedisPoolUtil {private static volatile JedisPool jedisPool = null;private JedisPoolUtil() {}public static JedisPool getJedisPoolInstance() {if (null == jedisPool) {synchronized (JedisPoolUtil.class) {if (null == jedisPool) {//配置池JedisPoolConfig poolConfig = new JedisPoolConfig();//最大链接数poolConfig.setMaxTotal(1000);//最大空闲poolConfig.setMaxIdle(32);//最大等待时间poolConfig.setMaxWaitMillis(100 * 1000);//测试连接poolConfig.setTestOnBorrow(true);//jedis连接池的配置jedisPool = new JedisPool(poolConfig, "192.168.92.131", 6379,60000);}}}return jedisPool;}//关闭链接池,释放对象public static void release(JedisPool jedisPool, Jedis jedis) {if (null != jedis) {jedisPool.returnResource(jedis);}}
}

将上面基础的代码改造:

//改造前://2.连接reidsJedis jedis = new Jedis("192.168.92.131", 6379);//改造后://通过连接池得到jedis对象JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();Jedis jedis = jedisPoolInstance.getResource();

问题2:超卖的问题
----解决方法:通过乐观锁的方式,使用事务
(把他放到一个事务中,进行组队,进行执行)

//1.监视库存
Jedis.watch(kcKey);
//2.使用事务
multi.decr(kcKey);
multi.sadd(userKey, uid);
//执行
List<Object> results = multi.exec();

综上,全改造代码

public class doSecKill {//秒杀实例public static boolean doSecKill(String uid, String prodid) throws IOException {//1.uid和prodid的非空判断if (uid == null || prodid == null) {return false;}//2.连接reids,通过连接池得到jedis对象JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();Jedis jedis = jedisPoolInstance.getResource();//3.拼接key// 3.1库存keyString kcKey = "sk:" + prodid + ":qt";//3.2秒杀成功用户keyString userKey = "sk:" + prodid + ":user";//监视库存jedis.watch(kcKey);//4.获取库存,如果库存null,表示秒杀还没开始String kc = jedis.get(kcKey);if (kc == null) {System.out.println("秒杀还没有开始,请等待");jedis.close();return false;}//5.判断用户是否重复秒杀操作(使用set集合 中的sismember)Boolean sismember = jedis.sismember(userKey, uid);if (sismember) {System.out.println("已经秒杀成功了,不能重复秒杀");jedis.close();return false;}//6.判断如果商品数量,库存数量小于1,秒杀结束if (Integer.parseInt(kc) <= 0) {System.out.println("秒杀已经结束了");jedis.close();return false;}//7.秒杀过程// 改造秒杀过程,使用事务Transaction multi = jedis.multi();//组队操作multi.decr(kcKey);multi.sadd(userKey, uid);//执行List<Object> results = multi.exec();if (results == null || results.size() == 0) {System.out.println("秒杀失败了");jedis.close();return false;} else {System.out.println("秒杀成功");jedis.close();return true;}}
}

另外,会有乐观锁造成的库存遗留问题
----使用LUA脚本可以解决(我也不太懂,先记录,以后再进行补充)

1.Lua 语言
Lua 是一个小巧的脚本语言,Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,Lua并没有提供强大的库,一个完整的Lua解释器不过200k,所以Lua不适合作为开发独立应用程序的语言,而是作为嵌入式脚本语言。
很多应用程序、游戏使用LUA作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。

2、LUA脚本在Redis中的优势
将复杂的或者多步的redis操作,写为一个脚本,一次提交给redis执行,减少反复连接redis的次数。提升性能。
LUA脚本是类似redis事务,有一定的原子性,不会被其他命令插队,可以完成一些redis事务性的操作。
但是注意redis的lua脚本功能,只有在Redis 2.6以上的版本才可以使用。
利用lua脚本淘汰用户,解决超卖问题。
redis 2.6版本以后,通过lua脚本解决争抢问题,实际上是redis 利用其单线程的特性,用任务队列的方式解决多任务并发问题。

local userid=KEYS[1];
local prodid=KEYS[2];
local qtkey="sk:"..prodid..":qt";
local usersKey="sk:"..prodid.":usr';
local userExists=redis.call("sismember",usersKey,userid);
if tonumber(userExists)==1 then return 2;
end
local num= redis.call("get" ,qtkey);
if tonumber(num)<=0 then return 0;
else redis.call("decr",qtkey);redis.call("sadd",usersKey,userid);
end
return 1;

凡心所向,素履以往,生如逆旅,一苇以航。

Redis学习之秒杀案例相关推荐

  1. Redis 学习笔记-NoSQL数据库 常用五大数据类型 Redis配置文件介绍 Redis的发布和订阅 Redis_事务_锁机制_秒杀 Redis应用问题解决 分布式锁

    1.NoSQL数据库 1.1 NoSQL数据库概述 NoSQL(NosQL = Not Only sQL ),意即"不仅仅是sQL",泛指非关系型的数据库.NoSQL不依赖业务逻辑 ...

  2. Redis 秒杀案例

    Redis 秒杀案例 文章目录 Redis 秒杀案例 实现 ab工具模拟并发 超卖和超时问题解决 配置JedisPool连接池来解决超时问题 利用乐观锁淘汰用户,解决超卖问题 库存遗留问题解决 什么是 ...

  3. NetCore3.1连接Redis做秒杀案例

    测试环境:netcore3.1   redis-6.2.4 一:安装Redis 尽管在不是系统性介绍Radis的地方介绍安装radis并不是一件明智的事情,但本着能跑起来就算成功的原则,这里简单介绍一 ...

  4. Redis轻松实现秒杀系统

    点击关注公众号,实用技术文章及时了解 什么是秒杀 秒杀场景一般会在电商网站举行一些活动或者节假日在12306网站上抢票时遇到.对于电商网站中一些稀缺或者特价商品,电商网站一般会在约定时间点对其进行限量 ...

  5. Redis学习笔记(B站狂神说)(自己总结方便复习)

    Redis学习笔记B站狂神说 redis: 非关系型数据库 一.NoSQL概述 1.为什么要用Nosql 1.单机Mysql的年代 思考一下,这种情况下:整个网站的瓶颈是什么? 1.数据量如果太大,一 ...

  6. 菜鸟的redis学习总结

    菜鸟的redis学习总结 说明 一.Nosql和Mysql 二.Nosql常见类型及比较 三.简介 四.入门系列 (1)性能测试 (2)String类型 (3)List类型 (4)Set集合 (5)H ...

  7. Redis(学习笔记)

    Redis学习笔记 1.NoSQL数据库 1.1解决的问题 1.1.1解决CPU及内存压力 1.1.2解决IO压力 1.2NoSQL数据库概述 1.2.1什么是NoSQL数据库 1.2.2适用与不适用 ...

  8. 2021-3-20 狂神说java之 redis学习

    Nosql概述 Nosql = not only sql (不仅仅是SQL) 泛指非关系型数据库 关系型数据库:表格,行,列 很多的数据类型用户的个人信息,社交网络,地理位置.这些数据类型的存储不需要 ...

  9. Redis学习笔记②实战篇_黑马点评项目

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...

最新文章

  1. 响应式网页的布局设计
  2. Linux下修改MAC地址总结
  3. 号外号外!RancherOS v1.2.0发布啦!
  4. 计算机知识和技能,计算机基本知识和技能PPT课件.ppt
  5. Django 1.8.2 文档
  6. Android使用的工具类
  7. 使用SignalR和SQLTableDependency进行记录更改的SQL Server通知
  8. python程序流程控制结构_Python程序控制结构 | 分支结构
  9. stm32单片机相同系列型号代码移植
  10. jvm执行java大致采用过程_java练习题
  11. 神经网络前向传播和反向传播算法(作业4)
  12. 计算机学win7画图,Windows7电脑基础使用画图程序画一个小鸭
  13. Spring security开发权限管理系统(一)
  14. Java中switch的四种用法
  15. lazada代运营-代运营服务平台
  16. 如何用阿里iconfont,在伪元素选择器content:‘‘中添加文字标签
  17. java生成PDF,各种格式、样式、水印都有
  18. 苹果手机数据恢复软件|易我iOS恢复大师免费下载
  19. (原码、反码和补码)例子byte的详细讲解
  20. 物料信用体系建立助力国产铝电解电容器品牌崛起

热门文章

  1. ssm大学生生活用品出售网站源码+毕业论文+开题报告+答辩PPT+要求文档
  2. MySQL备份与恢复之MySQL 延时备份
  3. 各大搜索引擎网站收录入口
  4. SSRF漏洞(服务器端请求伪造)
  5. 创建QQ群--非常图形,208894875
  6. Build.gradule
  7. Jmeter性能测试3——JMETER-脚本优化
  8. 从零开始之驱动发开、linux驱动(二十二、输入子系统)
  9. 机器学习:优化算法Optimizer比较和总结(SGD/BGD/MBGD/Momentum/Adadelta/Adam/RMSprop)
  10. MySQL 配置数据库远程访问权限