一个秒杀就把 MySQL 打挂了?我用 Redis + 异步削峰扛住了 100 倍流量
一个秒杀就把 MySQL 打挂了我用 Redis 异步削峰扛住了 100 倍流量 前言“服务器竟然挂了”——下午 14:00秒杀准时开启你盯着监控面板QPS 瞬间飙到 3 万数据库连接池爆满慢查询堆积成山Tomcat 线程全部阻塞。用户端疯狂重试nginx 日志全是 502页面白屏转圈一分钟后弹出网络异常。产品经理冲过来问还能不能恢复你盯着数据库连接数的折线图——已经是一条垂直线了。MySQL CPU 100%磁盘 IO 打满慢查询队列里排着上万个UPDATE stock正在死锁回滚。这不是虚构的生产事故。我经历过。而且不止一次。本文会把那次完整的技术选型、排查过程、优化方案、底层原理全部拆开讲清楚。如果你团队下一个版本也要上秒杀这可能是你今天读到最值的一篇文章。 环境说明组件版本/说明应用服务器Spring Boot 2.7 Tomcat 9数据库MySQL 8.0 集群1主2从缓存Redis 6.x 单机操作系统CentOS 7, 8C16G × 3 节点压测工具JMeter 5.5预估峰值3 万 QPS实际扛到 5000 开始雪崩 问题复现先看优化前的架构。简单到令人放心用户请求经过 nginx 负载均衡到 TomcatTomcat 直接操作 MySQL 集群。看起来没什么问题对吧MySQL集群TomcatNginx用户MySQL集群TomcatNginx用户点击立即秒杀转发请求检查库存库存充足校验一人一单未购买过UPDATE stock SET countcount-1INSERT INTO order ...订单创建成功返回抢购成功这套流程在低并发时表现完美。但在秒杀场景下暴露了三个致命问题问题 1MySQL 行锁变表锁噩梦库存表的核心 SQL 长这样UPDATEseckill_stockSETcountcount-1WHEREgoods_id?ANDcount0;-- -- 同一商品所有用户竞争同一行锁秒杀开始瞬间上万请求涌入。MySQL行锁排队事务等待时间飙升到秒级大量请求超时回滚后立刻重试——形成死锁风暴 雪崩。问题 2一人一单校验反复查库// 优化前的校验逻辑OrderorderorderMapper.selectByUserIdAndGoodsId(userId,goodsId);// -- 每次查MySQLif(order!null){thrownewBusinessException(每人限购一件);}假设 3 万 QPS一人一单这一步就产生 3 万次 MySQL 查询。对于秒杀这种写多读更多的场景MySQL 的 IO 根本扛不住。问题 3Tomcat 线程池耗尽Tomcat 默认线程池 200。200 个线程全部阻塞在数据库连接获取上——等待排队、等待锁释放、等待回滚。新请求进不来HTTP 连接超时后用户疯狂 F5 重试把服务器推向更深的雪崩。压测数据说明一切指标优化前3 万并发数据库连接池满120/120MySQL CPU100%平均响应时间8.7 s下单成功率3.2%Tomcat 线程200/200 阻塞这不是秒杀——这是自毁程序。 排查过程尝试 1: 加 MySQL 连接池和索引 ❌第一反应是MySQL 太忙了给它加点资源。把连接池从 120 加到 500给seckill_stock表加了(goods_id, user_id)联合索引把UPDATE改为只更新乐观锁版本号。结果连接多了行锁竞争更激烈——500 个线程同时争同一行死锁频次翻倍。TPS 从 200 降到 80。教训秒杀的本质矛盾不是 MySQL 连接不够是同一行记录的写竞争。MySQL 的行锁机制决定了它不适合高并发热点写。尝试 2: 前端限流 按钮置灰 ❌前端倒计时结束后按钮置灰 3 秒后端 nginxlimit_req限制单 IP 1r/s。结果阻止不了专业黄牛他们发包不经过前端、阻止不了海量并发IP 分布极广。真正用户也被限流挡在外面——误杀率 40%。教训前端限流只能做辅助不能依赖。秒杀的核心矛盾不在入口在数据库层。尝试 3: 引入 Redis 预减库存 异步下单 ✅第二次大促前花了两周重构了秒杀链路。核心思路只有一句话把秒杀的资格校验和正式下单解耦。让 Redis 扛住瞬时流量做资格判断把真正写入 MySQL 的操作放到队列里异步执行。MySQL集群异步线程阻塞队列RedisNginx用户MySQL集群异步线程阻塞队列RedisNginx用户异步解耦点击立即秒杀LUA脚本检查库存 一人一单返回抢购成功 订单ID保存订单信息到阻塞队列独立线程读取队列减库存无锁竞争创建订单落库成功变更后重新压测指标优化前优化后数据库连接池满120/120稳定 12 个连接MySQL CPU100%15%平均响应时间8.7 s12 ms下单成功率3.2%99.7%Tomcat 线程200/200 阻塞20 活跃️ 解决方案详细实现核心一Redis LUA 脚本做资格校验为什么用 LUA 脚本因为 Redis 的 LUA 脚本原子执行在整个脚本运行期间不会被其他命令打断。-- check_and_dec.lua-- KEYS[1]: 商品库存 key-- KEYS[2]: 用户已购 set key-- ARGV[1]: 用户 ID-- ARGV[2]: 商品 ID-- 1. 检查库存localstocktonumber(redis.call(GET,KEYS[1]))ifnotstockorstock0thenreturn-1-- 库存不足end-- 2. 检查一人一单localisBoughtredis.call(SISMEMBER,KEYS[2],ARGV[1])ifisBought1thenreturn-2-- 已购买过end-- 3. 预减库存 记录用户redis.call(DECR,KEYS[1])redis.call(SADD,KEYS[2],ARGV[1])-- 4. 生成唯一订单号localorderIdredis.call(INCR,order:id:gen)returnorderId调用这段 LUA 脚本整个秒杀资格校验在一次网络 IO 几微秒内完成彻底绕过了 MySQL。核心二线程池 阻塞队列异步落库ComponentpublicclassSeckillAsyncProcessor{privatefinalExecutorServiceexecutornewThreadPoolExecutor(1,// corePoolSize1,// maxPoolSize0L,TimeUnit.SECONDS,newLinkedBlockingQueue(10000),// -- 阻塞队列做缓冲区newThreadPoolExecutor.CallerRunsPolicy());PostConstructpublicvoidstartConsumer(){executor.submit(()-{while(true){try{SeckillMessagemsgqueue.take();// -- 阻塞获取processOrder(msg);}catch(Exceptione){log.error(异步下单失败,e);}}});}publicbooleanaddTask(SeckillMessagemsg){returnqueue.offer(msg,100,TimeUnit.MILLISECONDS);// -- 超时保护}}关键设计点单线程消费避免数据库写冲突天然解决行锁问题LinkedBlockingQueue作为缓冲区削峰填谷offer()带超时队列满时快速失败不让上游阻塞秒杀场景要用快速拒绝策略然后让用户重试核心三nginx 层面做网关限流limit_req_zone $binary_remote_addr zoneseckill:10m rate100r/s; location /seckill/ { limit_req zoneseckill burst50 nodelay; proxy_pass http://backend_servers; limit_req_status 429; error_page 429 /seckill_busy.html; }nginx 限流放在最外层挡住 90% 的无效流量让 Redis 只处理真正有资格进来的请求。踩坑记录README 没有告诉你的Redis DECR 可能变成负数——LUA 脚本里必须先 GET 判断库存 0 再 DECR不要直接 DECR 后判断。阻塞队列不能无限大——上限设为 10000超过直接拒绝。否则内存被打满OOM 了连日志都写不出去。异步线程要单独处理失败重试——如果数据库写入失败不能简单重试。设计一张状态表记录异步订单的处理状态用定时任务补偿。 原理分析为什么 Redis 比 MySQL 快这么多当我说Redis 能在几微秒内完成资格校验你不是应该只记住这个结论而是要理解为什么。对比维度MySQLRedis数据存储磁盘 Buffer Pool内存数据模型行 表 索引B树Hash / Set / String哈希表事务模型ACID / MVCC / 行锁LUA 原子执行并发瓶颈行锁竞争 → 死锁 → 回滚单线程 事件循环 → 无锁典型延迟1-10 ms含网络0.1-1 ms3 万 QPS 表现CPU 100%连接池爆满CPU 20%连接稳定根本原因MySQL 为了 ACID每一行数据写入都要经过Buffer Pool → Redo Log → Binlog → 脏页刷盘同一行的 UPDATE 还会产生行锁排队。而 Redis 纯粹在内存操作LUA 脚本保证原子性单线程模型天然避免了并发写冲突。秒杀场景下Redis 做资格校验是降维打击。为什么要用异步削峰优化后3万请求Redis资格校验1%通过 99%快速拒绝阻塞队列 削峰填谷单线程异步 顺序写入MySQL优化前3万请求直接写MySQL行锁/死锁/雪崩优化前3 万请求同时打到 MySQL每个请求都需要完整的数据库写操作——这是同心圆式压力放大。优化后99% 的请求在 Redis 层就被快速拒绝了“库存不足或已购买”只有真正抢到的请求进入队列。队列作为缓冲区让 MySQL 的写入速率变成可控的每秒几百笔——这才是数据库能优雅处理的速度。LUA 原子性的边界在哪一个很多人问的问题如果 Redis 执行 LUA 脚本的瞬间宕机了怎么办场景Redis 已经执行了 DECR stock 和 SADD user_set但还没把订单号返回给客户端就宕机了。解决方案订单号不要依赖 Redis 返回。让 Redis 只判断有资格/没资格返回布尔值。真正的订单号用雪花算法在应用层生成并配套一个任务状态表CREATETABLEseckill_task(idBIGINTPRIMARYKEY,user_idBIGINTNOTNULL,goods_idBIGINTNOTNULL,statusTINYINTDEFAULT0COMMENT0-待处理 1-成功 2-失败,create_timeDATETIMEDEFAULTCURRENT_TIMESTAMP,INDEXidx_status(status));异步线程处理完后更新状态。定时任务每 5 秒扫描 status0 的记录超过 30 秒未处理的做补偿处理。这叫最终一致——秒杀场景下你不需要强一致性但必须保证数据不丢。 总结不要把 MySQL 当秒杀引擎。MySQL 的行锁和磁盘 IO 决定了它不适合做热点写让它做最终落库就够了。Redis LUA 原子脚本做资格校验把 3 万 QPS 降维到几百 TPS 的 DB 写入延迟从 8 秒降到 12 毫秒。**异步削峰阻塞队列 单线程消费者**让数据库写入速率变得可控完全避免死锁和雪崩。最终一致性 强一致性。秒杀不是银行转账短暂的缓存和数据库不一致可以接受但数据绝对不能丢。延伸思考如果你的秒杀规模更大比如双十一百亿级上面这套方案还需要补充什么Redis 单机不够 →Redis Cluster 本地标记缓存阻塞队列内存不够 →Kafka/RocketMQ 替代内存队列数据库还不够 →分库分表 读写分离技术选型的核心就一句话让合适的组件干合适的活。 参考资料Redis Lua 脚本官方文档Spring Boot 异步任务配置MySQL 行锁与死锁分析秒杀系统设计 · 美团技术博客nginx ngx_http_limit_req_module本文为原创内容转载请注明出处。如果这篇文章对你有帮助欢迎点赞 、收藏 ⭐、关注 ➕你的支持是我持续输出的动力

