主頁 > 知識庫 > 數據庫 > Oracle >

基于Oracle的大數據導入方案探索(2)

來源:中國IT實驗室 作者:佚名 發表于:2013-07-23 17:45  點擊:
這兩個分別是POI加載Excel文件方法和讀取文件行的數據的片段,從這里暴露出POI處理大數據EXCEL的問題所在。首先,是將EXCEL文件加載到XSSFSheet對象的一個過程需要消耗很多時間及內存資源,通過測試得 出,當EXCEL

這兩個分別是POI加載Excel文件方法和讀取文件行的數據的片段,從這里暴露出POI處理大數據EXCEL的問題所在。首先,是將EXCEL文件加載到XSSFSheet對象的一個過程需要消耗很多時間及內存資源,通過測試得 出,當EXCEL數據記錄在6萬以上,文件大小超過30M時,此處就會出現異常“JVM內存溢出”,原因就是在加載EXCEL文件時開銷太大了,即使我們 在啟動服務器時擴大JVM內存分配,這也只是治標不治本的方法;其次,在循環讀取EXCEL行數據時需要預先獲得EXCEL中總行數,而獲得總行數的方法 則是通過函數sheet.getLastRowNum() - sheet.getFirstRowNum()+ 1 實現,在此又出現了另一個問題,sheet.getLastRowNum()返回值是一個int類型的數據,其最大值只可能是65535,那么它又如何可 以計算出超過65535行記錄的行數呢?所以得出結論:對于大數據的讀取,不能采用POI讀取EXCEL的方式。  不采用EXCEL作為數據源文件,可以采用CSV文件代之。CSV是EXCEL可另存為的數據文件格式,其本質上是以逗號分隔的文本文件,因 此,對于此類文件的讀取,我們可以采用傳統IO讀取文件的形式,通過字符串分割獲得每個單元格數據,拼接到SQL里面,形成SQL的數組。
  第二步,多線程執行數據導入。
  第一步已經將SQL儲存到SQL的數組中,接下來就是利用多線程執行批量插入。此處實現需要將SQL執行類實現Runnable接口或者繼承 Thread類,在常量中設置批量插入的記錄數,當加載的SQL數據大小達到該數目時,系統就自動啟動一個線程執行該數組的批量數據導入。為了確保線程管 理的安全,我們需要定義一個最大線程數,當處于運行的線程數達到最大值時,新開啟的線程將利用wait()方法實現等待,等待有線程執行完畢后才開始執 行。如此調用,直到加載的數據記錄全部都已開始導入才停止線程的啟動,此時為了監控數據導入是否全部完成,我們會再新開啟一個后臺線程,設置為守護進程 setDaemon(true),該類線程特點是在所有線程結束后將自動結束,其用于收集每個導入線程的執行狀態,當所分配的所有線程狀態都不是 active時就表示數據導入完成。
  利用該方案實現的數據導入較單線程執行的批量數據導入效率提高多倍,從測試導入40萬數據結果來看,單線程批量導入耗時19分鐘,而基于多線程 的導入只用了5分鐘左右的時間。但從性能消耗上來看,多線程方案平均同時工作線程數為15個左右,CPU利用率高達90%,內存消耗約500M,對于服務 器本身已造成了一定的壓力,雖然在速度上提升了,其對于服務器的穩定性將造成安全隱患。
  此外,對于多線程工作效率的探索上也有一點心得。多線程的出現更多的是迎合多核處理技術的革新,在單CPU工作的主機上,多線程看起來貌似是多 個線程并發執行,但從操作系統的角度出發其仍然處于串行狀態,因為在同一時間,處理器只對一個任務進行調度,只不過是輪詢的時間間隙較短不容易發覺。如果 在多核處理的主機上,就會有多個處理器同時處理并發的線程,這樣才能實現真正意義上的并發調度,所以多線程還是依賴于硬件本身。為了驗證效率,當我們把執 行導入的各個線程以webService的形式部署到不同的虛擬機中去執行時,效果就不一樣了,效率明顯還會提升。由此引出一個當今IT行業的一個熱點, 虛擬化技術的實現與應用,有利于資源的優化配置,在有限的資源上實現更大的利用價值,該技術在云計算領域也是頗受關注的。
  (二)利用SQLLOADER執行大數據導入
  SQLLOADER是oralce內置的一個命令工具,其可實現將CSV數據文件或者文本數據文件一次性導入數據庫中。它的使用需要有兩個文 件,一個是需要導入的數據文件,另一個是控制導入的控制文件。該方案的執行需要三個步驟,第一是格式化數據文件,第二是生成控制文件,最后是執行導入命 令。
  第一,格式化數據文件。
  數據文件不是已經上傳了,為什么需要格式化呢?原因在于SQLLOADER對于導入數據文件要求的嚴格性。利用SQLLOADER導入的數據文件有如下要求:
  1、數據行之間要有合法換行標志,數據與數據之間需要有合法分隔符,一般情況下數據之間用逗號分隔,數據記錄之間用換行符分隔;
  2、要導入的數據是直接導入到數據庫的內容,不能包含表頭信息,對于數據文件中有表頭的需要將其去除;
  3、數據中不能包含既定的數據分隔符,比如逗號,因為其在導入時對于數據個數不匹配的將視為錯誤數據被拒絕。
  因此,為了確保數據能夠準確的被導入到數據庫,在數據導入之前我們需要驗證原數據文件,并讀取其數據信息生成格式化的新數據文件提供導入。這也許是這種導入方式繁瑣的地方,但出于安全又不得不做。
  第二,生成控制文件。
  SQLLOADER執行數據導入并非直接通過命題操縱數據文件,而是通過一個控制文件規定了導入數據的方式,包括數據文件路徑及導入數據字段等等,它通過執行該控制文件來實現數據的導入。下面來看一個控制文件內容。
  load data
  infile 'e:\test\艙位數據源(20120101-20120331).csv'   (1)
  append into table CZDS_CABIN                           (2)
  fields terminated by ','                                (3)
  ( CARRIER,                                                 (4)
  ORGCITY,
  ARRIVALCITY,
  FLYDATE "to_date(:FLYDATE,'YYYY-MM-DD')",
  FLIGHTNO,
  FLIGHTSEG,
  AIRLINE,
  AIRLINETOANDFROM,
  FLIGHTTYPE,
  ORGUNITS,
  MOTHERCABIN,
  SONSPACE,
  DISCOUNTFACTOR,
  CLASSES,
  FLIGHTNAVIGATIONSECTION,
  BOARDINGTIMES,
  GROUPTICKETRNUMBER,
  REVENUEFORECASTING,
  SEATINGSECTOR,
  SEATINGNAVIGATIONSECTION,
  SEATINGSONTNSECTION      )

有幫助
(0)
0%
沒幫助
(0)
0%
31选7什么时候开奖