主页 > 知识库 > 数据库 > 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%
2019年歇后语2019125期 成都市| 麟游县| 巴马| 宿州市| 桓台县| 娱乐| 景德镇市| 西城区| 新巴尔虎左旗| 工布江达县| 肇东市| 屏山县| 东辽县| 松江区| 凌海市| 晋宁县| 保康县| 集贤县| 瓦房店市| 武宣县| 玉树县| 温州市| 新宁县| 南陵县| 张家界市| 汝南县| 乌兰浩特市| 阳谷县| 洛川县| 成武县| 昌图县| 舞阳县| 如东县| 郯城县| 黔江区| 宁阳县| 富阳市| 大洼县| 石渠县| 晋江市| 萍乡市| 遂宁市| 宝应县| 石嘴山市| 阳城县| 金川县| 尖扎县| 南通市| 德兴市| 岢岚县| 兴隆县| 印江| 镇平县| 绥中县| 佛坪县| 板桥市| 新沂市| 高青县| 田东县| 新和县| 永靖县| 玛纳斯县| 滦南县| 腾冲县| 广州市| 平阴县| 温宿县| 澄江县| 嵊州市| 康乐县| 江阴市| 新密市| 宜良县| 武安市| 辽宁省| 巴林右旗| 抚顺县| 白朗县| 信阳市| 泰州市| 秭归县| 汉沽区| 独山县| 台江县| 抚顺市| 海南省| 雷州市| 勐海县| 武宣县| 乐平市| 邓州市| 新昌县| 玛多县| 来凤县| 板桥市| 江山市| 喀喇| 富锦市| 南汇区| 清丰县| 上蔡县| 河津市| 翁牛特旗| 前郭尔| 安达市| 桃园县| 新乡县| 宁南县| 正镶白旗| 疏勒县| 伊宁县| 沁源县| 龙游县| 乌兰察布市| 浦北县| 百色市| 静乐县| 伊宁市| 西充县| 阜平县| 自治县| 南昌县| 长沙县| 昌黎县| 赣州市| 洪泽县| 安义县| 宁津县| 余姚市| 南阳市| 宣汉县| 蚌埠市| 罗城| 莱西市| 洪雅县| 深水埗区| 安化县| 浪卡子县| 汉中市| 闸北区| 仙游县| 农安县| 同德县| 香格里拉县| 冕宁县| 瑞昌市| 安国市| 苍梧县| 万宁市| 山西省| 利津县| 顺昌县| 顺昌县| 阳谷县| 绥滨县| 右玉县| 兴海县| 桂林市| 基隆市| 三门峡市| 汤原县| 舟山市| 聂荣县| 浦东新区| 海南省| 京山县| 阳春市| 周至县| 天全县| 勐海县| 县级市| 阳山县| 石河子市| 沐川县| 大连市| 平阴县| 满洲里市| 沙洋县| 福鼎市| 凉山| 房产| 正镶白旗| 呼和浩特市| 绥棱县| 精河县| 临泉县| 汝州市| 闸北区|