redis lua 抽奖 PHP,通过redis+lua实现加减库存
一. 场景
下单后库存校验或者秒杀场景下,有很多利用“锁”的方案来解决问题。但是加锁其实是一件性价比很低的事,所以我们采用用redis+lua的方式来实现这个功能。
二. 思路
阶段一:
在库存加减逻辑中分为2个步骤:STEP1.读取库存,STEP2.读取库存。
利用其他方法例如"锁"等,也就是想控制好STEP2一定要紧跟STEP1,本质上就是确保获取的库存的最新的数据为最新。
阶段二:
在相对较高的并发场景下,redis被常用作库存管理,我们需要通过最小成本的改动来实现库存的限制。但是redis的读取库存+读取库存一般都是有上层应用代码控制,有没有办法在一个函数调用中能串行执行这俩个步骤了?
阶段三:
众所周知,redis是单线程的,并且现在已经支持lua脚本,那是不是可以利用该组合实现我们的场景了?
三. 设计方案
这个方案就很简单了,直接利用redistemplate执行lua脚本
四. 代码
4.1 lua脚本代码样例
private static final String GET_COUPON_CODE =
"local values = redis.call('hmget',KEYS[1],'recvCnt','couponCnt');\n" + //lua返回value的数组
"if tonumber(values[1]) < tonumber(values[2]) then \n" + //lua的数组索引从1开始 values[1] = recvCnt,values[2] = couponCnt
" redis.call('hincrby',KEYS[1],'recvCnt',1);\n" +
" return true;\n" +
"else\n " +
" return false;\n" +
"end\n";
4.2 redis调用lua脚本
//执行调用
execute(GET_COUPON_CODE, keys);
//此处将数值类型转化为Long
public Long execute(String redisScript,List keys){
RedisScript REDIS_SCRIPT = new DefaultRedisScript<>(redisScript, Long.class);
return redisTemplate.execute(REDIS_SCRIPT,keys);
}
4.3 lua基本用法
redis.call()
redis.pcall()
call与pcall基本上一样。脚本报错时,call会直接报错,pcall不会报错,会把错误信息放到lua table 的err字段中。
五. 说明
1.记得利用“\n”分行,也可以利用string的append拼接
2.values[n]对应有序数组keys,需要控制好各数据顺序
3.lua的数组索引从1开始
六. 总结
我们先分析场景,通过多种方案对比,选用了redis+lua的组合来满足我们的业务需要。利用redis单线程的特点,以及redis2.6版本后开始对lua的支持,我们采用redis执行lua脚本来确保我们查询+修改的串行执行。后面我们展示了code的实现案例,以及介绍了lua脚本的一些注意事项,可以依葫芦画瓢形式自己实现自己的需求。综合而言,我们分析场景应先分析其核心问题,然后利用一些更简洁的方法或小技巧来落地。
redis lua 抽奖 PHP,通过redis+lua实现加减库存相关推荐
- redis实现抽奖php,使用redis zset实现抽奖,奖池商品按时间随机分布
话不多说,直接上需求描述: 最近需要上一期活动,这个活动是以转盘抽奖为形式的抽奖活动,要求每个用户用积分进行抽奖,且中奖率为100%即不可出现不中任何奖品的情况,之后,又加了一个要求,即不能实行纯随机 ...
- synchronized、Lock和 redis锁,基于redis实现的扣减库存锁(附代码)
目录 锁的概念 公平锁 可中断锁 可重入锁 几种加锁方式 synchronized Lock Lock接口的6个方法: Lock的实现类 ReentrantLock 可重入锁 ReadWriteLoc ...
- 【2020尚硅谷Java大厂面试题第三季 04】Redis 9种数据类型使用场景,分布式锁演变步骤,lua脚本,redis事务,Redisson,Redis内存占用,删除策略,内存淘汰策略,手写LRU
1.安装redis6.0.8 2023 02 02 为:redis-7.0.8.tar.gz 2.redis传统五大数据类型的落地应用 3.知道分布式锁吗?有哪些实现方案?你谈谈对redis分布式锁的 ...
- CentOS6.4 安装OpenResty和Redis 并在Nginx中利用lua简单读取Redis数据
1.下载OpenResty和Redis OpenResty下载地址:wget http://openresty.org/download/ngx_openresty-1.4.3.6.tar.gz Re ...
- Lua 脚本内部执行 Redis 命令
Lua 脚本内部允许通过内置函数执行 Redis 命令: redis.call() redis.pcall() 两者非常相似,区别在于: 若 Redis 命令执行错误,redis.call() 将错误 ...
- 华为云GuassDB(for Redis)发布全新版本推出:Lua脚本和SSL连接加密
摘要:9月8日,华为云GuassDB(for Redis)正式推出全新版本.新版本内核带来性能提升.无损升级.慢日志统计等多维度产品体验,同时推出Lua脚本和SSL连接加密两大重要功能,让业务设计更加 ...
- Redis学习笔记 - Lua脚本(2) - Lua脚本的实现
参考:<<Redis设计与实现>> 注:这本书是基于Redis3.0版本写的,和后面的版本有点差异 Redis中Lua脚本相关命令介绍以及简单使用,参考博客:https://b ...
- java使用lua脚本操作 redis_在Redis中使用简单强大的Lua脚本
Redis分布式锁加锁 前段时间写Redis分布式锁,想着在小灰文章的基础上再总结一下,这样能有更深的印象,顺便把Lua脚本分享一下,如果项目中使用Redis比较多,那么Lua脚本一定是会用到的,因为 ...
- 【开发经验】redis实现抽奖功能
文章目录 前言 一.抽奖功能要点 1.1.奖品多抽问题 1.2.概率计算问题 二.redis实现抽奖 前言 抽奖的功能在互联网的项目中随处可见,通过这些给用户惊喜的功能,来达到引流的效果.但是这个功能 ...
最新文章
- 前端console log之坑。。。
- mybatis调用oracle存储过程
- 八个非常实用的vsCode扩展插件,千万别错过了!
- 活用这23种图表,让你的数据分析胜人一筹 | 推荐收藏
- BCrypt加密怎么存入数据库_dns污染怎么解决
- [Python] virtualenvwrapper 常见问题
- C# 程序Hello World
- 两年数据对比柱形图_你与专业堆积柱形图的距离,只差一个数据标签
- 笔记本无线自动配置服务器,笔记本无线网卡充当路由器组建局域网
- flex:1代表什么意思
- python 3 5的值_杨桃Python基础教程第5章:Python数据类型(3)列表s[M:n]值,的,三,smn,取值...
- android当电脑麦克风,电脑没有麦克风?让手机充当电脑麦克风!
- 无线网络安全——1、WiFi安全基础知识
- ADO简介(未完成)
- 教你搭个助我大学拿Offer的面试项目
- Robust stochastic frontier analysis
- 松下电视机竟暗藏魂斗罗游戏(哈哈哈)
- 五个热门的免费Linux视频软件下载
- 关于Unity5 发布到安卓后帧数低的问题
- Gem5在X64架构下运行SPEC2006
热门文章
- linux c之用fopen、fputs、fgets、 fseek来对文件进行写、替换、读
- Andorid之教你全手工去除定制软件
- .bash_profile和.bashrc说明
- 【python opencv 计算机视觉零基础到实战】二、 opencv文件格式与摄像头读取
- solidity modifier函数修改器 智能合约开发知识浅学(三)
- python好用的模块和包_Python模块和包详细讲解与实例分析
- 120天的烧脑只为孩子设计一套教具~
- 数据这么多,且看R语言怎么处理!
- 数据可视化,带给你的惊艳并不止这一点!
- 如何用matlab消除谐波,如何在含有整次谐波和非整次谐波的信号中去除整次谐波?...