1) 【一句话结论】核心是通过“限流-分片-异步”三阶段设计,分阶段控制资源,避免单点资源耗尽,同时保证高并发下的稳定性与可扩展性。
2) 【原理/概念讲解】老师口吻,解释关键概念:
- 并发控制:高并发场景下,服务器资源(CPU、内存、带宽)有限,若不控制,大量请求同时处理会导致资源耗尽。比如用“限流器”类似“交通警察”,控制每秒进入系统的请求数,防止“车流”过载。
- 存储分片:大视频上传时,将其拆分成多个小块(分片),分别上传到不同的存储节点(比如对象存储的多个分片或本地存储的不同目录)。这样每个分片的上传是独立的,可以并行处理,提升整体吞吐量。类比:把一个大包裹拆成小包裹,分别寄给不同快递点,提高运输效率。
- 异步处理:上传完成后,将后续处理(如转码、索引生成)放入异步任务队列(如Kafka、RabbitMQ),由独立的后台消费者处理。这样前端上传不阻塞,系统资源可以快速释放,应对下一波请求。
3) 【对比与适用场景】
| 策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|
| 限流方式 | 控制请求进入系统的速率 | 令牌桶(平滑速率)、漏桶(突发限制) | 高并发入口控制 | 需要前端配合,避免“绕过” |
| 存储分片 | 将大视频拆分为多个小块 | 并行上传,提高吞吐 | 大文件上传 | 需要分片合并逻辑,保证数据一致性 |
| 异步处理 | 上传后放入队列,后续异步 | 解耦前端与后端,资源释放 | 需要后续处理步骤(转码等) | 需要消息队列可靠性保障 |
4) 【示例】
伪代码示例(用户上传视频流程):
- 请求进入限流器(令牌桶,每秒10个令牌,每个请求消耗1个)。
- 限流通过后,调用分片上传逻辑:
- 将视频按固定大小(如10MB)切分为10个分片(分片1-10)。
- 并行发起10个上传请求,分别上传到对象存储的不同存储桶(或本地不同目录)。
- 所有分片上传完成后,将“视频上传完成”事件发送到消息队列(如Kafka)。
- 后台消费者(转码服务)从队列中获取事件,读取所有分片,合并为完整视频,进行转码、生成索引等操作。
5) 【面试口播版答案】
“面试官您好,针对高并发视频上传避免资源耗尽的问题,我的核心思路是通过‘限流-分片-异步’三阶段设计来分阶段控制资源。首先,在入口做限流,比如用令牌桶算法控制每秒进入系统的请求数,防止服务器被瞬间压垮。然后,对大视频进行分片上传,把一个大的视频拆成多个小块,分别上传到不同的存储节点,这样每个分片可以并行处理,提升整体吞吐量。最后,上传完成后,将后续处理(比如转码、索引生成)放入异步消息队列,由独立的后台服务异步处理,这样前端上传不阻塞,系统资源能快速释放,应对下一波请求。这样三阶段结合,既能保证高并发下的稳定性,又能避免资源耗尽。”
6) 【追问清单】
- 问题1:限流策略如何选择令牌桶还是漏桶?
回答要点:令牌桶适合需要平滑速率的场景,漏桶适合限制突发流量,根据业务需求(比如是否允许短时间流量激增)选择。
- 问题2:存储分片后如何保证数据一致性?
回答要点:上传前检查分片完整性(比如校验和),上传完成后合并分片并验证,或者使用对象存储的版本控制。
- 问题3:异步处理中如何保证消息不丢失?
回答要点:使用消息队列的持久化存储(如Kafka的持久化日志),并设置重试机制。
- 问题4:高并发下如何保证存储分片的负载均衡?
回答要点:根据存储节点的负载情况(如CPU、存储使用率)动态分配分片,或者使用负载均衡器(如Nginx)分发请求。
7) 【常见坑/雷区】
- 坑1:只做前端限流,后端无控制,导致后端资源耗尽。
雷区:限流需前后端配合,后端也要做限流。
- 坑2:存储分片粒度过大或过小。
雷区:粒度过大(如整个视频一个分片)无法并行,粒度过小(如1KB)增加网络开销和存储复杂度。
- 坑3:异步处理未考虑消息积压。
雷区:消息队列需扩容,或者设置消息堆积上限,避免消费者处理不过来导致队列爆炸。
- 坑4:未考虑网络波动导致分片上传失败。
雷区:需要重试机制,比如分片上传失败后重试,或者设置超时重传。
- 坑5:未考虑存储分片后的合并逻辑。
雷区:上传完成后需要合并分片,否则后续处理无法进行,需保证合并逻辑的可靠性。