物流IT控: (java POI) WMS大資料BOM匯入最佳化
故事起因:一個WMS系統,需要定期更新從SAP匯入BOM表資料Excel檔案,資料比較多,共4萬多條,2。7M。在伺服器直接開啟時直接OutOfMemory(記憶體溢位),急需最佳化。
Ray: 好啊好啊,讓我來分析一下先。。。
問題分析
起因說了,我這邊給客戶開發的一個WMS系統,需要定期更新從SAP系統匯入BOM表資料Excel檔案,資料比較多,共4萬多條,2。7M。伺服器是1核1G記憶體,後臺是java,用的POI處理Excel(xlsx),只要使用者一選檔案匯入就OutOfMemory(記憶體溢位)。
當時臨時解決方案是:用開發員的機器(8G記憶體)連PROD資料庫去導資料,因為記憶體夠大,所以沒有爆掉,但是速度非常慢,導一次需要大概十幾分鍾。
據此判斷就是記憶體問題,理論上加大記憶體就行啦,但是這個解決方案不是一個適合的方案。雖然解決了OOM問題,速度問題仍舊是個大患。
java問題程式碼
XSSFWorkbook一次過裝載幾萬條資料到記憶體中肯定會有問題,應該是按行或分批放進記憶體處理,這個才是能一勞永逸解決問題的方案。
尋找答案
在Google中尋找java read big excel file oom,非常快的找到了一些靠譜的答案,都指向了需要用到POI的新API。請不要使用百度(不解釋)。
點選XSSF進行檢視
案例測試
按照官方的例子改造來開啟我的BOM excel, 首先我得重現錯誤,於是把eclipse VM 調整到256M,使用舊程式碼匯入檔案。
重現了OOM錯誤
新程式碼改造, 官方程式碼地址:
https://
svn。apache。org/repos/as
f/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV。java
我改造的地方
改造後再次匯入,耗時22秒,雖然時間還是有點稍長,但比起以前十幾分鍾已足夠好,證明方案改造OK了!
結論
我使用了當前(2017-06)POI最新的3。16版本中的XSSF and SAX (Event API),暫不確定這個Event API是否是把Excel逐行放進記憶體處理的,但已經保證了在低記憶體(-Xmx256M)的情況下不會發生OOM錯誤。
學海無涯,在學習的道路上,你並不孤單,希望本文可以幫助到相關的人,我是物流IT人,劉宇,謝謝,再見。