秒杀系统总结与思考(四) 流量削峰

本文探讨了秒杀场景中流量削峰的重要性和实现方法。通过排队、答题及分层过滤等策略,有效延缓和过滤无效请求,确保服务器稳定运行并节省资源。详细介绍了答题模块的设计与应用,以及请求的分层校验流程。
什么是流量削峰

秒杀这一场景,削峰的本质是更多的延缓用户请求的发出,以便减少和过滤一些无效的请求,遵从“请求数尽量少”的原则

为什么要用

削峰的存在,一是可以让服务器端处理变的更加平稳,二是节省服务器资源成本。

实现思路

排队、答题、分层过滤

排队

1、利用线程池加锁等待
2、先进先出、仅仅后出等常用的内存排队算法
3、请求序列化文件,然后再顺序读文件恢复请求

答题

作用: 1、防作弊。2、延缓请求
在这里插入图片描述
答题模块三部分
1、题库生成,重要防止机器算出结果
2、题库推送模块,秒杀答题前,把题目提前推送给详情和交易。题库推送目的是为了保证每次用户请求的题目是唯一,目的也是防止答题作弊
3、题目图片生成模块,生成图片增加干扰因素,同样防止机器。答题应该将题目图片提前推送到CDN进行预热。

答案验证逻辑

在这里插入图片描述
用户提交答案和题目答案比较,如果验证通过就继续下一步下单逻辑,否则就失败。将问题和答案用下面key来进行MD5加密:
· 问题key: user + itemId + question_id + time + pk
· 答案key: userId + itemId + answer + pk

还需要注意的:
除了验证答案,还要验证用户本身信息(是否登录,cookie是否完整等)
对提交答案时间做出限制,超过1s的可能是机器答题

分层过滤: 过滤无效请求

分层校验的基本原则: (每一步都做库存校验,不做强一致性要求,写操作时再做强一致校验)
1、将动态请求的读数据缓存(cache)在Web端,过滤无效数据读
2、对数据不坐强一致性校验,减少一致性校验产生的瓶颈
3、对数据进行基于时间的合理分片,过滤过期失效请求
4、对写请求做限流保护,将超出系统承载能力的请求过滤
5、对数据进行强一致性校验,只保留最后有效数据。

