前言
问题还是来源于实际项目。即席查询中,一次查询,返回大量数据会导致内存溢出问题。
问题原始方案
直接通过jdbc链接数据库,通过遍历ResultSet获取结果。示例代码:
问题:这样在大查询的情况下,会导致内存溢出。
优化方案1
减少应用服务器内存压力。将查询结果存储为hdfs文件,然后通过文件流式读取数据。
步骤
导出数据到hdfs中。
从hdfs获取查询
优点:减少应用服务器内存压力,避免了内存溢出OOM的风险。
缺点:需要增加hdfs登录过程(不方便对接第三方的数据源:需要处理不同安全认证登陆(ldap、kerberos等);hdfs的多结点备份,浪费很多存储;不建议小文件存储在hdfs中。
优化方案2
使用数据库内置的流式查询。示例代码:
核心代码分析
驱动中 api中指出,只有同时开启ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY,Integer.MIN_VALUE 三个条件才能实现流失处理。
优点:减少系统复杂度(相比第一种优化,减少了与hdfs系统交互过程);更加通用,对接其他数据库时,不需要关系上层系统的差异(如:集群认证方式等);流式方式是每次返回一个记录到内存,所以占用内存开销比较小,并且调用后会马上可以访问数据集的数据。
结语
性能问题,往往可以考虑是否可以通过流式编程来优化。
动动小手指,关注一下,是给予我最大的动力。
领取专属 10元无门槛券
私享最新 技术干货