【鱼皮的打工日记】20220628
今天的工作也是相对轻松的,上午上线了一个脚本,并且和另外一个产品对了需求;其余的时间就是在优化之前开发的 BI 可视化系统。
之前这个系统存在一个偶现的问题,就是如果同时有多个用户查询数据量较大的图表时,JVM 内存就会打满。这个主要是因为 MyBatis 从数据库中每次查询出来的数据都是全量加载到内存中的,本来数据量就已经很大了,再加上用 HashMap 去存储,有很多对象本身的信息会占用额外的空间,所以一个查询的数据可能就由原本的 100 M 膨胀到 1 个 G。假如同时发起 6 个这样的查询,就会瞬间占用 6 个 G 的内存,而如果内存不够,JVM 就会发起 Full GC,导致程序暂时卡死(也叫 STW - stop the world)。
所以今天主要是在思考和调研解决这个问题的思路,有几种方式吧。第一种是想办法用其他数据结构代替 Map 来接受数据,比如用 List<?> + 数据索引表(用下标来取对应的数据库字段),但这种方法感觉比较难实现,毕竟底层的 JDBC 封装了太多东西了,数据库默认也是全量返回的数据。第二种方法是使用数据库的流式查询,即我们后台和数据库建立一个链接,后台分批去取数据库已经查询出来的数据,处理一波再取下一波,从而把本来的洪峰控制成了平稳的水流。之前直播带大家看过的 Easy Excel 表格处理库也有用到类似的思想,大家可以试着使用这种方法优化自己的程序。第三种方式就是自己把完整的查询拆分成多次分页查询,本质上也是分批,但是需要自己来编码实现分页(根据情况决定页面的大小、页面数、并发等),比较麻烦。目前我个人更倾向于第二种方案,但是还没有实施,等后面这个问题紧急程度比较高了,再去优化也来得及。
今天晚上下班后学习了一会儿 Nginx 进阶,然后就是剪视频,并且成功在 0 点的时候发布了出来,主要是分享我这段时间做大数据开发的一些心得感悟,应该也能帮助大家了解大数据开发的一些工作内容、选择方向。欢迎大家三连支持哈:https://www.bilibili.com/video/BV1Wv4y1u7fo,谢谢,大家晚安~
