文件的秒传、分片上传以及断点续传 || Redis缓存减轻数据库读写压力

实现文件的秒传、分片上传以及断点续传的功能。使用 Redis 缓存上传的文件分片信息减轻数据库读写压力,同时防止有人恶意攻击服务器导致服务器磁盘爆满无法提供服务。


🔍 详解:

1. 实现文件的秒传、分片上传以及断点续传功能
  • 秒传(Instant Upload)
    用户上传文件时,先计算文件的 MD5 值,如果该 MD5 对应的文件在服务器上已存在,则不再上传,直接生成文件引用,极大节省带宽和上传时间。

  • 分片上传(Chunk Upload)
    将大文件切分为若干小分片(chunks)逐个上传,提升大文件上传成功率,避免因一次性传输失败而重传整个文件。

  • 断点续传(Resume Upload)
    上传中断后,下次上传时从上次已上传的分片继续上传,而不是重新上传所有数据,提升用户体验并节省网络资源。


2. 使用 Redis 缓存上传的文件分片信息,减轻数据库读写压力
  • Redis 作为内存型数据库,用于临时记录每个用户上传的文件分片状态(如已上传的分片编号、大小等)。
  • 这样可以避免频繁读写 MySQL,从而提升系统性能,减少数据库压力。

示例:

Key: upload:{userId}:{fileMd5}
Field: chunkIndex1 => uploaded
Field: chunkIndex2 => uploaded
...

3. 防止有人恶意攻击服务器导致服务器磁盘爆满无法提供服务
  • 攻击方式:伪装成正常用户,不断上传分片但不合并,长时间占用磁盘空间。

  • 解决策略:

    • 使用 Redis + 延时任务(如 ZSet + Kafka)记录每个上传任务超时时间;
    • 若长时间未完成上传合并,则触发清理任务,删除临时分片 + 回收空间记录
    • 通过这种方式防止大量临时文件残留占满磁盘,确保服务可用性。

✅ 总结:

系统通过实现秒传、分片上传和断点续传提升上传效率与用户体验,并结合 Redis 缓存与延时任务机制,有效降低数据库压力并防御恶意上传行为,保障磁盘资源和系统稳定性。


文件的秒传、分片上传、断点续传


🧩 一、文件的秒传(Instant Upload / Fast Upload)

✅ 概念

“秒传”是指:当用户上传一个文件时,系统会判断该文件是否已经存在于服务器上。如果已存在,则无需真正上传文件内容,直接在数据库中为该用户创建一个引用关系,完成上传操作。

✅ 实现原理

  • 客户端在上传前计算该文件的 唯一哈希值(如 MD5 或 SHA256)

  • 将该哈希值发送给服务器。

  • 服务器查询该哈希是否已存在(已上传的文件表)。

    • 存在 → 秒传成功,仅做数据库记录,不传文件;
    • 不存在 → 继续正常的分片上传流程。

✅ 优点

  • 避免重复上传同一文件,节省带宽;
  • 提高上传速度,尤其是常用/热门文件。

🧩 二、分片上传(Chunked Upload)

✅ 概念

将大文件切成多个小块(分片),逐个上传。这种方式适用于不稳定的网络环境,可以容忍部分上传失败而不影响整体进度。

✅ 实现方式

  1. 客户端

    • 将文件按固定大小(如1MB)分片;
    • 每个分片附带文件总 MD5、分片序号、总分片数等元信息;
    • 分片逐个上传。
  2. 服务端

    • 接收每个分片,保存至临时目录;
    • 使用 Redis 缓存当前已上传的分片索引;
    • 等全部分片上传完毕后,合并成完整文件;
    • 写入正式存储路径,并清理 Redis 分片记录和临时文件。

✅ 优点

  • 降低失败重试代价;
  • 支持更大的文件上传;
  • 易于并发上传,提升性能。

🧩 三、断点续传(Resume Upload)

✅ 概念

