Sqoop相关

1.Sqoop安装

下载sqoop文件:
[hadoop@hadoop001 software]$ wget http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.6-cdh5.7.0.tar.gz
解压:
[hadoop@hadoop001 software]$ tar -zxvf sqoop-1.4.6-cdh5.7.0.tar.gz -C ~/app/sqoop-1.4.6-cdh5.7.0
配置环境变量
[hadoop@hadoop001 sqoop-1.4.6-cdh5.7.0]$ vim ~/.bash_profile 
export SQOOP_HOME=/home/hadoop/app/sqoop-1.4.6-cdh5.7.0
export PATH=$SQOOP_HOME/bin:$PATH
生效文件:
[hadoop@hadoop001 sqoop-1.4.6-cdh5.7.0]$ source ~/.bash_profile
复制配置文件
[hadoop@hadoop001 conf]$ cp sqoop-env-template.sh sqoop-env.sh
修改环境配置文件
[hadoop@hadoop001 conf]$ vim sqoop-env.sh 
export HADOOP_COMMON_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0
export HADOOP_MAPRED_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0
export HIVE_HOME=/home/hadoop/app/hive-1.1.0-cdh5.7.0
需要将mysql相应的jar包,放入到sqoop的目录下
[hadoop@hadoop001 lib]$ cp ~/app/hive-1.1.0-cdh5.7.0/lib/mysql-connector-java-5.1.27.jar .

2.sqoop导入(MySQL==>HDFS)

使用sqoop展示所有的数据库:
[hadoop@hadoop001 bin]$ sqoop list-databases --connect jdbc:mysql://localhost:3306 --username root --password 123456
展示数据库中的数据表
[hadoop@hadoop001 bin]$ sqoop list-tables --connect jdbc:mysql://localhost:3306/sqoop --username root --password 123456
dept
emp
salgrade
插入相关的表和数据
  create table emp (
  empno numeric(4) not null,
  ename varchar(10),
  job varchar(9),
  mgr numeric(4),
  hiredate datetime,
  sal numeric(7, 2),
  comm numeric(7, 2),
  deptno numeric(2)
  );
 insert into emp values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);
