专业网盘中大文件夹移动、复制问题解决实践

背景:

为了方便客户,增加客户粘性,公司设计了一套某行业专用的网盘系统,主要保存图片素材,设计文件。
某些头部客户一个月就有上万个文件,某行业第一在系统迁移的时候一次性导入了15T的各类素材。
随着数据量增加,大文件夹的移动、复制异常逐步暴露出来,由于是和行业应用深度绑定,我们的网盘不仅保存文件的基本信息(文件名、文件父子关系)还有文件目录权限、文件特性等业务信息。方便客户在网盘中使用自己保存的文件。

文件移动发生OOM

某日系统报警,发现生产环境某个节点频繁重启,同事前方客服传来消息,某个重量级客户在操作文件夹复制的时候莫名报错了,赶紧找运维拿了dump文件,经过分析果然是OOM了,在文件移动的逻辑中,所有文件信息都被读进去内存,某个结果Result Lsit 中持续写入需要移动的文件信息,导致jvm 出现了OOM ,同时docker 容器重启。

定位问题之后分析文件移动逻辑,发现复制也是如此

而且复制还更复杂。

文件移动

网盘的文件移动其实很简单,抛去文件的权限、深度等信息,只要要移动的文件父节点和子节点关系更新掉就好,由于我们的网盘深度绑定了业务,导致需要诸暨递归更新所有的文件信息,包含权限、深度,同时移动的时候做了目录深度、广度、重名等逻辑处理,这就导致内存中90% 的信息其实和文件移动逻辑没关系,由于文件的ID 查找走了ES,所有在遍历 LIST ids 从MySQL 数据库中批量拿文件详情的时候oom。

这个时候我便整理好思路,文件移动逻辑只是处理文件移动相关的信息,文件特征信息不读到内存,这样正在递归处理文件树的时候,只需要把移动后的文件权限、深度等信息更新到MySQL 数据 之后同步到ES 即可。

这个方案评审之后,我便交给一个组员开始实现。其中我还写好了主流程。

文件复制

文件复制比较复杂的是 我需要把文件特征值也复制一份,这样的话就避免不了内存过大,同事文件数量多的时候 比如10万 就有一个过程,就像平时windows 系统内的文件夹 复制 、剪切,其实剪切的时候我们都不会进行操作,只是硬盘中数据移动,如果是是复制,windows 的策略是不锁定被复制对象,你可以继续操作被复制对象,如果你在编辑一个Word 复制过程会提示 是否跳过或者你关掉Word 编辑器,继续复制。

我们系统产品都没想到会有这个过程,所以给了一个临时方案 限制复制数量,保证一次性复制成功。

文件移动的改造

由于测试环境数据量不大,所以测试一切顺利,上了灰度,可以操作用户生产数据了,结果炸了,文件移动时候超过2000 马上内存主键升高,直到docker 容器重启。

查看监测数据,发现

1.移动的时候 网络IO 陡升,从50k 到了50mb。
2.CPU 持续高位利用率 疯狂的计算直到容器被重启
3.内存迅速升高直到容器重启
4.一分钟内产生大量日志文件,被分段策略分出很多压缩日志。

问题定位

由于业务逻辑日志打印了从ES 查询的返回结果,发现日志刷屏了,公司的发布系统性能一般,根部看不了大日志,根据关键字筛选,发现Es 返回了数据,并未数据超过2000个文件。

接着怀疑是Java 内存泄露,但看了代码发现根本没执行到很多逻辑,打印ES 返回的数据之后 日志就没了,范围缩小到了调用ES 返回结果的前后,接着看日志,发现请求ES 的参数有问题,这之前根本没想到这种分页参数会有问题

上代码

 try<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值