国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Java千萬級別數(shù)據(jù)生成文件思路和優(yōu)化

開發(fā) 后端
程序剛開始設(shè)計的時候說的是最多百萬級別數(shù)據(jù),最多50W數(shù)據(jù)生成到一個xml文件里面去,所以在做測試的時候自己也只是造了100W的數(shù)據(jù)并沒有做過多數(shù)據(jù)量的測試,然后問題就來了....

一年前寫過一個百萬級別數(shù)據(jù)庫數(shù)據(jù)生成配置xml文件的程序,程序目的是用來把數(shù)據(jù)庫里面的數(shù)據(jù)生成xml文件.程序可以配置多少文件生成到一個文件中去。

程序剛開始設(shè)計的時候說的是最多百萬級別數(shù)據(jù),最多50W數(shù)據(jù)生成到一個xml文件里面去,所以在做測試的時候自己也只是造了100W的數(shù)據(jù)并沒有做過多數(shù)據(jù)量的測試,然后問題就來了....由于程序使用的局點數(shù)據(jù)量巨大,需要生成xml文件的客戶資料接近千萬級別的程度,而現(xiàn)場對程序的配置大約是100W條數(shù)據(jù)生成一個xml文件里面去,程序在這樣的大數(shù)據(jù)量下面偶爾會有崩潰。

最近幾天現(xiàn)場催的比較緊,最近抽空把這個問題處理了一下,在解決問題的過程中我把解決的步驟和方法記錄了下來,正好和大家共享一下。

 

現(xiàn)場提的問題概況:

數(shù)據(jù)量:生成xml,每個文件100W+ 條的數(shù)據(jù)

內(nèi)存控制:最好不要超過512M

問題詳情:在處理70W左右的時候內(nèi)存溢出

一、先來看一下程序要生成的xml文件的結(jié)構(gòu)

  1. <File>  
  2.   <FileType>1</FileType>  
  3.   <RType>12</RType>  
  4.   <Version>03</Version>  
  5.   <BNo>004</BNo>  
  6.   <FileQ>5</FileQ>  
  7.   <FNo>0006</FNo>  
  8.   <RecordNum>1000000</RecordNum>  
  9.   <!-- 上面是文件頭  下面是百萬個<RecordList>  -->  
  10.   <RecordList>  
  11.     <Msisdn>10350719507</Msisdn>  
  12.     <State>1</State>  
  13.     <StartDate>20110303</StartDate>  
  14.     <Date>20110419</Date>  
  15.     <Balance>45000</Balance>  
  16.   </RecordList>  
  17.    ...  <!-- 可能百萬個  <RecordList> 塊-->  
  18.  </File> 

二、給大家說一下如何把大數(shù)據(jù)生成xml文件

 

1、小數(shù)據(jù)量的情況下 < 1W條數(shù)據(jù)

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

優(yōu)點:api操作簡單,方便維護(hù)

缺點:數(shù)據(jù)量大的情況下太消耗內(nèi)存

2、大數(shù)據(jù)量生成一個xml文件(本程序采用的方法)

自己做的一個可以使用極少的內(nèi)存生成無限制大的xml文件框架由3部分生成xml文件

第一部分:生成文件頭

例如: xxx.toXML(Object obj, String fileName)

第二部分:通過每次向文件里面追加3000(可配置)條數(shù)據(jù)的形式生成文件塊

例如:xxx.appendXML(Object object); //object 可以是ArrayList 或者一個單獨的javaBean

第三部分:生成xml文件尾巴

例如:xxx.finishXML();

 

程序中的調(diào)用:調(diào)用xxx.toXML(Object obj, String fileName) 生成文件頭之后,可以循環(huán)從數(shù)據(jù)庫中讀取數(shù)據(jù)生成ArrayList,通過xxx.appendXML(Object object) 方法追加到xml文件里面,xxx.finishXML() 對文件進(jìn)行收尾