insert into emp values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
insert into emp values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
insert into emp values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20);
insert into emp values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
insert into emp values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30);
insert into emp values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10);
insert into emp values (7788, 'SCOTT', 'ANALYST', 7566, '1982-12-09', 3000, null, 20);
insert into emp values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10);
insert into emp values (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);
insert into emp values (7876, 'ADAMS', 'CLERK', 7788, '1983-01-12', 1100, null, 20);
insert into emp values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30);
insert into emp values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20);
insert into emp values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10);
create table salgrade (
   grade numeric,
   losal numeric,
   hisal numeric
);
insert into salgrade values (1, 700, 1200);
insert into salgrade values (2, 1201, 1400);
insert into salgrade values (3, 1401, 2000);
insert into salgrade values (4, 2001, 3000);
insert into salgrade values (5, 3001, 9999);
create table dept (
   deptno numeric(2),
   dname varchar(14),
   loc varchar(13)
);
insert into dept values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept values (20, 'RESEARCH', 'DALLAS');
insert into dept values (30, 'SALES', 'CHICAGO');
insert into dept values (40, 'OPERATIONS', 'BOSTON');
导出数据
[hadoop@hadoop001 bin]$ sqoop import --connect jdbc:mysql://localhost:3306/sqoop --username root --password 123456 --table emp
出现错误:Exception in thread "main" java.lang.NoClassDefFoundError: org/json/JSONObject
需要下载文件java-json.jar文件
[hadoop@hadoop001 lib]$ pwd
/home/hadoop/app/sqoop-1.4.6-cdh5.7.0/lib
[hadoop@hadoop001 lib]$ wget         http://www.java2s.com/Code/JarDownload/java-json/java-json.jar.zip
解压文件
[hadoop@hadoop001 lib]$ unzip java-json.jar.zip 
产生数据的放在HDFS的根目录下,并以数据表的表明为文件夹名,如果没有数据,设置为空。
查看数据:
[hadoop@hadoop001 ~]$ hadoop fs -ls /user/hadoop
drwxr-xr-x   - hadoop supergroup          0 2018-11-12 23:54 /user/hadoop/emp
在指定导入数据时,默认为分成4个map: mapreduce.JobSubmitter: number of splits:4,也可以指定map和reduce的数量。
[hadoop@hadoop001 ~]$ hadoop fs -ls /user/hadoop/emp
-rw-r--r--   1 hadoop supergroup          0 2018-11-12 23:54 /user/hadoop/emp/_SUCCESS
-rw-r--r--   1 hadoop supergroup        124 2018-11-12 23:54 /user/hadoop/emp/part-m-00000
-rw-r--r--   1 hadoop supergroup        126 2018-11-12 23:54 /user/hadoop/emp/part-m-00001
-rw-r--r--   1 hadoop supergroup        253 2018-11-12 23:54 /user/hadoop/emp/part-m-00002
-rw-r--r--   1 hadoop supergroup        368 2018-11-12 23:54 /user/hadoop/emp/part-m-00003
在执行的过程中,要保证文件不存在,如果存在,需要删除,也可以添加参数--delete-target-dir,就不会报错啦。
设置生成作业的名称以及map的个数,使用参数 -m:
[hadoop@hadoop001 bin]$sqoop import --connect jdbc:mysql://localhost:3306/sqoop --username root --password 123456 --table emp --mapreduce-job-name FromMySQLToHDFS -m 1
#如果多次导出同一个表时,就会有FileExsitsException。需要添加参数--delete-target-dir,即
[hadoop@hadoop001 bin]$sqoop import --connect jdbc:mysql://localhost:3306/sqoop --username root --password 123456 --table emp --mapreduce-job-name FromMySQLToHDFS -m 1 --delete-target-dir 
如果需要导出一个表的几个字段时,并且将没有数据进行填充,使用--columns 参数,指定字段,也可以指定要导出的位置,使用参数--target-dir,判断一些空的值或者null值,并制定值,使用--null-non-string,--null-string,也可以添加查询的参数,使用--where,在输出的数据中,为了好看,需要添加字符分隔符,参数为--fields-terminated-by,需要使用下面的命令:
[hadoop@hadoop001 bin]$ sqoop import --connect jdbc:mysql://localhost:3306/sqoop --username root --password 123456 --table emp --mapreduce-job-name FromMySQLToHDFS -m 1 --delete-target-dir --columns 'EMPNO,ENAME,JOB,SAL,COMM' --target-dir EMP_COLUMN_WHERE --fields-terminated-by '\t' --null-non-string '0' --null-string '' --where 'SAL>2000'
 使用一个完整的查询语句替换,上面的操作,使用参数 -e, 语句如下:
[hadoop@hadoop001 bin]$sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--mapreduce-job-name FromMySQLToHDFS \
-m 1 \
--delete-target-dir \
--target-dir EMP_COLUMN_QUERY \
--fields-terminated-by '\t' \
--null-non-string '0' \
--null-string '' \
-e 'select * from emp where empno>7900' 
如果使用这个语句,会有一个错误,ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: Query [select * from emp where empno>7900] must contain '$CONDITIONS' in WHERE clause.
  通过错误信息,可以看到,需要添加一个$CONDITIONS字符串,--table与-e-同时使用,会出现歧义的问题,需要使用其他方法来解决,例如增加在sql语句中必须要在条件加上$CONDITIONS,如下所示:
[hadoop@hadoop001 bin]$sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--mapreduce-job-name FromMySQLToHDFS \
-m 1 \
--delete-target-dir \
--target-dir EMP_COLUMN_QUERY \
--fields-terminated-by '\t' \
--null-non-string '0' \
--null-string '' \
-e 'select * from emp where empno>7900 and $CONDITIONS'
#如果将单引号换成双引号时,会出现错误,要对$进行转移
[hadoop@hadoop001 bin]$sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--mapreduce-job-name FromMySQLToHDFS \
-m 1 \
--delete-target-dir \
--target-dir EMP_COLUMN_QUERY \
--fields-terminated-by '\t' \
--null-non-string '0' \
--null-string '' \
-e "select * from emp where empno>7900 and \$CONDITIONS"
#在数据表中的数据导出时,没有设置主键时,就会出现错误:Error during import:No primary key could be found for table.please specify one with --split-by or perform a sequential import with '-m 1',可以指定按照那个字段来进行拆分或者使用一个map来进行处理。可以使用下面的语法:
[hadoop@hadoop001 bin]$sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--table salgrade \
--split-by GRADE \
-m 2
可以将执行写入一个文件中,添加--options-file参数,--options-file 可以直接执行某个文件,将一下常用的操作封装到一个文件中。
[hadoop@hadoop001 bin]$sqoop --options-file /home/hadoop/data/import.txt 
文件内容为:
import 
--connect
jdbc:mysql://localhost:3306/sqoop 
--username
root 
--password
123456 
--table  
emp 
--delete-target-dir
在编写--options-file文件时,需要注意的是,不要有sqoop关键字,将'\'去掉,写成KV的形式。