相关新闻

F429-HAL-Usart(2026/7/23)

F429-HAL-Usart(2026/7/23)

目录 一、printf → fputc 完整流程图 二、两个实际细节 2.1 fputc 参数里的 FILE *f 为什么从来没用到? 2.2 超时值 0xFFFF vs 1000 的区别 三、分层架构总览 四、HAL_UART_Transmit vs HAL_UART_Receive 函数原型对比 对应到代码 一个比喻 超时值的小结 …

2026/7/23 16:53:59 阅读更多 →
【AI数字人形象定制黄金法则】:20年实战总结的7大避坑指南与3步高转化定制流程

【AI数字人形象定制黄金法则】:20年实战总结的7大避坑指南与3步高转化定制流程

更多请点击: https://codechina.net 第一章:AI数字人形象定制的底层逻辑与价值本质 AI数字人形象定制并非简单的图像合成或3D建模叠加,其底层逻辑建立在多模态感知、神经辐射场(NeRF)重建、参数化人脸模型&#xff08…

2026/7/23 16:53:59 阅读更多 →
AI客服系统优化:Agentic思维与5大实战技巧

AI客服系统优化:Agentic思维与5大实战技巧

1. 项目概述:当AI客服遇上Agentic思维去年夏天,我接手了一个濒临崩溃的智能客服系统改造项目。这个日均处理20万次咨询的系统,当时正面临37%的转人工率和大量用户投诉。在重构过程中,我发现传统基于固定流程的对话设计已经遇到天花…