對框架說明:我上面提供的例子有文件頭 + 文件塊 + 文件尾巴. 如果和你們的實際使用文件不太一致的話,可以參考上面提供的思路修改一下即可,主要的方法是把相同的文件塊部分分離出來通過追加的形式寫入xml文件.

有了思路之后,大家可以嘗試著自己寫一個類似的大數(shù)據(jù)處理框架(千萬級別以上),如何有什么需要幫助的可以直接聯(lián)系我,因為是公司的程序,不太敢放出來,怕......

 

三、我是如何測試性能和優(yōu)化的

1、手動排除

根據(jù)文件崩潰時候的日志發(fā)現(xiàn)是在生成xml的框架里面報的錯誤,第一想到的是框架有些資源沒有釋放.于是把自己做的文件生成框架整體的排查了一遍,并且自己寫個簡單程序生成200萬條數(shù)據(jù),使用xml框架生成一個xml文件,整個生成過程中任務(wù)管理器(xp)查看程序?qū)?yīng)的java進(jìn)程使用的內(nèi)存基本在20M左右,因此排除框架的問題.懷疑是數(shù)據(jù)庫查詢和調(diào)用框架的部門出現(xiàn)問題.

檢測了一遍主程序的關(guān)鍵部分代碼,優(yōu)化了一下字符串處理.手動的釋放一些對象的內(nèi)存(例如:調(diào)用ArrayList.clear(),或者把對象置空等),分配512內(nèi)存后運行程序,60萬數(shù)據(jù)的時候內(nèi)存溢出,因為能主動釋放的對象都已經(jīng)釋放掉了,還是沒有解決,果斷放棄看代碼,準(zhǔn)備使用JProfile進(jìn)行內(nèi)存檢測.

2、手動排除沒有解決,借助內(nèi)存分析工具JProfile進(jìn)行排除

通過在數(shù)據(jù)庫中生成300W條數(shù)據(jù),在JProfile上面多跑程序,一邊運行,一邊調(diào)用JProfile 提供的執(zhí)行GC按鈕主動運行垃圾回收,運行50W數(shù)據(jù)后,通過檢測中發(fā)現(xiàn) java.long.String[] 和 oracle.jdbc.driver.Binder[] 兩個對象的數(shù)目一直保持在自增狀態(tài),而且數(shù)目基本上差不多,對象數(shù)目 都在200W以上,由于java.long.String[]對象是需要依賴對象而存在的,因此斷定問題就出在oracle.jdbc.driver.Binder[]上面,由于改對象存在引用導(dǎo)致String[]不能正常回收.

 

3、通過在JProfile對象查看對象的管理

 

檢測到oracle.jdbc.driver.Binder 被 oracle.jdbc.driver.T4CPreparedStatement 引起,而T4CPreparedStatement正好是Oracle對jdbc OraclePreparedStatement的具體實現(xiàn),因此斷定是在數(shù)據(jù)庫處理方面出現(xiàn)的問題導(dǎo)致oracle.jdbc.driver.Binder對象不能正常釋放,通過再一次有目的的檢測代碼,排查jdbc數(shù)據(jù)查詢的問題,把問題的矛頭直至數(shù)據(jù)庫的批處理和事務(wù)處理.因此程序是每生成一個文件成功后,會把已經(jīng)處理的數(shù)據(jù)轉(zhuǎn)移到對應(yīng)的歷史表中進(jìn)行備份,而再個表操作的過程中使用了批處理和事務(wù),使用批處理主要是保證執(zhí)行速度,使用事務(wù)主要是保證同時成功和失敗。

4、又因此程序每次從數(shù)據(jù)庫中查詢3000條數(shù)據(jù)處理,所以準(zhǔn)備監(jiān)控oracle.jdbc.driver.Binder的對象數(shù)目是否和查詢次數(shù)對應(yīng).,通過在程序中Sysout輸出查詢次數(shù) + JProfile運行GC測試 Binder,數(shù)據(jù)匹配,證實是java在數(shù)據(jù)庫批處理的過程中有些問題.

5、專門把批處理代碼提取出來通過JProfile內(nèi)存分析.最終問題定位完畢.

 

