一、场景:对于百万级别的excel数据的导入,如何优化?
导入的痛点:一次加载百万级别数据到内存,发生OOM
如果一条条循环插入,数据库链接不够用
导出的痛点:
一次查询百万条数据,mybatis查询超时报错
一次加载百万条数据到内存,发生OOM
写到一个Sheet中,打不开
一行一行的写入到Excel,频繁的io操作,CPU飙升
操作高峰期,系统容易内存溢出
二、解决方案
1、选用合适的excel开源处理框架阿里的 easyexcel
2、百万级别导入方案
- 逐行解析excel数据,分批读取excel数据放到list,list达到一定数据量持久化到DB,同时清空list列表数据
- 采用MyBatis的foreach批量保存、myBatis plus批量saveBatch方法保存、spring jadbcTemplate,不过记得配置连接池参数要加上 rewriteBatchedstatements=true
3、百万级别导出方案
- 分批分页查询db数据到内存,比如一次查询5000条,分20次分批查询出来
- 每次加载指定大小的数据到内存,比如每次5000条,5000条批量写入到excel以后,清空当前list,释放内存.分多个sheet写入,每个sheet比如放20w,100百万数据放到5个sheet
- 每次从数据库批量读取指定大小的数据写入到excel,比如每次5000条
4、解决高峰期导入导出资源瓶颈
、从产品侧设计的时候,引导产品,将导入导出功能设计成异步,尽量不要同步等待,虽然牺牲了一点体验,但是长期看对系统的稳定非常重要。(为了产品的体验,可以提供一个统一excel导入导出历史记录功能给产品或运营同学,支持查看对应的下载进度,可追溯)
.前端导入导出按钮控制操作的频率,比如10分钟内不能频繁导入导出。
.后端导入导出采用MQ异步排队处理,防止把内存写爆,CPU打满。
,采用动态配置开关控制导入导出的数量,通过压测预估系统处理数据的阈值默认配置一个,导入导出超过阈值需要产品或运营发邮件申请,开发修改配置,如果业务确实有超大数据量要求,超过阈值太多,引导产品或运营分批导入导出解决。