<think>我们正在讨论的是黑马点评优惠券秒杀系统中的异步队列技术,特别是将数据库写入从同步改为异步的含义。 根据引用[1]和引用[3],我们知道异步处理是提升系统性能的重要手段,而消息队列(如RabbitMQ)在其中扮演关键角色。 用户要求详细解释“将数据库写入从同步改为异步”在异步队列中的含义。 思考过程: 1. 同步写入数据库:在高并发场景下,每个用户请求都会直接操作数据库(如创建订单、更新库存),导致数据库压力巨大,响应时间变长,甚至崩溃。 2. 异步队列:引入消息队列(如RabbitMQ)作为缓冲,将用户请求先存入队列,然后由后台消费者异步地从队列中取出请求并写入数据库。 3. 这样做的好处是将高并发的请求值“平”,变成平稳的数据库写入操作,避免数据库被瞬间高并发压垮。 具体步骤: - 用户请求到达后,系统通过Redis+Lua脚本进行库存校验和用户校验(原子操作)。 - 校验通过后,不直接操作数据库,而是将订单信息发送到消息队列(如RabbitMQ)中,然后立即返回用户“抢购中”等提示。 - 后台有多个消费者进程(或线程)监听消息队列,按照自己的处理能力从队列中取出消息,然后执行数据库写入(创建订单、更新库存等)。 优势: - 填谷:将瞬间的高并发请求积压在队列中,然后由消费者按照数据库能够承受的并发量逐步处理,避免数据库被冲垮。 - 异步解耦:用户请求处理和数据库写入两个环节解耦,即使数据库暂时出现性能问题,也不会直接影响用户请求的响应。 - 提高系统响应速度:用户请求只需要经过Redis校验和消息队列发送,耗时很短(通常小于50ms),用户体验更好。 引用支持: - 引用[1]提到:“填谷是消息队列最主要的作用,但是会造成请求处理的延迟。” - 引用[3]提到:“RabbitMQ 是解决数据库高并发问题的利器,通过异步化、解耦和流量三大核心机制保护数据库。” 因此,将数据库写入从同步改为异步,就是通过消息队列将实时数据库操作转换为异步操作,从而保护数据库,提升系统整体并发能力。 接下来,我们按照要求组织答案,包括数学表达(如果需要)和代码示例(如果有),并生成相关问题。 </think>### 异步队列:数据库写入从同步到异步的深度解析 #### 一、**同步写入 vs 异步写入的本质区别** 1. **同步写入模式**: $$T_{\text{响应}} = T_{\text{校验}} + T_{\text{DB写入}} + T_{\text{网络}}$$ - 用户请求线程必须**阻塞等待**数据库完成事务 - 数据库连接池快速耗尽(如:500并发 → 500个活跃连接) - 典型瓶颈:MySQL写操作耗时 $\propto$ $\frac{1}{\text{IOPS}}$ 2. **异步写入模式**: $$ \begin{cases} T_{\text{响应}} &≈ T_{\text{校验}} \\ T_{\text{处理}} &= T_{\text{入队}} + T_{\text{DB批量写}} \end{cases} $$ - 用户请求线程**立即释放**(仅需完成校验) - 数据库操作由**独立消费者线程**异步执行 #### 二、**异步队列的实现架构** ```mermaid graph LR A[用户请求] --> B[Redis原子校验] B -->|校验通过| C[写入消息队列] C --> D{消费者集群} D --> E[批量合并操作] E --> F[数据库批量写入] ``` 关键组件作用: 1. **消息队列**(如RabbitMQ/Kafka): - 作为**缓冲层**承接瞬时流量(如:10万请求/秒) - 消息积压公式:$Q_{\text{积压}} = \lambda - \mu$ ($\lambda$=生产速率,$\mu$=消费速率)[^1] 2. **消费者集群**: ```java // 伪代码示例:批量写入消费者 @RabbitListener(queues = "order_queue") public void handleBatch(List<Order> orders) { // 1.合并操作(减少事务次数) orderService.batchInsert(orders); // 批量INSERT stockService.batchDeduct(orders); // 批量UPDATE // 2.提交速率控制(根据DB能力调节) Thread.sleep(10); // 动态延迟 } ``` #### 三、**技术优势详解** | **维度** | **同步写入** | **异步写入** | **提升效果** | |----------------|------------------------------|------------------------------|--------------------------| | 响应时间 | 200ms~2s | **5~50ms** | 降低10~40倍 | | 数据库连接占用 | 1请求=1连接 | 100请求≈1连接 | 连接池需求**减少99%** | | 吞吐量 | MySQL单机≤500 TPS | **≥5000 TPS** | 提升10倍[^3] | | 系统稳定性 | 突发流量直接冲击DB | 流量平滑写入(填谷) | 崩溃风险**下降90%** | | 资源利用率 | 请求线程大量时间等待DB | 线程快速释放,CPU利用率↑ | 服务器成本**降低60%** | #### 、**异步写入的数学优化原理** 1. **合并写操作**: - 同步写入次数:$N_{\text{sync}} = R_{\text{请求}}$ - 异步写入次数:$N_{\text{async}} = \frac{R_{\text{请求}}}{\text{BatchSize}}$ - 磁盘I/O优化比:$\eta = 1 - \frac{1}{\text{BatchSize}}$ (当BatchSize=100时,$\eta$=99%) 2. **吞吐量模型**: $$ \text{最大吞吐量} = \min \left( \begin{array}{c} \text{消息队列堆积能力} \\ \text{消费者处理能力} \\ \text{数据库写入上限} \end{array} \right) $$ - 通过动态调节消费者数量实现弹性扩容 #### 五、**典型应用场景** 1. **秒杀值场景**: - 同步模式:1万并发 → 数据库崩溃 - 异步模式: ```mermaid flowchart TB 1万请求 --> 队列积压9000 队列 --> 消费者按1000TPS处理 消费者 --> DB稳定写入 ``` 2. **数据一致性保障**: - 通过**幂等设计**防止重复消费: ```sql CREATE TABLE orders ( id BIGINT PRIMARY KEY, user_id BIGINT, voucher_id BIGINT, UNIQUE KEY uk_user_voucher (user_id, voucher_id) -- 唯一约束防重 ); ``` #### 六、**注意事项** 1. **延迟可见性**: - 订单创建到可见延迟:$T_{\text{delay}} \approx \frac{\text{QueueSize}}{\text{ConsumerTPS}}$ - 需前端提示“订单处理中” 2. **故障恢复机制**: - 死信队列存储失败消息 - 定时任务补偿处理 ### 总结 将数据库写入从同步改为异步的核心价值在于: 1. **填谷**:通过消息队列承接流量,保护数据库[^1] 2. **资源解耦**:请求处理数据持久化分离,提升系统弹性[^3] 3. **批量优化**:合并写操作,磁盘I/O效率提升99%[^4] 这种设计使系统在高并发场景下保持高性能稳定性,是秒杀系统的核心架构思想。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值