在上传中断(如网络中断、浏览器关闭)后,用户再次上传该文件时,可以从中断的分片位置继续上传,而无需从头开始。

✅ 实现机制

  • 上传前,客户端向服务端查询该文件对应的已上传分片列表;
  • 服务端从 Redis 或数据库中查到已上传的分片序号;
  • 客户端只需上传未上传的分片;
  • 服务端补齐分片后继续合并文件。

✅ 核心点

  • Redis 缓存每个文件的上传状态(如:哪些分片已完成);
  • 分片文件统一保存到临时目录,命名规则中含有用户ID + 文件MD5 + 分片索引;
  • 定期清理长期未完成上传的临时分片,避免空间浪费。

✅ 优点

  • 提升用户体验,上传中断可恢复;
  • 适用于大文件和移动设备;
  • 减少带宽浪费。

✅ 总结对比表

功能核心作用关键技术点主要优势
秒传判断是否重复上传文件哈希(MD5、SHA256)节省带宽,极速上传
分片上传大文件分块分次上传客户端分片、服务端合并容错性强,适配弱网络环境
断点续传上传中断后断点恢复Redis 缓存、上传状态查询减少失败重传,提升用户体验

🎤 上传功能模块详解

在云盘项目中实现了上传模块,详细说一下你们是怎么处理大文件上传、断点续传、以及秒传的?

是的,这一块是我主导设计和实现的,我从三个方面来说:秒传、分片上传、断点续传,并介绍我们如何利用 Redis 减少数据库压力,同时避免恶意攻击 的问题。


✅ 第一,秒传功能

我们在用户上传文件前,会先计算整个文件的 MD5 值,然后将这个 MD5 发送到服务器。

  • 服务器会先查找该 MD5 是否存在于文件记录表中。
  • 如果存在,说明这个文件已经有人上传过了,我们就可以直接在数据库中记录一条文件引用关系,不需要再次上传文件。
  • 这样我们就实现了“秒传”——文件其实没上传,但用户看到已经上传成功。

这个功能的意义在于可以避免重复上传文件,节省带宽和服务器资源,特别是在多个用户之间共享同一文件的场景下非常高效。


✅ 第二,分片上传

对于大文件,我们采用的是 分片上传 的方式。

  • 客户端会把大文件按一定大小,比如1MB,切成多个分片;
  • 每个分片单独上传,并携带:文件 MD5、分片索引、总分片数等信息;
  • 服务端接收后,把分片暂存在临时目录中,文件名规则中会包含 用户ID+MD5+分片索引
  • 并把已上传的分片信息记录到 Redis,比如用一个 Set 结构标记当前文件已完成的分片列表;
  • 等所有分片都上传完成后,由后端合并这些分片,生成完整文件

这个机制带来的好处是:网络不稳定也能断点重试,每个分片都可单独上传,并行性高,效率也更高


✅ 第三,断点续传

断点续传是基于分片上传的扩展功能。

  • 当用户中断上传后(比如网络断了或浏览器关闭),再次上传这个文件时,前端会根据 文件MD5 + 用户ID 请求服务端查询已上传的分片索引;
  • 服务端从 Redis 里返回已上传的分片列表;
  • 客户端跳过这些分片,只上传剩下未完成的分片

这种方式能显著提升用户体验,尤其是大文件或上传中断的场景。


✅ Redis 在这里的作用

我们没有直接把每个分片信息写入数据库,而是使用 Redis 作为缓存层:

  • 一方面,降低数据库写入压力,避免频繁写入;
  • 另一方面,通过缓存控制上传行为,防止恶意攻击造成服务器硬盘爆满

比如:

  • 有人恶意频繁上传大文件的分片但不合并,正常流程不会增加用户空间;
  • 但这些临时分片文件会持续占用磁盘;
  • 我们会通过 Redis + 延时任务机制记录每个文件的上传状态,定期清理未完成的文件;
  • 并且维护 use_space_unfinished 这样一个字段,表示“未合并完成文件的总大小”,和 use_space_finished 分开存;
  • 系统判断磁盘是否超限,是通过这两个值之和。