原因如下:100W數(shù)據(jù)生成一個文件的過程中,等文件生成完畢之后才能把數(shù)據(jù)庫中的數(shù)據(jù)備份到歷史表中,這個時候才能進(jìn)行事務(wù)的提交,也就是執(zhí)行commit(), 并且刪除原表數(shù)據(jù),100W數(shù)據(jù)按照3000一批寫入文件,每批次只是通過 PreparedStatement.addBatch();加入到批次里面去,并沒有執(zhí)行PreparedStatement.executeBatch(),而是在commit()之前統(tǒng)一調(diào)用的PreparedStatement.executeBatch(),這樣的話PreparedStatement就會緩存100W條數(shù)據(jù)信息,造成了內(nèi)存溢出.

錯誤的方法如下:

  1. try{  
  2.             conn.setAutoCommit(false);  
  3.             pst = conn.prepareStatement(insertSql);  
  4.             pstDel = conn.prepareStatement(delSql);  
  5.             pstUpdate = conn.prepareStatement(sql);  
  6.             ...   
  7.             //totalSize = 100W數(shù)據(jù) / 3000一批次  
  8.             for (int i = 1; i <= totalSize; i++) {  
  9.                   
  10.                 client.appendXML(list);  
  11.                  
  12.             }  
  13.             // 錯誤的使用方法  
  14.             client.finishXML();  
  15.             pst.executeBatch();  
  16.             pstDel.executeBatch();  
  17.         }  
  18.          ...  
  19.         finally {  
  20.             try {  
  21.                 if (isError) {  
  22.                     conn.rollback();  
  23.                 }  
  24.                 else 
  25.                     conn.commit();  
  26.                ...  
  27.             }  
  28.           ...  
  29.         } 

正確的方法如下

  1. try{            
  2.   conn.setAutoCommit(false);  
  3.             pst = conn.prepareStatement(insertSql);  
  4.             pstDel = conn.prepareStatement(delSql);  
  5.             pstUpdate = conn.prepareStatement(sql);  
  6.             ...   
  7.             //totalSize = 100W數(shù)據(jù) / 3000一批次  
  8.             for (int i = 1; i <= totalSize; i++) {  
  9.                 list = 從數(shù)據(jù)庫中查詢3000條數(shù)據(jù)  
  10.                 client.appendXML(list);  
  11.  
  12.                pst.executeBatch();  
  13.                pstDel.executeBatch();  
  14.             }  
  15.             client.finishXML();  
  16.               
  17.         }  
  18.          ...  
  19.         finally {  
  20.             try {  
  21.                 if (isError) {  
  22.                     conn.rollback();  
  23.                 }  
  24.                 else 
  25.                     conn.commit();  
  26.                ...  
  27.             }  
  28.           ...  
  29.         } 

如果碰到和我一樣的需要給大家一個提醒。

oracle在每次執(zhí)行executeBatch();進(jìn)行批處理的時候,當(dāng)前connection對應(yīng)的rownum會根據(jù)操作的結(jié)果發(fā)生變化。

在執(zhí)行pst.executeBatch(); 之后,當(dāng)前連接的 rownum 數(shù)就會發(fā)生變化. 因此凡是通過rownum查詢數(shù)據(jù)的程序都要小心這一點

下一篇將整理寫java大數(shù)據(jù)(千萬級別以上的)處理,包括 ftp大數(shù)據(jù)處理、文件生成大數(shù)據(jù)處理、數(shù)據(jù)庫轉(zhuǎn)移大數(shù)據(jù)處理、文件讀取大數(shù)據(jù)處理等等。

原文鏈接:http://www.cnblogs.com/dyllove98/archive/2012/04/24/2468771.html

【編輯推薦】

  1. Java圖形界面開發(fā):高級Swing容器(一)
  2. Java圖形用戶界面:高級組件綜合例子
  3. Java程序員應(yīng)該遵循的10條戒律
  4. Java核心類庫:內(nèi)部類那點事兒
  5. 在Java程序中調(diào)用Matlab函數(shù)
