您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

一起聊聊Redis实现秒杀的问题

2024/6/19 18:32:09发布31次查看
本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于实现秒杀的相关内容,包括了秒杀逻辑、存在的链接超时、超卖和库存遗留的问题,下面一起来看一下,希望对大家有帮助。
推荐学习:redis视频教程
1、秒杀逻辑秒杀:解决计数器和人员记录的事务操作
1.uid和proid非空判断2.连接redis3.拼接key库存key秒杀成功用户key4.获取库存,如果库存为null,秒杀还没开始5.判断用户是否重复秒杀操作6.判断商品数量,库存数量小于1,秒杀结束7.秒杀过程库存-1把秒杀成功用户添加清单里面2、存在问题2.1、连接超时原因:由于大量创建连接,十分消耗性能,并且有时获取连接不及时,出现连接超时的情况
2.2、超卖在并发的情况下发生的,就是在输出没有库存(秒杀结束)后还有商品售出导致库存数量为负数。
2.3、库存遗留使用乐观锁解决问题2之后,出现问题3
如果库存数量相对并发更多,由于使用乐观锁,第一个用户秒杀成功后会修改库存键的版本号,其他抢到的用户会因为版本号不同导致无法继续购买,就会有库存遗留问题
3、解决3.1、连接超时使用连接池,工具类如下:
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(200); poolconfig.setmaxidle(32); poolconfig.setmaxwaitmillis(100 * 1000); poolconfig.setblockwhenexhausted(true); poolconfig.settestonborrow(true); jedispool = new jedispool(poolconfig, 127.0.0.1, 6379, 60000); } } } return jedispool; }}//使用jedispool jedispoolinstance = jedispoolutil.getjedispoolinstance();jedis jedis = jedispoolinstance.getresource();
springboot版本(pom.xml引入,application.yml配置,然后注入对象即可)
<dependency>    <groupid>org.springframework.boot</groupid>    <artifactid>spring-boot-starter-data-redis</artifactid></dependency><dependency>    <groupid>redis.clients</groupid>    <artifactid>jedis</artifactid>    <version>3.2.0</version></dependency>
spring:  redis:    host: 127.0.0.1    port: 6379    database: 0    timeout: 1800000    lettuce:      pool:        max-active: 20        max-wait: -1        max-idle: 5        min-idle: 0
@autowired    private redistemplate redistemplate;
3.2、超卖问题使用redis事务,乐观锁 + watch
//监视库存jedis.watch(kckey);//中间代码忽略//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;}
3.3、乐观锁导致的库存遗留问题使用lua嵌入式脚本语言
将复杂的或者多步的 redis 操作,写为一个脚本,一次提交给redis运行,减少反复连接 reids的次数。提升性能。lua脚本是类似 redis 事务,有一定的原子性,不会被其他命令插队,可以完成redis事务性的操作lua脚本功能,在redis 2.6以上的版本才可以使用利用 lua 脚本淘汰用户,解决超卖问题。redis 2.6 版本以后,通过 lua 脚本解决争抢问题,实际上是 redis 利用其单线程的特性,用任务队列的方式解决多任务并发问题。local userid=keys[1]; //1、2行定义两个变量, local prodid=keys[2];local qtkey=sk:..prodid..:qt; //3,4行定义拼接keylocal userskey=sk:..prodid..:usr;local userexists=redis.call(sismember,userskey,userid); //5-8,判断用户是否存在,不存在return 2if tonumber(userexists)==1 then    return2;endlocal num=redis.call(get,qtkey); //9-11,判断商品是否存在if tonumber(num)<=0 then    return 0;else //12-15,用户和商品操作    redis.call(decr,qtkey);    redis.call(sadd,userskey,userid);endreturn1;   //最后一行return 1;  秒杀成功
完整代码如下:
// 定义两段lua脚本(使用lua脚本可以解决乐观锁带来的库存遗留问题) static string seckillscript = local userid=keys[1];\r\n + local prodid=keys[2];\r\n + local qtkey='sk:'..prodid..\:qt\;\r\n + local userskey='sk:'..prodid..\:usr\;\r\n + local userexists=redis.call(\sismember\,userskey,userid);\r\n + if tonumber(userexists)==1 then \r\n +    return 2;\r\n + end\r\n + local num= redis.call(\get\ ,qtkey);\r\n + if tonumber(num)<=0 then \r\n +    return 0;\r\n + else \r\n +    redis.call(\decr\,qtkey);\r\n +    redis.call(\sadd\,userskey,userid);\r\n + end\r\n + return 1 ;   public static boolean doseckill(string uid,string prodid) throws ioexception {  jedispool jedispool =  jedispoolutil.getjedispoolinstance(); jedis jedis=jedispool.getresource(); jedis.select(2);  // 通过jedis的scriptload方法加载lua脚本 string sha1=  jedis.scriptload(seckillscript); //通过jedis的evalsha方法调用lua脚本 object result= jedis.evalsha(sha1, 2, uid,prodid);  string restring=string.valueof(result); if (0.equals( restring )  ) { system.err.println(已抢空!!); }else if(1.equals( restring )  )  { system.out.println(抢购成功!!!!); }else if(2.equals( restring )  )  { system.err.println(该用户已抢过!!); }else{ system.err.println(抢购异常!!); } jedis.close(); return true; }
推荐学习:redis视频教程
以上就是一起聊聊redis实现秒杀的问题的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product