✅ 总结

这三个上传功能是密切相关的:

  • 秒传:避免冗余传输;
  • 分片上传:支持大文件、容错性强;
  • 断点续传:中断后恢复,提升体验;
  • Redis 缓存:减压数据库 + 控制风险;
  • 同时我们后续结合了 Kafka 做延时任务调度,对未合并的分片进行智能清理,保证系统可持续运行。

✅ 面试官可能追问(你可以这样接)

面试官:如果 Redis 数据丢了怎么办?你怎么保证数据库和 Redis 最终一致?

你可以答:
我们每次上传分片时都会写 Redis,并通过 Kafka 发送异步消息,延迟执行任务时再将 未完成空间 写入数据库,从而保证最终一致性。即使 Redis 崩溃,Kafka 中的消息还能驱动后续数据写入,避免数据丢失。


如果 Redis 数据丢了怎么办?你怎么保证数据库和 Redis 最终一致?

❓问题背景

在文件上传过程中,为了提升性能,我们使用了 Redis 来缓存用户上传的文件分片信息(包括已上传的片段、未完成上传的总大小 use_space_unfinished 等),而不是直接频繁更新数据库
但问题是:Redis 是内存数据库,存在数据丢失的风险(如宕机、RDB/AOF未写入等)。
那么:Redis 挂了或者数据丢了,我们怎么保证数据库数据依然准确?系统还能恢复吗?


✅ 我们的设计目标:最终一致性

我们不是追求强一致性(强一致性下 Redis 就不能丢),而是保证 最终一致性

即使 Redis 崩溃,通过 Kafka 消息 + 定时任务重处理机制最终数据库的数据一定是正确的


🧠 核心思路:异步延时写数据库 + Kafka 兜底

✅ 1. 上传过程中,所有用户的 use_space_unfinished 信息先写入 Redis

  • 每上传一个分片:

    • Redis 记录该文件当前已上传的分片列表;
    • Redis 增加该用户的 use_space_unfinished
  • 每次更新 Redis 的同时,我们会将上传信息 作为消息发送到 Kafka 延时队列(或普通队列配合定时任务处理)。

✅ 2. Kafka 消费者异步更新 MySQL(延迟写入)

  • Kafka 的消息内容:{userId, fileMd5, 当前上传的分片大小, timestamp}
  • Kafka 消费者接收到消息后,经过一定延迟后,再写入 MySQL 中的 use_space_unfinished 字段
  • 此时系统就完成了一次异步更新:Redis 快速响应,Kafka 异步落库,性能与安全兼顾

💣 如果 Redis 崩溃了怎么办?

✔️ 情况1:短暂宕机,Kafka 尚未消费

  • Redis 挂了不影响 Kafka;
  • Kafka 中消息仍然存在;
  • 消费者重启后,Kafka 会自动重新投递未处理消息
  • 仍然可以补偿写入数据库;
  • 数据库数据不会丢,最终一致性得以保障。

✔️ 情况2:Redis 挂了、Kafka 也丢了?

  • Kafka 默认有消息持久化机制,消息不会轻易丢;

  • 如果真的同时丢(极端情况),我们可以:

    • 通过 定时扫描临时文件目录,判断哪些上传超时未合并;
    • 使用用户上传记录、文件碎片路径等重建上传记录;
    • 重算 use_space_unfinished 并写入 MySQL。
    • 这属于“容灾补偿机制”。

🧰 技术细节总结

技术点作用
Redis 缓存快速记录分片状态与用户未完成空间占用,避免频繁 DB IO
Kafka 异步通道保障数据写入流程的延迟解耦,实现数据持久化缓冲与补偿
MySQL 最终写入use_space_unfinished、分片记录最终落库,持久化核心数据
延迟任务机制清理超时未完成上传、维护空间一致性
幂等性处理Kafka 消费者必须幂等处理(如根据任务 ID 判重),避免重复写入