責(zé)任編輯:林師授 來源: jlins的博客
相關(guān)推薦

2020-08-06 08:00:51

數(shù)據(jù)分頁優(yōu)化

2022-09-01 08:42:36

SQL數(shù)據(jù)項目

2024-02-05 13:28:00

Excel優(yōu)化服務(wù)器

2023-06-29 08:22:43

數(shù)據(jù)Excel模板

2023-02-24 16:37:04

MySQL數(shù)據(jù)查詢數(shù)據(jù)庫

2013-09-10 10:20:12

數(shù)據(jù)大數(shù)據(jù)大數(shù)據(jù)應(yīng)用

2020-09-01 17:19:36

數(shù)據(jù)監(jiān)控建模

2009-12-28 16:10:38

WPF生成文件

2023-12-07 07:46:21

MySQL寫入點LSN

2022-08-31 12:57:58

PythonTemplate文件報告

2019-05-22 15:57:11

面試ES性能數(shù)據(jù)

2012-03-01 15:06:58

2013-02-27 15:48:05

自動化備份FacebookPB級別數(shù)據(jù)庫

2012-08-06 14:02:09

萬國數(shù)據(jù)數(shù)據(jù)中心GDS

2022-07-05 21:31:21

索引SQL分庫分表

2018-07-11 20:07:06

數(shù)據(jù)庫MySQL索引優(yōu)化

2024-07-22 11:48:42

2011-11-08 13:46:44

靜態(tài)文件Nginx優(yōu)化

2020-07-08 13:46:25

Python數(shù)據(jù)分析預(yù)處理

2023-12-29 08:12:58

Explain索引SQL優(yōu)化
點贊
收藏

51CTO技術(shù)棧公眾號

