企业在建设数据平台过程中,凭借大数据解决方案,企业能够收集处理大量低结构化的原始数据(如 Web 日志、社交媒体数据、电子邮件、传感器数据和位置数据),它们可以为业务应用程序提供丰富的实用信息。同时,在企业中关系数据库(大多数商业应用所采用的平台)中包含一些关键数据。在实施全数据分析的过程中,通常需要结合关系数据库中的数据和Hadoop数据池数据,从而获取更深入的洞察。
然而,Hadoop 上的数据必须经过一系列技术和工具(即“连接器”)的处理后才可由数据库进行分析。本文主要描述了如何实现快速加载Hadoop上的海量数据导入到Oracle关系数据库中,以帮助企业实现真正的全数据分析。
2.1 Oracle Big Data Connectors介绍
Oracle Big Data Connectors 是Oracle开发的一个用于集成 Apache Hadoop 发行版与 Oracle 数据库的软件套件。它赋予了使用 Hadoop 处理和分析大量数据,同时结合使用Oracle数据库数据以获得新的关键业务洞察的能力。
Oracle Big Data Connectors 将 Hadoop 与 Oracle 数据库连接在一起,并针对 Hadoop 和 Oracle 数据库进行了优化,为大数据解决方案提供了必要的基础架构。它包括将数据从 Hadoop 快速加载到 Oracle 数据库的工具、在 Hadoop 与 Oracle 数据库之间进行数据访问的工具,以及在 Hadoop 中执行 R 和 XML 分析的工具,以支持信息发现、深度分析,以及企业中所有数据的快速集成。
这个软件套件包含以下组件:
Oracle Loader for Hadoop
Oracle SQL Connector for Hadoop Distributed File System (HDFS)
Oracle Data source for Apache Hadoop
Oracle Advanced Analytics for Hadoop
Oracle XQuery for Hadoop
Oracle Big Data Connectors 同时支持企业私有部署和云部署,为大数据应用程序提供了丰富的特性、安全性和高速连通性。
本文主要介绍了其中的OracleLoader for Hadoop(OLH)这个组件,实现了将Hadoop数据快速导入到Oracle数据库的数据集成能力。
Oracle Loader for Hadoop(OLH) 是一个可将数据从 Hadoop 快速导入Oracle 数据库的高性能加载工具。Oracle Loader for Hadoop实现原理是在Hadoop 上利用Hadoop 计算资源对数据进行分类、分区、数据类型转换,然后再加载到数据库中。首先,OLH将数据转换为Oracle 类型减少了加载过程中对数据库 CPU 的使用,从而极大地减少了对数据库应用程序的影响。其次,OLH采用了创新的采样技术,可智能地将数据采集分布到各个Hadoop节点,同时以并行方式加载数据。第三,OLH 它本身可以支持多种来源加载数据:文本文件、Hive 表、日志文件(解析并加载)、Oracle NoSQL Database 等。此外,Oracle Loader for Hadoop 还可以通过用户提供的自定义输入格式实现来读取专有的数据格式。
其中OLH具备以下一些特点:
OLH 加载选项描述:
Oracle Loaderfor Hadoop 提供了联机和脱机加载选项。使用联机加载选项时,预处理数据和将数据加载到数据库都是 OracleLoader for Hadoop 作业的必要环节。每项化简任务都会与 Oracle 数据库建立一个连接,从而并行地将数据加载到数据库。数据库必须在 Oracle Loader for Hadoop 执行处理期间维持可用性。
使用脱机加载选项时,每个化简任务都会创建一个写入到 HDFS 的 Oracle 数据泵文件。在此期间,数据库可以处于脱机状态。随后,用户可以使用 Oracle Direct Connector for HDFS 将数据加载到数据库中。
本文主要介绍了联机加载选项。
3.1 部署结构图
OLH 作为一个Java Application,通过运行Mapreduce作业,利用大数据平台的分布式计算能力,完成对Hadoop上的文件进行数据读取,类型识别和转换工作,采用数据流的方式,将数据从Hadoop上采集后通过数据库OCI接口写入Oracle数据库中,从而实现Oracle数据表加载来自Hadoop大数据平台HDFS、Hive等的数据。
因此,OLH的部署可以采用单独环境部署,在Hadoop任意节点部署,在Oracle任意数据库节点部署的方式。
Hadoop平台版本:HDP 3.1.4.0-315
Oracle 版本:Oracle 19.8
Oracle Loader forHadoop Release 5.1.1安装介质下载:
https://download.oracle.com/otn/other/bigdata/oraloader-5.1.1.x86_64.zip
IP | 名称 | 描述 |
10.0.0.2 | Master | Hadoop Namenode |
10.0.0.3 | Datanode1 | Hadoop Datanode |
10.0.0.4 | Datanode2 | Hadoop Datanode |
10.0.0.5 | Datanode3 | Hadoop Datanode |
10.0.0.6 | bigdata-db-1 | Oracle数据库和OLH运行环境 |
在OLH 运行环境进行操作,配置Hadoop和Hive客户端。
1.把HDP 1号节点的mapreduce.tar.gz文件上传到OLH 运行环境端的/u01/bdc目录:
scp /usr/hdp/current/hadoop-client/mapreduce.tar.gz root@10.0.0.6:/u01/bdc
在OLH 运行环境解压到/u01/bdc目录
2.把HDP 1号节点/usr/hdp/current/hive-client/hive.tar.gz文件上传到OLH 运行环境的/u01/bdc目录
scp /usr/hdp/current/hive-client/hive.tar.gz root@10.0.0.6:/u01/bdc
在OLH 运行环境解压到/u01/bdc目录
3.进入HDP 1号节点,把/usr/hdp/3.1.4.0-315目录下的所有包生成tar包.
tar -czvf/usr/hdp/3.1.4.0-315.tar.gz /usr/hdp/3.1.4.0-315/*
并把3.1.4.0-315.tar.gz文件传到OLH 运行环境的/u01/bdc目录
scp /usr/hdp/3.1.4.0-315.tar.gz root@10.0.0.6:/u01/bdc
在OLH 运行环境解压到/usr/hdp目录,解压之后的路径如下:
4.在Ambari中下载hdfs和hive的客户端配置文件,并把配置文件放到OLH 运行环境的/u01/bdc目录中
解压之后目录结构如下:
5. 配置环境变量~/.bash_profile
使用oracle用户登陆操作系统,增加如下环境变量:
export HADOOP_HOME=/u01/bdc/hadoopexport HADOOP_CONF_DIR=/u01/bdc/hadoop-confexport HIVE_HOME=/u01/bdc/hiveexport HIVE_CONF_DIR=/u01/bdc/hive-confexport JAVA_HOME=/usr/local/jdk1.8.0_261 export PATH=$HADOOP_HOME/bin:$HIVE_HOME/bin:$OSCH_HOME/bin:$PATHexport HADOOP_CLASSPATH=:$HIVE_HOME/lib/*:$HADOOP_CLASSPATH
6. 验证,执行hdfs dfs –ls / 能查看到hdfs中的目录,说明配置成功。
在OLH运行环境中,安装配置Oracle数据库客户端。
1. 把下载的olh包上传到安装节点的/u01/bdc目录,并解压,解压之后的目录如下:
2. 配置环境变量,增加如下环境变量。
export OLH_HOME=/u01/bdc/orahdfs-5.0.0export PATH=$HADOOP_HOME/bin:$HIVE_HOME/bin:$OLH_HOME/bin:$PATHexport HADOOP_CLASSPATH=$OLH_HOME/jlib/*:$HADOOP_HOME/lib/*:$HIVE_HOME/lib/*:$HADOOP_CLASSPATH
配置之后的环境变量如下:
在Oracle数据库中创建bdcdemo用户,并赋予相应的权限,用于数据导入操作。
sqlplus / as sysdba;create user bdcdemo identified by welcome1;grant connect to bdcdemo;grant resource to bdcdemo;grant dba to bdcdemo;grant CREATE TABLE,CREATE VIEW,CREATE SESSION,ALTER SESSION to bdcdemo;GRANT EXECUTE ON sys.utl_file TO bdcdemo;
4 Oracle Load For Hadoop 测试
4.1 准备测试数据
测试数据为Text格式的文本文件part-r-00000。
测试数据如下:
把数据上传到hdfs中的/user/oracle/bdws/olh/data目录:
hdfs dfs -mkdir /user/oracle/bdws/olh/datahdfs dfs -put /u01/bdc/bdws/olh/data/*/user/oracle/bdws/olh/data
1. 使用sqlplus创建Oracle 表作为导入目标表。
sqlplus bdcdemo/welcome1@10.0.0.6:1521/orclDROP TABLE OLH_DEMO_OCI;CREATE TABLE OLH_DEMO_OCI("SESSION_ID" NUMBER,"TIME_ID" DATE,"CUST_ID" NUMBER,"DURATION_SESSION" NUMBER,"NUM_RATED" NUMBER,"DURATION_RATED" NUMBER,"NUM_COMPLETED" NUMBER,"DURATION_COMPLETED" NUMBER,"TIME_TO_FIRST_START" NUMBER,"NUM_STARTED" NUMBER,"NUM_BROWSED" NUMBER,"DURATION_BROWSED" NUMBER,"NUM_LISTED" NUMBER,"DURATION_LISTED" NUMBER,"NUM_INCOMPLETE" NUMBER,"NUM_SEARCHED" NUMBER)PARTITION BY HASH(CUST_ID);
2. 创建导入配置xml文件,olh_demo_oci.xml,文件内容如下:
<?xml version="1.0" encoding="UTF-8" ?><configuration> <!-- Input settings --><property><name>mapreduce.inputformat.class</name><value>oracle.hadoop.loader.lib.input.DelimitedTextInputFormat</value></property> <property><name>mapred.input.dir</name><value>/user/oracle/bdws/olh/data</value></property> <property><name>oracle.hadoop.loader.input.fieldTerminator</name><value>\u0009</value></property> <!-- Output settings --><property><name>mapreduce.outputformat.class</name><value>oracle.hadoop.loader.lib.output.OCIOutputFormat</value></property><property><name>mapred.output.dir</name><value>temp_out_session</value></property> <!-- Table information --><property><name>oracle.hadoop.loader.loaderMap.targetTable</name><value>olh_demo_oci</value></property> <property><name>oracle.hadoop.loader.input.fieldNames</name><value>SESSION_ID,TIME_ID,CUST_ID,DURATION_SESSION,NUM_RATED,DURATION_RATED,NUM_COMPLETED,DURATION_COMPLETED,TIME_TO_FIRST_START,NUM_STARTED,NUM_BROWSED,DURATION_BROWSED,NUM_LISTED,DURATION_LISTED,NUM_INCOMPLETE,NUM_SEARCHED</value></property> <property><name>oracle.hadoop.loader.defaultDateFormat</name><value>yyyy-MM-dd:HH:mm:ss</value></property> <!-- Connection information --> <property><name>oracle.hadoop.loader.connection.url</name><value>jdbc:oracle:thin:@${HOST}:${TCPPORT}/${SERVICE_NAME}</value></property><property><name>TCPPORT</name><value>1521</value></property><property><name>HOST</name><value>localhost</value></property><property><name>SERVICE_NAME</name><value>orcl</value></property><property><name>oracle.hadoop.loader.connection.user</name><value>bdcdemo</value></property><property><name>oracle.hadoop.loader.connection.password</name><value>welcome1</value><description> Having password in cleartext is NOT RECOMMENDED - use Oracle Wallet instead </description></property> <property><name>oracle.hadoop.loader.logBadRecords</name><value>true</value></property> </configuration>
3. 创建导入脚本olh_demo_oci.sh,脚本内容如下:
export HADOOP_CLASSPATH="$OLH_HOME/jlib/*:$HIVE_HOME/lib/*:/etc/hive/conf:$HADOOP_CLASSPATH" hdfs dfs -rm -r -f /user/oracle/temp_out_sessionhadoop jar ${OLH_HOME}/jlib/oraloader.jar \ oracle.hadoop.loader.OraLoader \ -conf /u01/bdc/bdws/olh/olh_demo_oci.xml \ -D mapred.reduce.tasks=2
4. 也可以不使用xml配置文件,直接创建脚本进行执行,例如:
$ cat olh_hdfs_txt.sh#!/bin/bash export HADOOP_CLASSPATH="${OLH_HOME}/jlib/*:${HIVE_HOME}/lib/*:/etc/hive/conf:$HADOOP_CLASSPATH" export OUTPUT_DIR=/user/hive/temp_out_texthdfs dfs -rm -r -f $OUTPUT_DIR hdfs dfs -rm -r -f $OUTPUT_DIRhadoop jar ${OLH_HOME}/jlib/oraloader.jar \ oracle.hadoop.loader.OraLoader \ -D mapred.reduce.tasks=2 \ -D mapreduce.inputformat.class=oracle.hadoop.loader.lib.input.DelimitedTextInputFormat \ -D mapred.input.dir='/user/oracle/bdws/olh/data' \ -D oracle.hadoop.loader.input.fieldTerminator='\u0009' \ -D mapreduce.outputformat.class=oracle.hadoop.loader.lib.output.OCIOutputFormat \ -D oracle.hadoop.loader.connection.url='jdbc:oracle:thin:@${HOST}:${TCPPORT}/${SERVICE_NAME}' \ -D TCPPORT=1521 \ -D HOST=10.0.0.3 \ -D SERVICE_NAME=orcl \ -D oracle.hadoop.loader.connection.user=bdcdemo \ -D oracle.hadoop.loader.connection.password=welcome1 \ -D oracle.hadoop.loader.loaderMap.targetTable=olh_demo_oci \ -D oracle.hadoop.loader.input.fieldNames=SESSION_ID,TIME_ID,CUST_ID,DURATION_SESSION,NUM_RATED,DURATION_RATED,NUM_COMPLETED,DURATION_COMPLETED,TIME_TO_FIRST_START,NUM_STARTED,NUM_BROWSED,DURATION_BROWSED,NUM_LISTED,DURATION_LISTED,NUM_INCOMPLETE,NUM_SEARCHED \ -D oracle.hadoop.loader.defaultDateFormat='yyyy-MM-dd:HH:mm:ss' \ -D oracle.hadoop.loader.logBadRecords=true \ -D mapred.output.dir=$OUTPUT_DIR
5. 执行数据装载操作
用oracle用户进入 /u01/bdc/bdws/olh目录,执行olh_demo_oci.sh 脚本:
6. 验证数据,执行如下脚本 :
sqlplus bdcdemo/welcome1@10.0.0.3:1521/orclset linesize 200;set pages 200;select count(1) from olh_demo_oci;select SESSION_ID, CUST_ID from olh_demo_oci where rownum<=10;
执行结果如下 :
1. 准备数据集,在Hive中执行如下脚本:
use bdws; drop table EXT_OLH_DEMO_OCI;CREATE EXTERNAL TABLE EXT_OLH_DEMO_OCI(SESSION_ID String,TIME_ID String,CUST_ID String,DURATION_SESSION String,NUM_RATED String,DURATION_RATED String,NUM_COMPLETED String,DURATION_COMPLETED String,TIME_TO_FIRST_START String,NUM_STARTED String,NUM_BROWSED String,DURATION_BROWSED String,NUM_LISTED String,DURATION_LISTED String,NUM_INCOMPLETE String,NUM_SEARCHED String)STORED AS ORCLOCATION '/user/oracle/bdws/olh/data'; #Txt file, hive managed tablecreate table OLH_DEMO_TXT stored as textfile as select * from EXT_OLH_DEMO_OCI; #orc file, hive managed tablecreate table OLH_DEMO_ORC stored as orc as select * from EXT_OLH_DEMO_OCI; #Parquet file, hive managed tablecreate table OLH_DEMO_parquet stored as parquet as select * from EXT_OLH_DEMO_OCI;
2. 查询Hive 表数据
select SESSION_ID,time_id,cust_id from OLH_DEMO_ORC limit 10;select count(1) from OLH_DEMO_TXT;select count(1) from OLH_DEMO_ORC;select count(1) from OLH_DEMO_parquet;
数据存放的位置如下:
Hive
外部表,
Txt file: /user/oracle/bdws/olh/data
Hive
管理表,
Txt file: /warehouse/tablespace/managed/hive/bdws.db/olh_demo_txt
Hive 管理表,Orc file:
Hive 管理表,Parquet file:
3. 创建Oracle目标数据表
使用sqlplus登录到DB节点执行创建Oracle数据库表,用于数据装载。
sqlplus bdcdemo/welcome1@10.0.0.6:1521/orcl DROP TABLE OLH_DEMO_ORC;CREATE TABLE OLH_DEMO_ORC("SESSION_ID" VARCHAR2(100),"TIME_ID" VARCHAR2(100),"CUST_ID" VARCHAR2(100),"DURATION_SESSION" VARCHAR2(100),"NUM_RATED" VARCHAR2(100),"DURATION_RATED" VARCHAR2(100),"NUM_COMPLETED" VARCHAR2(100),"DURATION_COMPLETED" VARCHAR2(100),"TIME_TO_FIRST_START" VARCHAR2(100),"NUM_STARTED" VARCHAR2(100),"NUM_BROWSED" VARCHAR2(100),"DURATION_BROWSED" VARCHAR2(100),"NUM_LISTED" VARCHAR2(100),"DURATION_LISTED" VARCHAR2(100),"NUM_INCOMPLETE" VARCHAR2(100),"NUM_SEARCHED" VARCHAR2(100))PARTITION BY HASH(CUST_ID);
4. 创建导入配置的xml文件,olh_demo_orc.xml,文件内容如下:
<?xml version="1.0" encoding="UTF-8" ?><configuration> <!-- Input settings --> <property><name>mapreduce.inputformat.class</name><value>oracle.hadoop.loader.lib.input.HiveToAvroInputFormat</value></property> <property><name>oracle.hadoop.loader.input.hive.databaseName</name><value>bdws</value></property> <property><name>oracle.hadoop.loader.input.hive.tableName</name><value>olh_demo_orc</value></property> <!-- Output settings --><property><name>mapreduce.outputformat.class</name><value>oracle.hadoop.loader.lib.output.OCIOutputFormat</value></property> <!--property> <name>mapred.output.dir</name> <value>temp_out_session</value> </property--> <!-- Table information --> <property><name>oracle.hadoop.loader.loaderMap.targetTable</name><value>olh_demo_oci</value></property> <property><name>oracle.hadoop.loader.defaultDateFormat</name><value>yyyy-MM-dd:HH:mm:ss</value></property> <!-- Connection information --><property><name>oracle.hadoop.loader.connection.url</name><value>jdbc:oracle:thin:@${HOST}:${TCPPORT}/${SERVICE_NAME}</value></property> <property><name>TCPPORT</name><value>1521</value></property> <property><name>HOST</name><value>localhost</value></property> <property><name>SERVICE_NAME</name><value>orcl</value></property> <property><name>oracle.hadoop.loader.connection.user</name><value>bdcdemo</value></property> <property><name>oracle.hadoop.loader.connection.password</name><value>welcome1</value><description> Having password in cleartext is NOT RECOMMENDED - use Oracle Wallet instead </description></property> <property><name>oracle.hadoop.loader.logBadRecords</name><value>true</value></property></configuration>
5. 创建导入脚本olh_demo_orc.sh,脚本内容如下:
export HADOOP_CLASSPATH="$OLH_HOME/jlib/*:$HIVE_HOME/lib/*:/etc/hive/conf:$HADOOP_CLASSPATH" export OUTPUT_DIR=/user/oracle/temp_out_text1hdfs dfs -rm -r -f $OUTPUT_DIR hadoop jar ${OLH_HOME}/jlib/oraloader.jar \ oracle.hadoop.loader.OraLoader \ -conf /u01/bdc/bdws/olh/olh_demo_orc.xml \ -D mapred.output.dir=$OUTPUT_DIR \ -D mapred.reduce.tasks=1 \ -D hive.transactional.table.scan=true \ -D 'hive.txn.valid.txns=9223372036854775807:9223372036854775807::' \ -D 'schema.evolution.columns=${columns}' \ -D 'schema.evolution.columns.types=${columns.types}'
6. 也可以不使用xml配置文件,直接创建脚本进行执行,例如:
[oracle@bigdata-db-1 olh]$ cat olh_hive_orc.sh#!/bin/bash export HADOOP_CLASSPATH="${OLH_HOME}/jlib/*:${HIVE_HOME}/lib/*:$HADOOP_CLASSPATH" export OUTPUT_DIR=/user/hive/temp_out_texthdfs dfs -rm -r -f $OUTPUT_DIR hadoop jar ${OLH_HOME}/jlib/oraloader.jar \ oracle.hadoop.loader.OraLoader \ -D mapred.reduce.tasks=2 \ -D oracle.hadoop.loader.targetTable=olh_demo_orc \ -D oracle.hadoop.loader.input.hive.databaseName=bdws \ -D oracle.hadoop.loader.input.hive.tableName=OLH_DEMO_orc \ -D oracle.hadoop.loader.connection.url=jdbc:oracle:thin:@10.0.0.3:1521/orcl \ -D oracle.hadoop.loader.connection.user=bdcdemo\ -D oracle.hadoop.loader.connection.password=welcome1 \ -D mapreduce.inputformat.class=oracle.hadoop.loader.lib.input.HiveToAvroInputFormat \ -D mapreduce.outputformat.class=oracle.hadoop.loader.lib.output.OCIOutputFormat \ -D hive.transactional.table.scan=true \ -D 'hive.txn.valid.txns=9223372036854775809:9223372036854775809::' \ -D 'schema.evolution.columns=${columns}' \ -D 'schema.evolution.columns.types=${columns.types}' \ -D mapred.output.dir=$OUTPUT_DIR
7. 执行数据导入操作
8. 验证导入数据 :
sqlplus bdcdemo/welcome1@10.0.0.3:1521/orclset linesize 200;set pages 200;select count(1) from olh_demo_orc;select SESSION_ID, CUST_ID from olh_demo_orc where rownum<=10;
结果如下 :
1、是否支持中文数据导入?
OLH导入HDFS文本文件方式下,OLH支持导入UTF8格式文件,其中Oracle数据库使用AL32UTF8编码。
OLH 导入Hive 表数据,Oracle数据库使用AL32UTF8编码,可以支持中文数据导入。
2、OLH是否支持文本文件中字段分割符为多字节。
OLH不支持文本中字段分割符为多字节,另外一个Oracle SQL connector for Hadoop可以支持。
3、OLH 是否支持文件中第一行为表头。
支持,数据装载过程中,数据文件内容会根据目标表的定义字段类型进行数据内容的检查,如果不合法,该行数据会被skip掉,其他数据正常加载。文件头信息也是这样处理的。加载数据日志中会统计成功写入多少行,skip多少行。
4、OLH导入日志与异常处理
OLH采用java开发,使用java运行环境,导入使用MapReduce过程,运行日志记录了导入数据行,数据量,skip数据行等信息。在使用ETL调用过程中,可以判断java运行返回结果来判断是否运行成功。
https://www.oracle.com/database/technologies/bdc/hadoop-loader.html
https://www.oracle.com/technetwork/database/database-technologies/bdc/big-data-connectors/overview/bigdata-connectors-datasheet-1883359.pdf?ssSourceSiteId=otncn
https://docs.oracle.com/en/bigdata/big-data-connectors/5.1/user/start.html
编辑:萧宇