关于cachedrowset在实际项目中的应用

1.问题的产生原因

    由于项目需求原因,需要实现一个功能就是,抽取大量的数据库数据然后写入文本并打包上传。看似一个很简单的东西,在大数据量的环境下就显得不是那么简单了。首先有60张左右的表需要进行数据的处理。各个公司情况不同,表的总数据量可能是几千万到几十亿不等。所以,耗时非常严重。

2.问题解决过程

    由于只是单纯的进行数据的提取加工写入文本打包等操作,不涉及表与表之间的业务逻辑。那么,大家下意识的的想到的就是多线程了。同样,我们也是用多线程进行第一步的数据处理。在这第一步就遇到了一个小坑,没有用线程池进行处理。并且业务逻辑方面也要做到主线程在等待所有子线程处理完毕之后在进行处理。线程有个方法就是join()方法,单纯的以为将所有的线程的join()方法连到一起就可以做到主线程等待所有子线程处理完毕之后再进行处理。巴特,还是太年轻在测试的时候就发现,这种方法做不到我们要求的效果。在经过查询搜集资料之后发现ExecutorService pool=Executors.newFixedThreadPool(threadNumber);一个固定线程池数量的线程池可以实现我们的要求。
//关闭线程池
			pool.shutdown();
			 try  
			 {  
			 // awaitTermination返回false即超时会继续循环,返回true即线程池中的线程执行完成主线程跳出循环往下执行,每隔10秒循环一次  
			 while (!pool.awaitTermination(10, TimeUnit.SECONDS));  
			 }  
			 catch (InterruptedException e)  
			 {  
			 e.printStackTrace();  
			 }  
在线程池关闭之后,该方法会一直进行检查直到所有的线程池中的线程都执行完毕才会继续主线程,从而实现我们的要求。
     将表之间进行拆分之后,第二步就是将每张表的数据进行查询并进行处理之后再写入文件。但是单张表的数据也太大了,开始我们循环rs.next();。将没次查询到的数据写入TXT并记录数据的大小,重而拆分写多个不同的文件。但是这个还是太慢了,因为所有的数据处理都是串行的太慢了。
    随后我们又做了,将所有数据封装了一个LIST并将返回的LIST拆分成十个小LIST写成多线程的方式进行处理,巴特,还是太年轻了。多线程中开多线程,导致程序中有几百个进程在跑,并且将内存中的放入了几十亿的数据。很抱歉,在某家公司进行测试的时候,64G的内存处理一般就内存溢出了……。所以该方案也不行。
    接下来,我们就在想有没有更高效的方法,不必将每张表的所以数据都复制进内存在进行处理。而是将按多少条进行查询处理。一个是手工分页查询进行处理。一个是加序列进行处理。还有就是cachedrowset的方法。

3.cachedrowset的使用

    cachedrowset 继承自ResultSet,它是将数据库的数据一次拷贝到内存中,并支持分页拷贝。在发现这个方案的时候才知道原来每次while(rs.next())都是与数据库的链接光标取下一行,原来自己的认知是将所有都加载到内存,看来还是自己太年轻了。cachedrowset是将数据复制到内存,它提供了一个分页方法setPageSize(size); 可以设置每页读取的数据数量并加载到内存,同理while(crs.nextpage()) 是取下一页。所以,我们将数据的逻辑放到了while里,不能直接将crs传入到多线程里进行处理,不然在进行字段数据获取的时候会报错。cachedrowset.createCopy()这个方法可以帮我们复制一份这个对象。我们可以将这个对象传入到线程池中进行处理。哈哈,到这里是不是以为已经可以了。答案是否定的%>_<%
    在实际测试的时候发现,每次还是将数据全部复制到了内存。虽然线程池的线程个数有设置,但是循环每次crs.nextpage()会将复制后的对象放进内存中在放入线程池的队列中……。所以我们要在循环取数的时候判断线程池是否有空闲的在用crs.nextpage()取下一页的数据。这样就不会讲一个表的所有数据加载到内存了。这样内存中的数据量等于=线程数*每页数量+每页数量。这样就可以有效的将问题分解处理了。执行将数据查询和业务逻辑耦合了……

4.总结

通过这次问题的分析以及初步解决。感觉自己知道的东西还是有限。无论是自己的眼界和见解都还没用达到一个程序员应有的水平,对于不常用的东西还是知识储备不足。哦对了,cachedrowset的Statement要是可滚动的。欢迎各位可以有更好的方案,同时也随便告诉下我这个无知的萌新。


    
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值