sqoop操作之HDFS导出到ORACLE

注意:在导出前需要先创建待导出的表结构。如果导出的表在数据库中不存在则会报错;如果重复导出多次,表中的数据会重复;

create table EMP_DEMO as select * from EMP where 1=2;
create table SALGRADE_DEMO as select * from SALGRADE where 1=2;

 

导出表的所有字段

sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--export-dir /user/hadoop/EMP  -m 1;

 重复执行多次,表中的数据会重复,不会删除以前存在的数据。

 

导出表的指定字段

为了查看演示效果方便,先删除表中已经存在的数据。

DELETE FROM EMP_DEMO;
sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--columns "EMPNO,ENAME,JOB,SAL,COMM" \
--export-dir '/user/hadoop/EMP_COLUMN' \
-m 1;

sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--columns "EMPNO,ENAME,JOB,SAL,COMM" \
--export-dir '/user/hadoop/EMP' \
-m 1;

 

导出表的指定字段使用指定的分隔符

为了查看演示效果方便,先删除表中已经存在的数据。

DELETE FROM EMP_DEMO;
sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--columns "EMPNO,ENAME,JOB,SAL,COMM" \
--export-dir '/user/hadoop/EMP_COLUMN_SPLIT' \
--fields-terminated-by '\t' --lines-terminated-by '\n' -m 1;

没有指定分隔符的脚本在执行时是会报错的:Caused by: java.lang.NumberFormatException

sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--columns "EMPNO,ENAME,JOB,SAL,COMM" \
--export-dir '/user/hadoop/EMP_COLUMN_SPLIT' \
-m 1;

说明:
1)--fields-terminated-by '\t' --lines-terminated-by '\n'要和导入的一致,否则报错
2)export 命令是不支持覆盖的,经过上次的两个导出操作,表里就有两份相同的数据了

 

批量导出

为了查看演示效果方便,先删除表中已经存在的数据。

DELETE FROM EMP_DEMO;
sqoop export  \
-Dsqoop.export.records.per.statement=10 \
--connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--export-dir /user/hadoop/EMP  -m 1 \
--batch ;

 默认情况下读取一行HDFS文件的数据就insert一条记录到关系型数据库中,性能低下;

可以使用批量导出,一次导入10条数据到关系型数据库中;

 

导出保证原子性

为了查看演示效果方便,先删除表中已经存在的数据。

DELETE FROM EMP_DEMO;
sqoop export   --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--export-dir /user/hadoop/EMP  -m 1 \
--staging-table staging_emp  \
--clear-staging-table ;

map task没有数据回滚操作,如何保证原子性呢?

sqoop在导出在目标表中,先导入到临时表中staging_emp,确定导出成功后,再一次性的操作到目标表中,保证原子性;

在使用--staging-table时,staging_emp表必须要事先创建好,而且必须要有主键;
如果使用了--clear-staging-table,staging_emp如果存在数据,则先删除staging_emp表中的数据再导出;

 

处理null数据

sqoop export   --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO  \
--export-dir /user/hadoop/EMP  -m 1 \
--input-null-string '\\N' \
--input-null-non-string '\\N' ;

 

update-key操作

create table EMP_DEMO2 as select * from EMP_DEMO where 1=1;

将empno=7788的ename改为SCOTT11,empno=7782的ename改为CLARK11

此时hdfs中的empno=7788的ename为SCOTT,empno=7782的ename为CLARK

sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO2  \
--export-dir /user/hadoop/EMP  \
--update-key EMPNO -m 1;

执行完后,发现empno=7788的ename为SCOTT,empno=7782的ename为CLARK

将empno=7788的ename改为SCOTT11,empno=7782的ename改为CLARK11
表中删除除了empno为7788和7782之外的任意数据,再次执行

sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO2  \
--export-dir /user/hadoop/EMP  \
--update-key EMPNO -m 1;

