java千万级别数据处理Word格式文档下载.docx

上传人:b****6 文档编号:19909714 上传时间:2023-01-12 格式:DOCX 页数:11 大小:25.65KB
下载 相关 举报
java千万级别数据处理Word格式文档下载.docx_第1页
第1页 / 共11页
java千万级别数据处理Word格式文档下载.docx_第2页
第2页 / 共11页
java千万级别数据处理Word格式文档下载.docx_第3页
第3页 / 共11页
java千万级别数据处理Word格式文档下载.docx_第4页
第4页 / 共11页
java千万级别数据处理Word格式文档下载.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

java千万级别数据处理Word格式文档下载.docx

《java千万级别数据处理Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《java千万级别数据处理Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。

java千万级别数据处理Word格式文档下载.docx

BNo>

004<

/BNo>

6. 

FileQ>

5<

/FileQ>

7. 

FNo>

0006<

/FNo>

8. 

RecordNum>

1000000<

/RecordNum>

9. 

!

-- 

上面是文件头 

下面是百万个<

RecordList>

-->

10. 

11. 

Msisdn>

/Msisdn>

12. 

State>

/State>

13. 

StartDate>

20110303<

/StartDate>

14. 

Date>

20110419<

/Date>

15. 

Balance>

45000<

/Balance>

16. 

/RecordList>

17. 

... 

可能百万个 

块-->

18. 

/File>

二、给大家说一下如何把大数据生成xml文件

1、小数据量的情况下 

1W条数据

比较好用的方法是使用开源框架,比如XStream直接把javabean生成xml

优点:

api操作简单,方便维护

缺点:

数据量大的情况下太消耗内存

2、大数据量生成一个xml文件(本程序采用的方法)

自己做的一个可以使用极少的内存生成无限制大的xml文件框架由3部分生成xml文件

第一部分:

生成文件头 

例如:

xxx.toXML(Objectobj,StringfileName)

第二部分:

通过每次向文件里面追加3000(可配置)条数据的形式生成文件块 

xxx.appendXML(Objectobject);

//object可以是ArrayList或者一个单独的javaBean

第三部分:

生成xml文件尾巴 

例如:

xxx.finishXML();

程序中的调用:

调用xxx.toXML(Objectobj,StringfileName)生成文件头之后,可以循环从数据库中读取数据生成ArrayList,通过xxx.appendXML(Objectobject)方法追加到xml文件里面,xxx.finishXML()对文件进行收尾

对框架说明:

我上面提供的例子有文件头+文件块+文件尾巴.如果和你们的实际使用文件不太一致的话,可以参考上面提供的思路修改一下即可,主要的方法是把相同的文件块部分分离出来通过追加的形式写入xml文件.

有了思路之后,大家可以尝试着自己写一个类似的大数据处理框架(千万级别以上),如何有什么需要帮助的可以直接联系我,因为是公司的程序,不太敢放出来,怕......

三、我是如何测试性能和优化的

1、手动排除

根据文件崩溃时候的日志发现是在生成xml的框架里面报的错误,第一想到的是框架有些资源没有释放.于是把自己做的文件生成框架整体的排查了一遍,并且自己写个简单程序生成200万条数据,使用xml框架生成一个xml文件,整个生成过程中任务管理器(xp)查看程序对应的java进程使用的内存基本在20M左右,因此排除框架的问题.怀疑是数据库查询和调用框架的部门出现问题.

检测了一遍主程序的关键部分代码,优化了一下字符串处理.手动的释放一些对象的内存(例如:

调用ArrayList.clear(),或者把对象置空等),分配512内存后运行程序,60万数据的时候内存溢出,因为能主动释放的对象都已经释放掉了,还是没有解决,果断放弃看代码,准备使用JProfile进行内存检测.

2、手动排除没有解决,借助内存分析工具JProfile进行排除

通过在数据库中生成300W条数据,在JProfile上面多跑程序,一边运行,一边调用JProfile提供的执行GC按钮主动运行垃圾回收,运行50W数据后,通过检测中发现java.long.String[]和oracle.jdbc.driver.Binder[]两个对象的数目一直保持在自增状态,而且数目基本上差不多,对象数目都在200W以上,由于java.long.String[]对象是需要依赖对象而存在的,因此断定问题就出在oracle.jdbc.driver.Binder[]上面,由于改对象存在引用导致String[]不能正常回收.

3、通过在JProfile对象查看对象的管理

检测到oracle.jdbc.driver.Binder被oracle.jdbc.driver.T4CPreparedStatement引起,而T4CPreparedStatement正好是Oracle对jdbcOraclePreparedStatement的具体实现,因此断定是在数据库处理方面出现的问题导致oracle.jdbc.driver.Binder对象不能正常释放,通过再一次有目的的检测代码,排查jdbc数据查询的问题,把问题的矛头直至数据库的批处理和事务处理.因此程序是每生成一个文件成功后,会把已经处理的数据转移到对应的历史表中进行备份,而再个表操作的过程中使用了批处理和事务,使用批处理主要是保证执行速度,使用事务主要是保证同时成功和失败。

4、又因此程序每次从数据库中查询3000条数据处理,所以准备监控oracle.jdbc.driver.Binder的对象数目是否和查询次数对应.,通过在程序中Sysout输出查询次数+JProfile运行GC测试Binder,数据匹配,证实是java在数据库批处理的过程中有些问题.

5、专门把批处理代码提取出来通过JProfile内存分析.最终问题定位完毕.