✅ 面试中回答:

我们通过 Redis 快速缓存上传状态,同时将每个上传分片的元信息异步发送到 Kafka。Kafka 消费者会延迟一段时间后将上传占用的未完成空间数据写入 MySQL,从而实现最终一致性。如果 Redis 崩溃了,我们仍能从 Kafka 补偿更新数据库,确保数据准确。同时我们有超时任务清理机制,能识别上传失败或中断的文件,避免资源泄露。这样做的好处是既降低了数据库压力,又提升了系统的容错能力和可恢复性。


如何使用 Redis 缓存上传的文件分片信息,从而减轻数据库的读写压力提升性能,并且防止磁盘资源被恶意攻击耗尽

✅ 一、问题背景

用户上传一个大文件(比如 1GB),我们会将它分成多个小的“分片”进行上传。例如:

文件A:共10个分片,每个分片10MB

如果每上传一个分片我们都去操作数据库:

  • 会产生大量频繁的 写请求(一次上传 = N 次写库);
  • MySQL 属于磁盘存储,写入开销大
  • 数据库本身的 QPS 很有限,很容易被打爆。

因此,我们需要一个中间层 —— Redis 缓存


✅ 二、Redis 缓存的核心作用

🧠 用 Redis 缓存上传状态(代替频繁写库)

在上传过程中:

  • 记录:当前已上传的分片编号;
  • 临时计算:该用户上传但尚未合并的文件空间(用于判断是否超限);
  • 状态标记:记录上传是否完成、是否需要合并、是否被取消等。

这些数据原本都应写入数据库,但 Redis 拥有:

  • 高速读写性能(QPS > 10万+)
  • 天然支持原子操作、集合管理(比如 Set/Zset)
  • 支持过期策略,可定期清理数据

因此用 Redis 做临时缓存,可以极大降低数据库负载。


✅ 三、Redis 的数据结构设计示意

以下是几个核心的缓存键设计:

Redis Key 名称类型作用
upload:{userId}:{fileMd5}:chunksSet当前已上传分片编号集合
upload:{userId}:{fileMd5}:sizeString已上传分片大小汇总(用于限制未完成空间)
user:{userId}:use_space_unfinishedString用户未完成上传所占空间
user:{userId}:use_space_totalString已完成上传文件所占空间

示例:

SADD upload:123:abcd1234:chunks 1 2 3
INCRBY user:123:use_space_unfinished 10485760  # +10MB

✅ 四、缓存 + 延迟写入数据库(最终一致)

使用 Redis 作为上传状态的实时缓存后,我们不立即更新数据库,而是采用 异步写入

  1. 每次上传一个分片 → 更新 Redis;
  2. 同时将信息发到 Kafka 延迟队列(或加入延迟任务);
  3. Kafka 消费者延时写入 MySQL(例如每 10 秒批量写);
  4. 上传完成时合并数据,正式更新数据库已用空间。

这样设计的优点是:

  • 上传体验流畅(Redis 快);
  • 数据库不被频繁写入;
  • 保障最终一致性,可靠补偿;

✅ 五、上传完成前如何防止磁盘打爆?

防攻击策略:

  • 每上传一个分片,就立刻在 Redis 中增加 user:xxx:use_space_unfinished;
  • 服务器校验:use_space_unfinished + use_space_total ≤ 用户最大限额
  • 如果超限则直接拒绝上传请求;
  • 定期扫描 Redis 和磁盘上的临时文件,清理过期未完成的上传记录。

✅ 总结一句话回答:

为了避免每个文件分片都写一次数据库,我们使用 Redis 缓存用户的上传状态、分片列表和未完成上传的总大小。这一方面提升了系统的处理吞吐量,减少了数据库压力,另一方面也能实时检测用户是否超额占用磁盘资源,防止恶意攻击。最终一致性则通过 Kafka 异步任务机制或定时任务补偿保证。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安全大模型智驱网络和数据安全效能跃迁