2026/7/23 16:53:59 阅读更多 →

最新新闻

量化交易平台商业化困境与破局路径分析

量化交易平台商业化困境与破局路径分析

1. 量化交易平台的商业困境解析 "量化平台玩家"这个群体正在经历一场前所未有的身份危机。去年某头部平台公布的数据显示,超过67%的个人量化策略开发者月收入不足5000元,而平台方自身的商业化尝试也屡屡碰壁。这个看似光鲜的领域,实…

2026/7/23 17:02:02 阅读更多 →
嵌入式以太网开发:从PHY芯片到TCP/IP协议栈的完整方案解析

嵌入式以太网开发:从PHY芯片到TCP/IP协议栈的完整方案解析

1. 项目概述与核心价值 在嵌入式系统开发中,实现稳定、高速的网络连接一直是个硬骨头。尤其是在工业控制、电信设备或者需要远程数据采集的场景里,你需要的不仅仅是一个能“联网”的功能,而是一个从物理层到协议栈都经过验证、能扛住恶劣环境…

2026/7/23 17:02:02 阅读更多 →
TM4C123BH6ZRB I2C寄存器级编程:从时序到实战代码

TM4C123BH6ZRB I2C寄存器级编程:从时序到实战代码

1. 项目概述与I2C核心价值在嵌入式系统开发中,设备间的通信是构建复杂功能的基础。面对GPIO点对点通信的繁琐、SPI需要较多引脚、UART缺乏寻址能力的局限,I2C(Inter-Integrated Circuit)总线以其简洁的两线制(SDA数据线…

2026/7/23 17:02:02 阅读更多 →
AI回答采集API调用:指数退避+熔断+降级重试机制实现

AI回答采集API调用:指数退避+熔断+降级重试机制实现

文章简介:在构建AI回答采集系统时,调用多个大模型API(如OpenAI、国产模型)经常遇到超时、429限流、5xx错误。本文从工程实践出发,设计一套包含指数退避、熔断和降级的重试机制,并给出参数选择依据和可运行的…

2026/7/23 17:02:02 阅读更多 →
佳能万能清零软件+详细操作G1800 G2800 G3800 G4800 IP8780 IP7280 IX6880IX6780 MG3580 MG3680 TS5080 TS6080 TS6020亲测

佳能万能清零软件+详细操作G1800 G2800 G3800 G4800 IP8780 IP7280 IX6880IX6780 MG3580 MG3680 TS5080 TS6080 TS6020亲测

蓝奏云:点这里下载 密码:00 百度云:点这里下载 备用:pan.baidu.com/s/1gls2G4rqWWP-Mw-z6tVjnQ?pwd0000 常见型号如下: G1000、G1100、G1200、G1400、G1500、G1800、G1900、G1010、G1110、G1120、G1410、G1420、G1411、G151…

2026/7/23 17:02:01 阅读更多 →
BLE连接的时长拆解

BLE连接的时长拆解

客户反馈IOS手机APP添加设备的时长比较久,需要5S多,IOS 的 APP 添加设备,这个时候经典蓝牙已经连接成功,这个连接的步骤:BLE的连接 -> 通过BLE的数据交互 -> APP切换到卡片,这里主要是针对BLE连接过程…

2026/7/23 17:01:01 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 12:54:44 阅读更多 →

月新闻