一. 场景

下单后库存校验或者秒杀场景下,有很多利用“锁”的方案来解决问题。但是加锁其实是一件性价比很低的事,所以我们采用用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实现加减库存相关推荐

  1. redis实现抽奖php,使用redis zset实现抽奖,奖池商品按时间随机分布

    话不多说,直接上需求描述: 最近需要上一期活动,这个活动是以转盘抽奖为形式的抽奖活动,要求每个用户用积分进行抽奖,且中奖率为100%即不可出现不中任何奖品的情况,之后,又加了一个要求,即不能实行纯随机 ...

  2. synchronized、Lock和 redis锁,基于redis实现的扣减库存锁(附代码)

    目录 锁的概念 公平锁 可中断锁 可重入锁 几种加锁方式 synchronized Lock Lock接口的6个方法: Lock的实现类 ReentrantLock 可重入锁 ReadWriteLoc ...

  3. 【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分布式锁的 ...

  4. 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 ...

  5. Lua 脚本内部执行 Redis 命令

    Lua 脚本内部允许通过内置函数执行 Redis 命令: redis.call() redis.pcall() 两者非常相似,区别在于: 若 Redis 命令执行错误,redis.call() 将错误 ...

  6. 华为云GuassDB(for Redis)发布全新版本推出:Lua脚本和SSL连接加密

    摘要:9月8日,华为云GuassDB(for Redis)正式推出全新版本.新版本内核带来性能提升.无损升级.慢日志统计等多维度产品体验,同时推出Lua脚本和SSL连接加密两大重要功能,让业务设计更加 ...

  7. Redis学习笔记 - Lua脚本(2) - Lua脚本的实现

    参考:<<Redis设计与实现>> 注:这本书是基于Redis3.0版本写的,和后面的版本有点差异 Redis中Lua脚本相关命令介绍以及简单使用,参考博客:https://b ...

  8. java使用lua脚本操作 redis_在Redis中使用简单强大的Lua脚本

    Redis分布式锁加锁 前段时间写Redis分布式锁,想着在小灰文章的基础上再总结一下,这样能有更深的印象,顺便把Lua脚本分享一下,如果项目中使用Redis比较多,那么Lua脚本一定是会用到的,因为 ...

  9. 【开发经验】redis实现抽奖功能

    文章目录 前言 一.抽奖功能要点 1.1.奖品多抽问题 1.2.概率计算问题 二.redis实现抽奖 前言 抽奖的功能在互联网的项目中随处可见,通过这些给用户惊喜的功能,来达到引流的效果.但是这个功能 ...

最新文章

  1. 前端console log之坑。。。
  2. mybatis调用oracle存储过程
  3. 八个非常实用的vsCode扩展插件,千万别错过了!
  4. 活用这23种图表,让你的数据分析胜人一筹 | 推荐收藏
  5. BCrypt加密怎么存入数据库_dns污染怎么解决
  6. [Python] virtualenvwrapper 常见问题
  7. C# 程序Hello World
  8. 两年数据对比柱形图_你与专业堆积柱形图的距离,只差一个数据标签
  9. 笔记本无线自动配置服务器,笔记本无线网卡充当路由器组建局域网
  10. flex:1代表什么意思
  11. python 3 5的值_杨桃Python基础教程第5章:Python数据类型(3)列表s[M:n]值,的,三,smn,取值...
  12. android当电脑麦克风,电脑没有麦克风?让手机充当电脑麦克风!
  13. 无线网络安全——1、WiFi安全基础知识
  14. ADO简介(未完成)
  15. 教你搭个助我大学拿Offer的面试项目
  16. Robust stochastic frontier analysis
  17. 松下电视机竟暗藏魂斗罗游戏(哈哈哈)
  18. 五个热门的免费Linux视频软件下载
  19. 关于Unity5 发布到安卓后帧数低的问题
  20. Gem5在X64架构下运行SPEC2006

热门文章

  1. linux c之用fopen、fputs、fgets、 fseek来对文件进行写、替换、读
  2. Andorid之教你全手工去除定制软件
  3. .bash_profile和.bashrc说明
  4. 【python opencv 计算机视觉零基础到实战】二、 opencv文件格式与摄像头读取
  5. solidity modifier函数修改器 智能合约开发知识浅学(三)
  6. python好用的模块和包_Python模块和包详细讲解与实例分析
  7. 120天的烧脑只为孩子设计一套教具~
  8. 数据这么多,且看R语言怎么处理!
  9. 数据可视化,带给你的惊艳并不止这一点!
  10. 如何用matlab消除谐波,如何在含有整次谐波和非整次谐波的信号中去除整次谐波?...