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

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

來源:中國IT實驗室 作者:佚名 發表于:2013-07-23 17:45  點擊:
數據導入功能在報表項目中是經常可見的,因為它是報表數據展示的基礎,但對于大量數據的導入,真正從性能、效率等方面兼顧的方案卻很少有。最近在南航廣西數據服務平臺的項目開發中,我需要設計一個能快速將40多萬條數據導入Oracle數據庫的方案,為了實現導
 數據導入功能在報表項目中是經常可見的,因為它是報表數據展示的基礎,但對于大量數據的導入,真正從性能、效率等方面兼顧的方案卻很少有。最近在南航廣西數據服務平臺的項目開發中,我需要設計一個能快速將40多萬條數據導入Oracle數據庫的方案,為了實現導入的高效,我通過在網上收集資料以及動手實踐測試,得出了一些分析總結與大家分享探討。  談到數據導入功能的實現,無可厚非應該包括兩個過程,首先是數據文件的上傳,其次是數據的導入。
  一、數據文件上傳
  文件上傳本應該是與導入無關,但它處于數據導入功能的一個環節,其效率也顯得有些重要。對于傳統項目,文件上傳通常采用Struts等框架實現 的文件上傳機制以及一些開源的文件上傳組件,比如SmartUpload等,通過Html中類型為File的Input標簽將數據文件獲取,通過流的形式 發送服務端,最后由服務端獲取流并寫入文件,如此實現了文件從客戶端到服務器的上傳過程,這些方式我們都可以將其統一稱為Web文件上傳。
  Web文件上傳是通過Http協議實現的文件流傳輸,其受限于Web數據傳輸的瓶頸,基于Http協議傳 輸的數據在傳輸的速度上有一定影響,首先可能出現數據文件請求超時需要數據重傳;其次在每秒能傳輸的字節數在Web方式里受到限制;最后,由于Web在傳 輸數據文件之前需要將數據文件轉化為數據流,通過Web的File標簽實現的文件流化效率很低,通過對比試驗發現,同樣對一個50M的文件流化,用Web 的File標簽流化的時間要大于采用IO方式流化所消耗的時間,也就是說,對于大數據文件,要將其通過Web標簽流化再傳輸,可能會有很長一段時間是處于 發送請求狀態,甚至會因為這個過程的時間持續較長而造成網絡請求超時。這可能是優酷等類似的網站上傳視頻不采用Web方式的一個原因。
  除了Web方式,可以考慮使用Applet,作為一個客戶端小程序嵌入到網頁中,以IO的方式讀取本地數據文件,然后通過Socket將文件流 發送到服務端。這種方式從效率上比Web方式有明顯的改進,首先是通過IO將文件轉化為文件流的效率提升,其次數據通過Socket方傳輸式,是一種基于 TCP協議的網絡傳輸,去除了Web下Http協議對文件傳輸的限制,通過TCP協議直接從網絡的傳輸層進行數據通信,傳輸速度上必然會更快。綜上,采用Applet加Socket實現網絡文件上傳性能優于Web方式。
  然而,Applet實現的網絡文件上傳又并非最優,原因在于Applet在運行時受到沙箱的限制。出于對客戶機和服務器的保護,web中的applet程序只能運行在限制的沙箱中,其受到很多安全策略的限制,在applet中不能直接訪問客戶端本地文件系統,除非使用applet授權,采用數字簽名的方式使applet能確認該客戶端系統是可信的。這樣一來,要使用該功能的客戶機系統都需要安裝安全證書,在項目的部署上就顯得十分繁瑣。
  以上方式都各有弊端,最終,通過和用戶協商,我們決定借助外部的FTP工具,使用開源的文件傳輸工具讓用戶將數據文件直接傳到服務器指定目錄 下,在網站系統上就只執行數據文件列表加載。另外,目前也有在web上嵌入FTP功能的插件,其通過activeObject的形式嵌入web,實現類似 ftp的文件上傳功能,打算抽空繼續研究。
  二、數據導入
  大數據導入Oracle數據庫是功能實現的重點。
  大數據導入的特點在于數據記錄多,數據插入需要批量執行,分批量commit,以此來減少對數據庫的交互訪問次數,減輕數據庫壓力。在此,我主要探索了兩種導入方式,一種是基于多線程的并發插入,另一種是利用SqlLoader實現的大數據導入。
  (一)基于多線程的并發插入
  該方案是在批量到插入的基礎之上采用多線程來執行的方式實現的。
  該方案第一步是加載所需的數據文件到內存,生成一個Sql的數組。對于導入的數據文件,一般是EXCEL格式的,對于此種類型數據文件,我們需要借助POI來實現EXCEL文件的加載,并通過POI讀取EXCEL中行數據來生成數據插入Sql,文件代碼如下:
  private XSSFSheet get07SheetForExcel(File file, String sheetName) {
  if (file != null) {
  try {
  FileInputStream fileInputStream = new FileInputStream(file);
  // 創建對Excel工作簿文件的引用
  XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
  // 創建對工作表的引用?1?7?1?7
  XSSFSheet sheet = workbook.getSheetAt(0);
  // 也可用getSheetAt(int index)按索引引用,
  // 在Excel文檔中,第一張工作表的缺省索引是0$1?7
  // 其語句為:HSSFSheet sheet = workbook.getSheetAt(0);
  return sheet;
  } catch (Exception e) {
  }
  }
  return null;
  }
  ……
  for (int i = begin; null != sheet
  && i < sheet.getLastRowNum() - sheet.getFirstRowNum()
  + 1; i++) {
  HSSFRow row = sheet.getRow(i);
  System.out.println(i);
  String[] valuesPerRow = getHSSFRowValues(row);
  if (null == valuesPerRow || valuesPerRow.length < 1) {
  continue;
  }
  rows.add(valuesPerRow);
  if (rows.size() == CommonParas.PER_IMPORT_SIZE) {
  v.importToDB(rows);
  rows.clear();
  }
  }
  v.importToDB(rows);

有幫助
(0)
0%
沒幫助
(0)
0%
极速快3哪里下载迅雷下载