当前位置: 首页 > news >正文

redis秒杀之lua脚本

Lua 脚本核心原理:
​1.单线程模型:Redis 使用单线程处理命令,所有命令按顺序执行。Lua 脚本会被视为一个整体任务,执行期间不会被其他命令中断。
​2.原子性保证:将库存检查、扣减、订单记录等多个操作放在一个脚本中,会连续执行,中间不会有其他客户端操作插入。保证了脚本的原子性。
​3.无需锁机制:由于 Redis 的单线程特性,Lua 脚本天然避免了并发冲突,无需额外加锁。

实现流程:

1.首先库存预热:活动开始前将对应商品的库存存redis;

2.然后实现lua脚本(可以将库存检查、扣减、订单记录等多个操作放在一个脚本中)。

下述的字段备注

-- 秒杀Lua脚本
-- KEYS[1]: 库存key
-- KEYS[2]: 订单集合key(用于去重)
-- ARGV[1]: 用户ID
-- ARGV[2]: 当前时间戳(可选)

-- 返回: 1-秒杀成功; 0-秒杀失败

php具体实现如下:

class SeckillService
{private $redis;public function __construct(){$this->redis = new Redis();$this->redis->connect('127.0.0.1', 6379);}/*** 执行秒杀* @param int $productId 商品ID* @param int $userId 用户ID* @return array ['success'=>bool, 'msg'=>string]*/public function seckill($productId, $userId){// 定义Redis key$stockKey = "product:{$productId}:stock";$orderKey = "product:{$productId}:orders";// Lua脚本$luaScript = <<<LUA
local stockKey = KEYS[1]
local orderKey = KEYS[2]
local userId = ARGV[1]local stock = tonumber(redis.call('GET', stockKey) or 0)
if stock <= 0 thenreturn 0
endif redis.call('SISMEMBER', orderKey, userId) == 1 thenreturn 0
endredis.call('DECR', stockKey)
redis.call('SADD', orderKey, userId)
return 1
LUA;try {// 执行Lua脚本$result = $this->redis->eval($luaScript, [$stockKey, $orderKey, $userId], 2 // KEYS的数量);if ($result == 1) {// 秒杀成功,异步创建实际订单到数据库$this->createOrderAsync($productId, $userId);return ['success' => true, 'msg' => '秒杀成功'];}return ['success' => false, 'msg' => '秒杀失败,可能已售罄或您已参与过'];} catch (Exception $e) {// 记录日志error_log("秒杀异常: " . $e->getMessage());return ['success' => false, 'msg' => '系统繁忙,请稍后再试'];}}/*** 异步创建订单(实际项目中可用消息队列实现)*/private function createOrderAsync($productId, $userId){// 这里可以写入消息队列或直接处理// 示例: 写入文件日志,实际项目中不要这样做$orderData = json_encode(['product_id' => $productId,'user_id' => $userId,'time' => time()]);file_put_contents('orders.log', $orderData . "\n", FILE_APPEND);// 实际项目建议使用消息队列如RabbitMQ、Kafka等// $this->mq->publish('order_queue', $orderData);}/*** 初始化商品库存(仅在活动前调用)*/public function initStock($productId, $quantity){$stockKey = "product:{$productId}:stock";return $this->redis->set($stockKey, $quantity);}
}

http://www.dtcms.com/a/292612.html

相关文章:

  • 20250722解决在Ubuntu 24.04.2下编译RD-RK3588开发板的Android13出现找不到python2的问题
  • GraphRAG的部署和生成检索过程体验
  • C++11--锁分析
  • npm全局安装后,依然不是内部或外部命令,也不是可运行的程序或批处理文件
  • 大数据量查询计算引发数据库CPU告警问题复盘
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第二十二讲)
  • Linux_Ext系列文件系统基本认识(一)
  • Product Hunt 每日热榜 | 2025-07-22
  • “鱼书”深度学习入门 笔记(1)前四章内容
  • day19 链表
  • 【科研绘图系列】R语言绘制柱状堆积图
  • 基于 Vue,SPringBoot开发的新能源充电桩的系统
  • 豪鹏科技锚定 “AI + 固态” 赛道:从电池制造商到核心能源方案引领者的战略跃迁
  • mybatis拦截器实现唯一索引的动态配置
  • 网络基础DAY16-MSTP-VRRP
  • git reset --soft和 git reset --mixed的主要区别
  • 智能制造——解读制造业企业数字化转型实施指南2025【附全文阅读】
  • libgmp库(GNU高精度算术库)介绍
  • 算法训练营day28 贪心算法②122.买卖股票的最佳时机II、55. 跳跃游戏、 45.跳跃游戏II 、1005.K次取反后最大化的数组和
  • Web服务器(Tomcat、项目部署)
  • 0722 数据结构顺序表
  • 循环神经网络--NLP基础
  • <另一种思维:语言模型如何展现人类的时间认知>总结
  • 大型语言模型(Large Language Models,LLM)
  • Science Robotics 机器人成功自主完成猪胆囊切除手术
  • vue3 动态判断 el-table列 用 v-if 是否显示
  • 微算法科技(NASDAQ: MLGO)探索优化量子纠错算法,提升量子算法准确性
  • 4.组合式API知识点(2)
  • 计算机视觉领域的AI算法总结——目标检测
  • C语言:循环结构