百万级数据导入导出优化总结

1、 背景

大家在日常的开发中,excel导入导出是非常常见的需求,大部分公司因为业务量比较小,操作的数据量都是几千、几万,这个级别的数据量,我们采用apache的POI很轻松可以搞定,但如果遇到大型互联网公司动不动就百万级别的用户体量,POI就会出现各种各样的问题,比较常见的现象就是内存OOM或者导入导出耗时特别久无响应,很显然,POI在百万级别的数据量处理,已经不合适了。

2、痛点

1、导入百万级别数据(excel)到DB,有什么痛点呢?

  1. 一次加载百万级别数据到内存,发生OOM?

  2. 导入时百万级别数据存储到DB如果循环一条条插入,数据库链接不够用?

2、导出百万级别数据(DB)到excel,有什么痛点?

  1. 一次查询百万级别数据到内存,mybatis查询超时报错?

  2. 一次加载百万级别数据到内存,发生OOM?

  3. 百万级别数据导出到Excel,写到一个Sheet中,能打开,不卡爆?

  4. 百万级别数据导出到Excel中一行一行写入Excel,频繁io操作,CPU飙高?

3、业务操作高峰期,后台管理员频繁操作导入导出excel,这个时候系统很容易就会因为内存溢出挂掉了

3、解决方案

1、选用合适的excel开源处理框架

阿里的easyexcel

2、百万级别导入方案

  • 逐行解析excel数据,分批读取excel数据放到List, ist达到一定数据量持久化到DB,同时清空List列表数据;

  • 采用mybatis的foreach批量保存、mybatis-plus批量saveBatch法保存;

3、百万级别导出方案

  • 分批分页查询db数据到内存,比如一次查询5000条,分20次分批查询出来;

  • 每次加载指定大小的数据到内存,比如每次5000条,5000条批量写入到excel以后,清空当前List,释放内存;

  • 分多个sheet写入,每个sheet比如放20w,100百万数据放到5个sheet;

4、解决高峰期导入导出资源瓶颈

  • 从产品侧设计的时候,引导产品,将导入导出功能设计成异步,尽量不要同步等待,虽然牺牲了一点体验,但是长期看对系统的稳定非常重要(为了产品的体验,可以提供一个统一excel导入导出历史记录功能给产品或运营同学,支持查看对应的下载进度,可追溯),异步导入导出可参考这里

    Java注解实现异步导入与导出(一)

    Java注解实现异步导入与导出(二)

  • 前端导入导出按钮控制操作的频率,比如3分钟内不能频繁导入导出。

  • 后端导入导出采用MQ异步排队处理,防止把内存写爆,CPU打满。

  • 采用动态配置开关控制导入导出的数量,通过压测预估系统处理数据的阔值,导入导出超过闻值需要产品或运营发邮件申请,开发修改配置如果业务确实有超大数据量要求,超过闽值太多,引导产品或运营分批导入导出解决。

通过以上方法,能够有效的支撑百万级别的数据导入导出,而且系统的CPU、内存等核心指标不会出现明显波动。

你可能感兴趣的:(Java,mybatis,excel,学习,java)