3.导出(HDFS==>MySQL)

将hadoop中的数据导入到mysql中:
[hadoop@hadoop001 bin]$sqoop export \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--table emp_test \
--export-dir emp 
输出错误信息:Error executing statement: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'sqoop.emp_test' doesn't exist com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'sqoop.emp_test' doesn't exist
这是由于emp_test数据表不存在sqoop数据库中,需要添加创建这个数据表,创建命令如下:
mysql> create table emp_test as select * from emp where 1=2;
然后在执行上面的命令,可以查看到数据已经导入了。
在导出数据库时,有时会只需要几个字段,可以使用下面的命令:
[hadoop@hadoop001 bin]$sqoop export \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--table emp_test \
--export-dir emp \
--columns 'EMPNO,ENAME,JOB,SAL,COMM'
控制台会输出:ERROR tool.ExportTool: Error during export: Export job failed!,这是由于没有分割符或者分隔符不对造成的,修改命令如下:
[hadoop@hadoop001 bin]$sqoop export \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--table emp_test \
--export-dir emp \
--columns 'EMPNO,ENAME,JOB,SAL,COMM' \
--fields-terminated-by '\t' 

4.MySQL==>Hive

在导入数据时,需要在Hive上创建数据表(在default下创建),命令如下:
CREATE TABLE emp_test (
empno int, 
ename string, 
job string,  
mgr int,
hiredate string,
sal double,
common double,
deptno int
)ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
也可以在导入的时候,指定要创建的数据表,可以对数据库的数据进行重写,命令如下:
[hadoop@hadoop001 bin]$sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--table emp \
--delete-target-dir \
--hive-import  \
--hive-table emp_test \
--fields-terminated-by '\t' \
--columns 'empno,ename,job,sal,common' \
--hive-overwrite
在mysql==>hive的过程中,有的需要导入到指定数据库中,如果没有指定数据库,默认导入到default数据下,在查看是否导入成功时,需要到/user/hive/warehouse文件夹下查看,可以添加参数--hive-database 来指定要导入的数据库。
创建分区表:
 CREATE TABLE emp_test_p (
empno int, 
ename string, 
job string,  
mgr int,  
hiredate string,
sal double,
common double,
deptno int
)partitioned by (pt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
导入的命令:
[hadoop@hadoop001 bin]$sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password 123456 \
--table emp \
--delete-target-dir \
--hive-import  \
--hive-table emp_test_p \
--fields-terminated-by '\t' \
--columns 'empno,ename,job,sal,common' \
--hive-overwrite \
--hive-partition-key 'pt' \  #指定分区字段
--hive-partition-value 'xiaoyao'  #指定分区值
在导入之后,可以在hive中直接看数据:
hive (default)> select * from emp_test_p where pt='xiaoyao';
在导入的时候,会出现ClassNotFoundException:org.apache.hive.conf.HiveConf异常,这是因为没有配置HIVE_CONF_DIR,但是配置HIVE_CONF_DIR变量之后,依然爆相应的错误,需要将相应的文件包复制到sqoop中
hadoop@hadoop001 lib]$ pwd
/home/hadoop/app/hive-1.1.0-cdh5.7.0/lib
[hadoop@hadoop001 lib]$ cp hive-common-1.1.0-cdh5.7.0.jar     ~/app/sqoop-1.4.6-cdh5.7.0/lib/
[hadoop@hadoop001 lib]$ cp hive-shims-* ~/app/sqoop-1.4.6-cdh5.7.0/lib/
查看导入的数据:
[hadoop@hadoop001 sqoop-1.4.6-cdh5.7.0]$ hadoop fs -ls /user/hive/warehouse/
drwxr-xr-x   - hadoop supergroup          0 2018-11-14 00:30   /user/hive/warehouse/emp_test
drwxr-xr-x   - hadoop supergroup          0 2018-11-14 00:41 /user/hive/warehouse/emp_test_p
drwxr-xr-x   - hadoop supergroup          0 2018-11-12 22:53 /user/hive/warehouse/xiaoyao.db