执行完后,发现表中的数据条数并没有添加,但是发现empno=7788的ename为SCOTT,empno=7782的ename为CLARK

总结:--update-key只更新,不添加

 

update-mode allowinsert操作

EMP_DEMO2表中将empno=7788的ename改为SCOTT11,empno=7782的ename改为CLARK11,删除一些数据,只留下几条做测试

sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO2 \
--export-dir /user/hadoop/EMP \
--update-key EMPNO \
--update-mode allowinsert -m 1;

执行完毕后,发现一共有14条数据了,将HDFS中的数据都导出到数据库中,并更新了empno=7788的ename改为SCOTT,empno=7782的ename改为CLARK
再执行一次:

sqoop export --connect jdbc:oracle:thin:@192.168.1.107:1521:ORCL \
--username SCOTT --password tiger \
--table EMP_DEMO2 \
--export-dir /user/hadoop/EMP \
--update-key EMPNO \
--update-mode allowinsert -m 1;

还是14条数据没变;

总结:根据指定的ID,没有数据就插入,有数据就更新

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Web应用程序通常需要处理大量的数据,而Hadoop是一种用于存储和处理大数据的分布式系统。因此,将Web应用程序中的数据导出到Hadoop中进行处理是一个非常常见的需求。在这种情况下,我们可以使用Sqoop和Flume来实现数据的导出Sqoop是一个用于在Hadoop和关系数据库之间进行数据传输的工具。通过Sqoop,我们可以将关系数据库中的数据导出到Hadoop中,或者将Hadoop中的数据导入到关系数据库中。Sqoop支持多种关系数据库,如MySQL、Oracle、PostgreSQL等。 Flume是一个用于在不同的数据源之间移动数据的分布式系统。通过Flume,我们可以将Web应用程序中产生的数据实时地导出到Hadoop中进行处理。Flume支持多种数据源,如日志文件、网络流、Twitter数据流等。 下面是一个通过Sqoop和Flume将Web应用程序中的数据导出到Hadoop中的项目介绍: 1. 数据库中的数据导出到Hadoop中 首先,我们需要使用Sqoop将关系数据库中的数据导出到Hadoop中。假设我们要将MySQL数据库中的数据导出HDFS中,我们可以使用以下命令: ``` sqoop import \ --connect jdbc:mysql://localhost/test \ --username root \ --password root \ --table mytable \ --target-dir /user/hadoop/mydata ``` 该命令会将MySQL数据库中的mytable表中的数据导出HDFS的/user/hadoop/mydata目录中。 2. Web应用程序中的数据实时导出到Hadoop中 接下来,我们需要使用Flume将Web应用程序中产生的数据实时地导出到Hadoop中。假设我们要将Tomcat服务器中的日志文件导出HDFS中,我们可以使用以下命令: ``` flume-ng agent -n agent -c conf -f /path/to/flume.conf ``` 其中,flume.conf是Flume的配置文件,我们需要在其中指定数据源和目的地。例如,以下是一个简单的flume.conf文件: ``` agent.sources = web agent.sinks = hdfs agent.channels = mem agent.sources.web.type = exec agent.sources.web.command = tail -F /path/to/tomcat/logs/*.log agent.sinks.hdfs.type = hdfs agent.sinks.hdfs.hdfs.path = /user/hadoop/mydata agent.sinks.hdfs.hdfs.fileType = DataStream agent.channels.mem.type = memory agent.channels.mem.capacity = 1000 agent.channels.mem.transactionCapacity = 100 ``` 该配置文件中,我们将Tomcat服务器中的日志文件作为数据源,使用tail命令实时读取最新的日志数据。然后,我们将数据导出HDFS中,使用的是hdfs类型的sink。最后,我们使用memory类型的channel将数据缓存起来,以便在数据传输过程中进行流量控制。 通过上述配置,我们可以实现将Web应用程序中产生的数据实时地导出到Hadoop中进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值