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

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. Factory-pattern 三种工厂模式
  2. 浅淡Windows7 32位与64位/x86与x64的区别
  3. linux挂载设备类型lvm,linux——管理系统设备之LVM的管理
  4. java正则表达式所有字符串_java正则表达式获取字符串中所有匹配的内容
  5. assert宏的用法
  6. Spring Boot集成Dubbo多模块项目创建与配置
  7. 艾宾浩斯记忆表格excel_Excel全年学习复习计划表(艾宾浩斯遗忘曲线)
  8. java21天打卡 day10-字符串2
  9. Arduino教程 RFID-RC522读IC卡门禁原理及破解防御
  10. 局域网屏幕共享_我把手机、平板、笔记本,变成了电脑的第二屏幕。
  11. App测试实战:测试内容、测试工具、测试效果
  12. 单元一: 全桥驱动电路(驱动MOS/IGBT均适用,附带硬件)
  13. HTML编辑器-Bluefish 2.0.1 发布
  14. Centos 6.6安装chrome 谷歌浏览器
  15. LikeLib:区块链+云计算的结合技术现在成熟了吗?
  16. 快乐二级域名分发程序-美化版源码
  17. Python定义常量,设置config.py文件
  18. influx数据同步
  19. 本周推荐 | 基于 canvas 实现 H5 丝滑看图体验
  20. 优思学院|六西格玛黑带考试难不难?

热门文章

  1. CAD2009开发笔记(一)
  2. oracle数字签名,gnupg数字签名与加密详解
  3. chrome去除htst_HTTP Strict Transport Security实战详解
  4. 并发编程三大特性——原子性
  5. htc820+android+l,HTC Desire 820手机更新 安卓6.0+Sense 7.0
  6. java忍者_Java字节码忍者禁术
  7. 用计算机写作文主题,体验自然之美 感受田园欢乐——用计算机写作文教案
  8. 用了IC卡刷卡水控器有什么好处
  9. Linux 卸载OpenJDK
  10. python getattribute方法_Python:避免getattribute中的无限循环__