从2023年ChatGPT开始,网络安全行业就一直尝试和AI大模型来结合,解决网络安全的痛点,例如告警多,专家少,新的APT攻击层出不穷,已有的基于规则的防护手段失灵,如何使用大模型的泛化能力来提升对未…

Android S - 恢复部分应用安装

使用展锐提供的代码编译出来的固件&#xff0c;不包含DeskClock等应用。 之前也遇到过这个情况&#xff0c;只是时间太久忘记了&#xff0c;在这里再次记录&#xff01; frameworks/native/data/etc/android.app.remove.xml<?xml version"1.0" encoding"ut…

android 之 CALL

一、组件职责与定位 组件所在进程核心职责关键特性CallsManagerTelecom系统进程通话状态机核心&#xff1a;管理所有Call对象的生命周期&#xff08;创建、状态更新、销毁&#xff09;。监听Call状态变化并通知所有观察者&#xff08;如InCallController&#xff09;。通过mLi…

Swift 6 学习笔记(二)The Basics

这篇笔记也是同步 Swift 6 官方教程中的第二篇 《The Basics》&#xff0c;这篇博客中的大部分内容在第一篇中已经涉及&#xff0c;这篇可以被认为是基础类型的的补充篇&#xff0c;多了很多说明信息。 官方教学文档 《The Basics》&#xff1a; Swift 提供了许多基本数据类型…

【PHP】BC Math 函数参考表

BC Math 函数参考表: 函数名描述语法bcadd两个任意精度数字的加法bcadd($num1, $num2, [scale])bcsub两个任意精度数字的减法bcsub($num1, $num2, [scale])bcmul两个任意精度数字乘法bcmul($num1, $num2, [scale])bcdiv两个任意精度数字除法bcdiv($num1, $num2, [scale])bcmod…

C# TAP异步编程(Task/async/await)总结

C#中有个很好用的东西&#xff0c;TAP异步编程&#xff08;Task-based Asynchronous Pattern&#xff09;&#xff0c;是目前C#推荐的异步编程模型。它基于 System.Threading.Tasks.Task 和 async/await 关键字&#xff0c;旨在简化异步代码的编写、调试和维护。TAP 是现代 .NE…

达梦数据库(DM)用户名大小写处理规则

达梦数据库(DM)用户名大小写处理规则 达梦数据库对用户名的处理与PostgreSQL和Oracle有所不同&#xff0c;以下是相关说明&#xff1a; 一、基本规则 默认情况下&#xff1a;达梦数据库区分用户名大小写 创建的用户名会保留原始大小写格式连接时必须使用相同的大小写形式 …

黑马点评面试话术

文章目录 1.项目介绍2. 分布式登录功能2.1 讲讲登录的整个流程2.2 集群模式session下存储用户信息会有啥问题&#xff1f;2.3 为什么采用redis存储用户信息和验证码2.4 redis的存储格式怎么样的&#xff1f;2.5 为什么采用Hash结构存储用户信息2.6 为什么采用双拦截器&#xff…

MTK APEX测光系统中各变量具体的计算方式探究

目录 一、APEX测光系统介绍 二、MTK测光系统实例介绍 三、关于测光系统的一些疑问 一、APEX测光系统介绍 详细内容可以参考; AE(自动曝光)系统简介

K8S的基本概念

Kubernetes是一个开源的容器编排部署管理平台,用于管理云平台中多个主机上的容器化应用。Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署、规划、更新、维护的一种机制。 对应用开发者而言,可以把Kubernetes看成一个集群操作系统。Kubernetes…

NLP学习路线图(三十四): 命名实体识别(NER)