5.Hive==>MySQL

由于hive中的数据都是存在于HDFS上的,Hive==>MySQL的流程就是HDFS==> MySQL的流程。
导入流程:
      创建emp_test表,结构于emp一致;
      执行命令:[hadoop@hadoop001 ~]$ sqoop export --connect jdbc:mysql://localhost:3306/sqoop --username root --password 123456 --table emp_test --export-dir /user/hive/warehouse/xiaoyao.db/emp_test --input-fields-terminated-by '\t'
      然后进入mysql数据库中查看数据。

6.简单运用

需求:统计每个区域下最受欢迎的产品TOPN

6.1准备数据

创建产品表:
create table product_info(
product_id int,
product_name string,
extend_info string
)
row format delimited fields terminated by '\t';
创建城市表:
create table city_info(
city_id int,
city_name string,
area string
 )
row format delimited fields terminated by '\t';
创建用户行为的表:
create table user_click(
user_id int,
session_id string,
action_time string,
city_id int,
product_id int
) partitioned by(date string)
row format delimited fields terminated by ',';
如果数据量比较大情况下,请先将数据导入到mysql中,然后使用sqoop将数据导入到hive。

6.2需求分析

  先获取产品编号和城市编号:
  select product_id, city_id from user_click 
  where date='2016-05-05' 
  and product_id <> 0
  将上面的求的结果和城市信息进行关联:
  create table tmp_product_click_basic_info
  as
  select 
  u.product_id, u.city_id, c.city_name, c.area
  from
  (select product_id, city_id from user_click 
  where date='2016-05-05' 
  and product_id <> 0) u 
  join 
  (select city_id,city_name, area  from city_info) c 
  on u.city_id = c.city_id;
  各个区域各商品的点击次数:根据之前计算出来的数据,来进行分组
  create table tmp_area_product_click_count as 
  select product_id,area,count(1) as click_count from     tmp_product_click_basic_info group by product_id,area;
  检索出产品名字
  create table tmp_area_product_click_count_full_info as 
  select a.product_id,b.product_name,a.click_count, a.area from tmp_area_product_click_count a join product_info b on a.product_id=b.product_id;
  求每个区域下最受欢迎的top3
   create table area_product_click_count_top3
    as
    select *,
    case when click_count >=10 and click_count<20 then 'lower'
    when click_count>=20 and click_count<30 then 'middle'
    else 'highest' 
    end click_count_grade,
    '2016-05-05' day
  from (
  select 
  product_id,product_name,click_count,area,
  row_number() over(partition by area order by click_count desc) rank
  from tmp_area_product_click_count_full_info
  ) t where t.rank <=3 ;
row_number 参考自:https://blog.csdn.net/gumengkai/article/details/51356045,https://blog.csdn.net/hr541659660/article/details/75243787,https://www.cnblogs.com/ianunspace/p/5057333.html
get_json_object适用于数据量比较小的情况。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1/列出mysql数据库中的所有数据库sqoop list-databases -connect jdbc:mys...
    时待吾阅读 2,815评论 1 5
  • 上节课学习了Hadoop集群测试,这节课我们一起学习一下Sqoop,Sqoop是专门用来迁移数据的,它可以把数据库...
    文子轩阅读 7,317评论 1 9
  • 1.大数据协作框架: 大数据协作框架是Hadoop 2.x生态系统中几个辅助框架。最为常见的是以下几个: 数据转换...
    奉先阅读 3,197评论 0 2
  • 加油 300可以加49升图片发自简书App
    智者的石头阅读 264评论 0 0
  • 1、扔掉了买了但不喜欢吃的零食,扔掉了不合适的内衣 2、保持房间整洁舒适,保持衣着干净得体 3、帮爸爸订了酒店,打...
    人生需要靠自己阅读 150评论 1 1

友情链接更多精彩内容