国产精品a久久久久久| 久久综合色视频| 亚洲国产清纯| 欧美日韩国产综合在线| 久久三级视频| 9色视频在线观看| 成人美女在线视频| 精品999在线| 亚洲一二三区在线观看| 欧美女子与性| 91麻豆精品久久久久蜜臀| 欧美办公室脚交xxxx| 久久精品中文字幕一区| 欧美久久精品| 久久精品二区| 91啪亚洲精品| 可以在线观看的黄色| 亚洲国产福利在线| 97品白浆高清久久久久久| 国产区亚洲区欧美区| 视频一区在线播放| 国产欧美日韩小视频| 亚洲免费电影在线| 伦理av在线| 欧美亚洲伦理www| 欧美亚洲网站| 色婷婷综合网站| 欧美三级电影在线观看| 欧美性xxx| 国产精品96久久久久久| 青娱乐精品视频| 成人福利视频在| 精品国产乱码久久久久久1区2区| 精品久久ai电影| 欧美日韩精品免费看| 久久午夜免费电影| 黄网页免费在线观看| 久久久久久久av| 久久亚洲国产精品一区二区| 自拍偷拍21p| 亚洲国产一区二区三区在线观看| 网曝91综合精品门事件在线| 制服国产精品| 精品成人国产在线观看男人呻吟| 日本免费一区二区三区四区| 国产视频观看一区| 成人av在线电影| 免费高清完整在线观看| 91精品国产免费久久久久久| 美腿丝袜在线亚洲一区| 在线观看黄网| 欧美成人午夜免费视在线看片| 一本久道综合久久精品| 69中国xxxxxxxxx69| 亚洲一级一级97网| 亚洲欧洲一级| 麻豆电影传媒二区| 色黄久久久久久| 日本欧美一区二区| 四虎成人免费在线| 国产91精品黑色丝袜高跟鞋| 国产福利一区二区三区视频在线 | 国产精品国模在线| 国产精品一区在线观看乱码| 91xxx在线观看| 欧美孕妇毛茸茸xxxx| 成人黄色777网| 中文字幕在线播放网址| 国产精品扒开腿做爽爽爽男男| a在线播放不卡| 成人女同在线观看| 精品午夜一区二区| 色天天综合色天天久久| 国产一区不卡| wwwav91| 欧美国产中文字幕| 99精品一区二区| 天天免费亚洲黑人免费| 日本中文不卡| 欧美一区二区三区在线视频| 国产在线欧美| 久蕉在线视频| www.日韩大片| 欧美成人视屏| 国产日韩二区| 欧美亚洲愉拍一区二区| 首页国产精品| 在线视频色在线| 热re99久久精品国产66热| 国产精品网站在线观看| 国产麻豆一区二区三区| 少妇性饥渴无码a区免费| 日韩中文在线视频| 国产91综合一区在线观看| 欧美特黄aaaaaaaa大片| 香蕉视频在线网址| 亚洲精品一区二区在线| 国产一区二区三区久久悠悠色av| 国产传媒在线观看| 成人在线免费观看网址| 亚洲男人天堂2024| 成人免费视频国产在线观看| 欧美视频在线视频精品| 欧美牲交a欧美牲交aⅴ免费真| 久久天天躁日日躁| 亚洲国产精品ⅴa在线观看| 久久aimee| 亚洲色图图片网| 精品国产一区二区三| 日韩欧美国产一二三区| 韩国欧美国产一区| 日韩一区中文| 四虎影视av| 92看片淫黄大片看国产片| 91久久国产最好的精华液| 亚洲国产二区| 1024在线看片你懂得| 人体内射精一区二区三区| 久久av红桃一区二区小说| 亚洲欧美综合在线精品| 精品一区电影| 1769在线观看| 日韩在线电影一区| 综合激情国产一区| 亚洲免费电影在线| 欧美成人有码| 波多野结衣在线观看| 香港三级韩国三级日本三级| 日本一欧美一欧美一亚洲视频| 日本久久一区二区三区| 久久er精品视频| xvideos.蜜桃一区二区| 亚洲美女电影在线| 一区二区三区在线观看www| 欧美成人手机在线| 欧美日韩午夜视频在线观看| 日韩和欧美一区二区| 国产精品国产亚洲精品| 一区二区三区不卡在线视频| 日本在线成人| 欧美福利一区二区| 国产精品99久久久久久久vr| 风间由美性色一区二区三区四区 | 亚洲日日夜夜| 中文在线有码| 亚洲日本精品一区| 欧美巨大黑人极品精男| 日韩高清一区| 国产原创av在线| 久久这里只有精品8| 国产精品99导航| 日韩免费看网站| 欧美极品另类videosde| 亚洲二区视频| 欧美黄视频在线观看| 免费国产在线观看| 国产99久久九九精品无码| 99re视频在线观看| 久久精品国产亚洲7777| 日韩欧美高清在线视频| 精品亚洲成av人在线观看| 欧美毛片免费观看| gogo久久| 伪装者在线观看完整版免费| 欧美一级爱爱视频| 7777精品久久久大香线蕉小说| 中文字幕亚洲自拍| 欧美中文字幕一区二区三区亚洲| 久久久噜噜噜久久中文字幕色伊伊| 亚洲黄色av| 三级小说欧洲区亚洲区| 欧美裸体视频| 国产在线视频福利| 日本不卡一区在线| 男人的天堂视频在线| 国产激情一区二区三区在线观看 | 日韩免费成人| 99热国产在线| 原千岁中文字幕| 欧美黑人经典片免费观看| 久久精品欧美| 国产精品h片在线播放| 色妞久久福利网| 欧美videos中文字幕| 色愁久久久久久| 青春草在线视频| 日韩偷拍自拍| 欧美女同在线观看| 精品丰满人妻无套内射| 久久国产精品 国产精品| 国产精品av网站| 久久亚洲精品视频| 日韩欧美国产一二三区| 欧美日韩国产精品一区二区不卡中文 | 日韩a一区二区| 国产精品一区二区美女视频免费看 | 欧美黑人xxx| 亚洲第一av网| 91精品国产色综合久久ai换脸| 午夜视频久久久久久|