原因如下:

100W数据生成一个文件的过程中,等文件生成完毕之后才能把数据库中的数据备份到历史表中,这个时候才能进行事务的提交,也就是执行commit(),并且删除原表数据,100W数据按照3000一批写入文件,每批次只是通过PreparedStatement.addBatch();

加入到批次里面去,并没有执行PreparedStatement.executeBatch(),而是在commit()之前统一调用的PreparedStatement.executeBatch(),这样的话PreparedStatement就会缓存100W条数据信息,造成了内存溢出.

错误的方法如下:

Java代码 

1.try{ 

conn.setAutoCommit(false);

pst 

conn.prepareStatement(insertSql);

pstDel 

conn.prepareStatement(delSql);

pstUpdate 

conn.prepareStatement(sql);

//totalSize 

100W数据 

3000一批次 

for 

(int 

1;

totalSize;

i++) 

client.appendXML(list);

// 

错误的使用方法 

client.finishXML();

pst.executeBatch();

pstDel.executeBatch();

19. 

finally 

20. 

try 

21. 

if 

(isError) 

22. 

conn.rollback();

23. 

24. 

else 

25. 

connmit();

26. 

27. 

28. 

29. 

正确的方法如下

try{

1. 

list 

从数据库中查询3000条数据 

17.... 

18.inally 

如果碰到和我一样的需要给大家一个提醒.

oracle在每次执行executeBatch();

进行批处理的时候,当前connection对应的rownum会根据操作的结果发生变化.

在执行pst.executeBatch();

之后,当前连接的rownum数就会发生变化.因此凡是通过rownum查询数据的程序都要小心这一点

java千万级别数据处理

(2)-千万级别FTP下载

∙Java开发经验

这个也是以前做过的一个程序,目的主要是去ftp主机(最多100左右)去取xx数据文件.

千万级别只是个概念,代表数据量等于千万或者大于千万的数据

本分享不牵扯分布式采集存储之类的.是在一台机器上处理数据,如果数据量很大很大的话,可以考虑分布式处理,如果以后我有这方面的经验,会与时分享的.

1、程序采用的ftp工具

2、千万级别ftp核心关键的部分--列目录到文件,只要是这块做好了,基本上性能就没有太大的问题了.

可以通过apache发送ftp命令"

NLST"

的方式列目录到文件中去

#ftp列目录执行的命令以环境变量的配置优先,不配置则使用默认的列目录方式NLST

1.# 

DS_LIST_CMD 

NLST 

2.public 

File 

sendCommandAndListToFile(String 

command,String 

localPathName) 

throws 

IOException 

return 

client.createFile(command, 

localPathName);

catch 

(IOException 

e) 

log.error(e);

throw 

new 

IOException("

the 

command 

"

+command 

+"

is 

incorrect"

);

当然应该还有其他形式的,大家可以自己研究一下

十万级别以上的数据量的话千万不要使用下面这种方式,如果用的话====找死

FTPFile[]dirList=client.listFiles();

3、分批次从文件中读取要下载的文件名. 

加载到内存中处理,或者读取一个文件名就下载一个文件,不要把所有的数据都加载到内存,如果很多的话会出问题

为啥要分批次?

因为是大数据量,如果有1000W条记录,列出来的目录文件的大小1G以上吧

4、文件下载的核心代码----关于文件的断点续传,获得ftp文件的大小和本地文件的大小进行判断,然后使用ftp提供的断点续传功能

下载文件一定要使用二进制的形式

client.enterLocalPassiveMode();

//设置为被动模式

ftpclient.binary();

//一定要使用二进制模式

1./** 

下载所需的文件并支持断点续传,下载后删除FTP文件,以免重复 

param 

pathName 

远程文件 

localPath 

本地文件 

registerFileName 

记录本文件名称目录 

size 

上传文件大小 

true 

下载与删除成功 

Exception 

*/ 

public 

boolean 

downLoad(String 

pathName, 

String 

localPath) 

flag 

false;

file 

File(localPath+"

.tmp"

//设置临时文件 

FileOutputStream 

out 

null;

try{ 

设置为被动模式 

client.setFileType(FTP.BINARY_FILE_TYPE);

//设置为二进制传输 

if(lff.getIsFileExists(file)){//判断本地文件是否存在,如果存在并且长度小于FTP文件的长度时断点续传;

返之新增 

long 

this.getSize(pathName);

localFileSize 

lff.getSize(file);

if(localFileSize 

>

size){ 

FileOutputStream(file,true);

client.setRestartOffset(localFileSize);

client.retrieveFile(new 

String(pathName.getBytes(),client.getControlEncoding()),out);

out.flush();

else{ 

FileOutputStream(file);

30. 

31. 

32. 

33. 

34. 

35. 

}catch(IOException 

e){ 

36. 

37. 

log.error("

download 

error 

38. 

e;

39. 

}finally{ 

40. 

41. 

if(null!

=out) 

42. 

out.close();

43. 

if(flag) 

44. 

lff.rename(file, 

localPath);

45. 

46. 

47. 

48. 

49. 

flag;

50. 

51. 

/** 

52. 

获取文件长度 

53. 

fileNamepath 

本机文件 

54. 

55. 

56. 

57. 

getSize(String 

fileNamepath) 

IOException{ 

58. 

FTPFile 

[] 

ftp 

client.listFiles(new 

String(fileNamepath.getBytes(),c

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1