一次多线程优化读取文件的实战

本文讲述了在处理大文件时遇到的内存溢出问题,从最初的全量读取到采用多线程分批读取的解决方案,再到最终通过线程同步限制并发数量以避免内存压力,逐步优化处理大文件的过程,实现了服务器资源的有效利用并提升了处理速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求描述:商户每天会定时将文件传到我们的sftp服务器,我们需要对文件解析落库等操作。

方案A:起初的设计是将文件下载到本地,读取整个文件,落库等一系列处理。

方案A的设计本来是没问题的,因为商户每天回传的文件不过5MB左右,程序运行了一年多时间,直到后来对接了一个新商户A,A回传的文件每天都在增长,有一天达到了200+MB,当程序将整个文件加载到内存时直接把CPU打满,最后内存溢出了,于是发现原先的方案已不适用,需要马上修改,此时引入了多线程,也就是方案B。

方案B:将文件下载后,不再一次性全部读取,而是分批读,读取一部分就将这一部分作为独立个体放到多线程里去处理。

方案B上线后,200MB文件处理很轻松,不再有内存溢出的情况,后续观察发现还有问题:随着文件增长,每天解析文件时服务器的CPU会越来越高,从100+MB到200MB,CPU使用率已经从34到了50,随着时间推移,很快又会出现之前的问题,多线程虽然可以不再一次性加载整个文件,但如果读取文件速度快,落库等操作慢时,还是存在很多数据同时加载到内存中,此时又想到了一个解决方案C。

方案C:问题还是文件过大导致的,多线程解析是正常的,那么怎么可以让文件尽量减少同时加载到内存的数量呢?想到是否可以让多线程处理数据时不要有太多队列等待,处理一部分再读取一部分,不要一直读取到结束,然后排队等待处理,也就是让多线程处理完前面的数据时再继续读取文件,此时引入了一个线程安全的类AtomicLong,每次开启一个多线程时,计数,保持正在运行的多线程数量不超过设置的最大值,当多线程到达最大值时,让主线程等待,直到多线程数量降低到最大值以下时再分配一个线程,多线程执行完再将数量减1。

方案C使用后,发现CPU不会一下飙高了,在等待时会降下来,读取时会涨上去,但也不会涨到之前那么高,而且处理的速度反而比之前更快了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值