一、命名实体识别(NER)是什么? 命名实体识别(Named Entity Recognition, NER)是自然语言处理中的一项关键序列标注任务。其核心目标是从非结构化的文本中自动识别出特定类别的名词性短语,并将其归类到预定义的类别中。 核心目标:找到文本中提到的命名实体,并分类。 典…

大三自学笔记:探索Hyperlane框架的心路历程

## Day 1&#xff1a;初识 Hyperlane 在 GitHub 上发现了 Hyperlane 这个 Rust HTTP 框架&#xff0c;立刻被它的性能数据吸引。官方文档写着&#xff1a; > "hyperlane 是一个高性能且轻量级的 Rust HTTP 框架&#xff0c;设计目标是简化现代 Web 服务的开发&#xff…

Java大厂面试真题:谢飞机的技术挑战

Java大厂面试真题&#xff1a;谢飞机的技术挑战 场景一&#xff1a;电商场景 面试官&#xff1a;在电商项目中&#xff0c;我们通常需要处理大量的并发请求。请谈谈你对JVM调优的理解。 谢飞机&#xff1a;嗯&#xff0c;JVM调优主要是为了提高程序的性能和稳定性。比如&…

【Docker管理工具】安装容器管理工具Oxker

【Docker管理工具】安装Oxker容器管理工具 一、Oxker介绍1.1 Oxker简介1.2 Oxker功能1.3 Docker介绍 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Oxker镜像五、安装Oxke…

产品成本分析怎么做?从0到1搭建全生命周期分析框架!

目录 一、为什么要做产品全生命周期成本分析&#xff1f; 1.资源再分配 2.动态成本校准 3.战略决策支持 二、产品成本分析思路 1.建立全生命周期成本追踪 2.联动分析关键指标 3.定位问题产品线 4.资源效率四象限分配 三、产品成本分析指标 1.分投入成本&#xff1a;…

机器学习与深度学习20-数学优化

目录 前文回顾1.梯度下降的基本原理2.什么是损失函数&#xff1f;3.随机梯度下降和小批量梯度下降4.什么是学习率5.优化算法中的收敛性6.常用的数学优化算法 前文回顾 上一篇文章链接&#xff1a;地址 1.梯度下降的基本原理 梯度下降&#xff08;Gradient Descent&#xff0…

Photoshop 2025 性能配置全攻略:硬件选购与软件优化指南

一、硬件配置核心建议 根据Adobe官方要求及实测反馈&#xff0c;Photoshop 2025对硬件的需求侧重CPU、内存和存储&#xff0c;显卡需求相对宽松&#xff0c;但特定功能&#xff08;如AI滤镜、3D渲染&#xff09;需关注显卡性能。 硬件类别最低配置推荐配置&#xff08;流畅运…

华为云Flexus+DeepSeek征文 | 华为云ModelArts Studio快速上手:DeepSeek-R1-0528商用服务的开通与使用

华为云FlexusDeepSeek征文 | 华为云ModelArts Studio快速上手&#xff1a;DeepSeek-R1-0528商用服务的开通与使用 引言一、ModelArts Studio平台介绍华为云ModelArts Studio简介ModelArts Studio主要特点 二、开通DeepSeek-R1-0528商用服务访问ModelArts Studio控制台DeepSeek-…

day53 神经网络调参指南

目录 一、引言 二、权重初始化&#xff1a;为何如此重要&#xff1f; &#xff08;一&#xff09;随机种子&#xff1a;确保实验的可重复性 &#xff08;二&#xff09;权重初始化的重要性 1. 神经网络的对称性问题 2. 避免梯度消失和梯度爆炸 &#xff08;三&#xff0…

【大模型02---Megatron-LM】

文章目录 Megatron-LM数据并行模型并行张量并行流水线并行 3D并行 Megatron-LM Megatron是当前大模型训练时经常使用的一种分布式并行框架&#xff0c;它通过采用DP,TP,PP等来加速模型的训练&#xff0c;反正就是一个字&#xff0c;好。 大模型在训练的时候&#xff0c;显存占…