美文网首页
一口气搞定系列-Sqoop组件使用

一口气搞定系列-Sqoop组件使用

作者: CoderInsight | 来源:发表于2022-09-05 17:57 被阅读0次
'''
导入是指从非大数据集群向大数据集群(hdfs,hive,HBase)中传入数据;
导出正好相反。
不支持从hbase直接导出到mysql;但是可以通过MR实现:先将数据导入到hdfs,然后利用sqoop将hdfs中的数据导出到hive或者mysql中。
'''
hive 的版本是1.1.0的时候与hive进行对接是有bug的,所以建议还是用使用高版本的hive进安装测试!!!
# hive1.1.0的时会报错
ERROR tool.ImportTool: Import failed: java.io.IOException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf
# 解决
# 1.编译环境变量
vi /etc/profile
# 2.追加以下内容
export HADOOP_CLASSPATH=/usr/local/hadoop/lib/*
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/usr/local/hive/lib/*
# 3.使环境变量立即生效
source /etc/profile

一、本地文件上传到HDFS中

先将本地文件上传到服务器文件系统,再传到HDFS中(在hadoop2.6之后,命令由hdfs dfs代替了之前的hadoop fs)

hadoop fs -mkdir /temp            // 创建一个文件夹
hdfs dfs -put /root/test /temp/   // 将本地文件上传到HDFS中,前面文件为服务器中的文件路径,后面时指在HDFS中的文件路径       
hdfs dfs -ls /temp         // 可发现HDFS的temp路径下新增test.txt文件
hdfs dfs -cat   /temp/test     // 显示文件中的内容
hadoop fs -rm /temp            // 删除文件
hdfs dfs -rm /output2/*        // 删除文件  
hdfs dfs -rm -r /output2      // 删除文件夹  

二、利用sqoop将Mysql数据库中的表数据导入到HDFS中 ----> import

1.实现逻辑

(1),将指定数据库的指定数据表导入到指定路径下(可以指定查询条件)
sqoop import --connect jdbc:mysql://主机名/数据库名 
--table 表名  
--username root --passoword 123456  
--fields-terminated-by '指定数据上传到hdfs中的指定分隔符,当不指定时默认的是逗号分隔符'
--target-dir "文件要上传到hdfs中的路径" 
-m 2 
--where '单引号内可以跟条件 如:id>2 and id<9' 

# 注意: 
1.  "-m 2" 表示启动两个Mapper来执行这个操作;但是需要多添加一个配置项【--split-by】:指定一个用于分割的字段
    "--colums " 可以选择列(每个列之间用逗号隔开)
    "--where" 是指定你在将数据导入到hdfs中指定条件
(2.1),"--query"的使用:只启动一个Mapper

导入数据的时候还可以指定一个select查询语句(--query),通过-m参数来指定启动几个mapper

sqoop import --connect jdbc:mysql://主机名/数据库名 
--username root --passoword 123456 
--fields-terminated-by '指定数据上传到hdfs中的指定分隔符,当不指定时默认的是逗号分隔符' 
-m 1 
--query '单引号内的一条select语句 where xxx and $CONDITIONS' 
--target-dir /文件要上传到hdfs中的路径 

# 注意: 
1、"-m 1" 表示启动一个mapper进行工作;
2、还可以指定如果当前目录存在就删除当前目录:--delete-target-dir
3、如果要写一个select语句,可以加一个--query '单引号内要跟select语句',但是就必须在select语句结束后加一个where xxx "and $CONDITIONS" (或者是当只是查询所有的时候,不需要指定查询条件,那么我们我们可以直接用 where $CONDITIONS )
,表示在起mapper的时候、动态的将数据传递给一个变量 "$CONDITIONS";
,另外 $CONDITIONS 是必须有的,而且是区分大小写的,必须是大写的;
其中 xxx 代表的时候查询条件
4、在使用 --query 的时候,我们不需要再手动的指定 --table 来指定表名了,在查询语句中自动调用我们指定的表名
5.--fields-terminated-by ':'是指定导入数据之后的分割方式
6.在输入Linux命令时如果要换行输入可以在要换的行之后加\


# 例如1:
sqoop import --connect jdbc:mysql://master:3306/sqoop \
--username root --password P@ssw0rd \
--query 'select * from test where $CONDITIONS' -m 1 \
--target-dir /sqoop/data6 \
--fields-terminated-by ':'

# 例如2: 
sqoop import \
--connect jdbc:mysql://master:3306/sqoop \
--username root --password P@ssw0rd \
--query 'select * from test where id >2 and $CONDITIONS' \
-m 1  \
--target-dir /sqoop/data4 \
--fields-terminated-by ':'
(2.2),"--query"的使用:启动两个Mapper

导入数据的时候还可以指定一个select查询语句---指定启动两个mapper

sqoop import --connect jdbc:mysql://主机名/数据库名 
--username root --passoword 123456 
--query '单引号内的一条select语句 where $CONDITIONS' 
-m 2 
--split-by 指定一个用于分割的字段

# 注意:
    -m 2 表示启动两个 mapper 进行工作,如果要启动多个mapper(这里启动了2和mapper),就需要添加分割字段
    如果要写一个select语句,可以加一个--query '单引号内要跟select语句',但是就必须在select语句结束后加一个 "and $CONDITIONS",表示在起mapper的时候、动态的将数据传递给一个变量 "$CONDITIONS"
    --split-by 指定一个用于分割的这个表的某一个字段 (表名.字段),这里是说如果要启动多个mapper进行工作,需要加指定的分割字段标志

2.具体操作

(1),先在mysql中建立数据库和表
create database sqoop;
use sqoop;
create table test(id int,name varchar(10),age int);
insert into test values(1,'zhangsan',22);
insert into test values(2,'lisi',22);
insert into test values(3,'haha',22);
insert into test values(4,'xiaoming',23);
(2),执行sqoop命令

将数据导入指定目录下:/sqoop/data

sqoop import --connect jdbc:mysql://master:3306/sqoop --table test \
--username root --password 123456 \
--fields-terminated-by ':' \
-m 1 \
--target-dir /sqoop/data \
--delete-target-dir

# 注意:
    --fields-terminated-by ':'是指定导入hdfs后数据之后的分割方式
    --target-dir:数据导入到hdfs中的路径
    --delete-target-dir:指定如果当前目录存在就删除当前目录,在测试时候可以加上
(3),以命令的方式查看数据
hdfs dfs -cat /sqoop/data/part-m-00000

三、利用sqoop将Mysql数据库中的表数据导入到hive中 ----> import

注意:实际上命令的执行过程是分成了两部分,然后先把数据上传到hdfs,然后指定输入一个临时存放的路径,然后再通过指定的参数--hive-import,将数据导入到hive中。

1,以mysql中的表名导入到hive的默认库

sqoop import --connect jdbc:mysql://master:3306/sqoop --table test \
--username root --password P@ssw0rd \
--fields-terminated-by '\t' \
-m 1 \
--target-dir /temp \
--delete-target-dir \
--hive-import 
# 注意:
    --target-dir /temp :是指定一个在hdfs中临时存放的路径并且要保证不能为空
    --fields-terminated-by :指定数据上传到hive之后数据的分割方式。
    --hive-import :指定数据是由hdfs重新再向hive中导入
    --delete-target-dir:保证数据上传的路径不存在

2,导入到hive指定数据库下面的指定表中

(1).基本过程
-- 在hive中创建数据库、数据表
create database hive_db;
use hive_db;
create table tab(id string,name string,age string,gender string) 
row format delimited fields terminated by '\t' 
stored as textfile;
-- 注意:
    1.这里的所有数据类型都设置成string类型的,因为数据在上传到hdfs中时就都是字符串类型的了,不存在整型数据等;
    2.这里建表的时候指定的分隔符与之后sqoop在将mysql中数据暂时导出到hdfs时要一致
(2),执行sqoop命令

将mysql中的数据导入到hive

sqoop import --connect jdbc:mysql://lky01:3306/sqoop --table test \
--username root --password 123456 \
--fields-terminated-by '\t' \
-m 1 \
--target-dir /temp/hive\
--delete-target-dir \
--hive-import \
--hive-database hive_db \
--hive-table tab
# 注意:
    --target-dir:是说数据导入到hive中,然后也是在hdfs中,也要指定一个输入的hdfs路径,并且这个路径必须是唯一的(或者说是先导入到hdfs中然后再导入到hive中)
    --hive-import:指定该条命令的作用是由mysql导入到hive中
    --fields-terminated-by ':':是指定数据暂时存在hdfs时的分隔符为:
(3),在hive中查看是否导入成功了
select * from tab limit 10;

四、利用sqoop将Mysql数据库中的表数据导入到HBase中 ----> import

实际命令的执行是直接将数据写到hdfs中后转移到HBase

1.导入到hbase中,自动创建表(jar包版本不兼容的时候会执行失败,但是语句没有错)

# 提示:sqoop1.4.6只是支持HBase1.0.1之前的版本自动创建HBase表的功能
sqoop import --connect jdbc:mysql://lky01:3306/sqoop --table test \
--username root --password 123456 \
--hbase-create-table --hbase-table sqoop_test --hbase-row-key id \
--column-family info -m 1

# 注意:
    "--hbase-table":可以指定在hbase中创建的"表"名;
    "--hbase-row-key":可以指定在hbase中创建的"行键"名
    "--column-family":可以指定"列族"名

2,将数据导入HBase的指定表中

(1),在hbase中建表
-- 进入hbase的shell终端
hbase shell
-- 建表语句
create 'sql_tab','id','fname'
create 'sql_tab1','id','fname','info'
(2.1),执行命令,其中列族必须与HBase建表的列族名保持一致

当只有一个列族

sqoop import --connect jdbc:mysql://lky01:3306/sqoop --table test \
--username root --password 123456 -m 1 \
--hbase-table sql_tab --hbase-row-key id --column-family fname 

# 注意:
写好连接mysql的参数之后,依次将habse的表名,行键,列族指定好
(2.2),执行命令,其中列族必须与hbase建表的列族名保持一致

当有多个列族的示例(两个列族 ---> fname,info)

// 多个列族要分多次进行导入
// 第一次
sqoop import --connect jdbc:mysql://lky01:3306/sqoop --table test \
--columns "id,name" \
--username root --password 123456 \
-m 1 \
--hbase-table sql_tab1 \
--hbase-row-key id \
--column-family fname

// 第二次
sqoop import --connect jdbc:mysql://lky01:3306/sqoop --table test \
--columns "id,age,gender" \
--username root --password 123456 \
-m 1 \
--hbase-table sql_tab1 \
--hbase-row-key id \
--column-family info

// 注意:
    1.当有多个列族时,可以根据列族名进行分批次导入数据,其中每次导入的时候指定不同的--columns,
    2.还有假如选了那个字段作为行键了,每次导出的时候都选择上!
    3. --columns:是指定导出的字段
    4.每一次的导入实际上是实现增量数据导入,即在原数据集上追加

五、利用sqoop将HDFS上的数据导出到Mysql中 ----> export

1.建表

首先在Mysql数据库中建立一张和HDFS中数据格式一模一样的表

create table test_hdfs(id int,name varchar(20),age int);

2.执行sqoop命令

sqoop export --connect jdbc:mysql://lky01:3306/sqoop --table test_hdfs \
--username root --password 123456 \
--export-dir '/sqoop/data/part-m-00000' \
--fields-terminated-by ':' -m 1
注意:
    --export-dir:是说要导出的文件在hdfs中的路径
    --fields-terminated-by :是指定数据在hdfs中的分隔符

3,验证结果

在mysql中输入命令查询表中的数据

select * from test_hdfs limit 10;

六、利用sqoop将HDFS上的数据加载到hive中 ----> load

1.建表

在hive中新建一个表,输入命令

create table test_hive(id int,name string, age int,gender string)
row format delimited fields terminated by ':'
stored as textfile;
-- 注意:
    fields terminated by ':' 这里是用来指定导入数据的时候的格式是什么样的,以什么样的格式分割的,然后保证依次导入数据

2.执行load命令

把hdfs中数据传到hive中(这里可以指定一个文件,也可以指定一整个文件夹),输入load命令

load data inpath '/sqoop/data/part-m-00000' into table test_hive;
# 注意:
    这里并没有指定分割格式,默认是按\t分割的 
    在把hdfs中数据加载到hive中时可以指定字段之间的分割方式(这里是以\t为例)--->但是并没有测试成功!
    load data '/数据在hdfs中的路径' into table test fields terminated by '\t';

3.验证结果

查询表中的数据是否导入成功了

select * from test_hive;

七、利用sqoop将Hive上的数据导出到Mysql中 ----> export

1.建表

在mysql的db数据库中创建临时表test_mysql

create table test_mysql(id int,name varchar(20), age int, gender varchar(10));

2.执行sqoop命令

sqoop export --connect jdbc:mysql://lky01:3306/sqoop --table test_mysql \ 
--username root --password 123456 \   
--fields-terminated-by '\t' --export-dir \ 
'/user/hive/warehouse/temp_table/000000_0'
利用sqoop导出,--连接的数据类型是mysql,数据库名字是db,--数据表的名字 --登录数据库的用户名 --密码
--字段-分割-由 'XXX' --导出-目录 要导出的hive表的具体路径

# 表项说明:
    lky01:这里是连接hadoop的主机名
    3306端口号之后的sqoop:mysql的数据库名
    test_mysql:数据库中的表名
    \t:是用来控制换行符 
    demo:是创建的临时表的名字
   --export-dir "要导出的临表在hdfs在中的路径,然后在user跟路径下"

3.将hive中查询出来的数据导出到mysql中

实际上就是 在建立临时表的时候,使用 as 关键字建立一个子查询,然后将子查询中的内容放到新建的表中。

(1),建立临时表

先在hive中建立一个临时表,用来存查询出来的数据

create table temp_table row format delimited fields terminated by '\t' stored as textfile as select count(*) from test where name='zhangsan'; 
-- 也就是说将查询出来的数据按指定的分割符分割之后,保存
create table temp_table2 row format delimited fields terminated by '\t' stored as textfile as select name,count(*) from test group by name; 

-- 表项说明:
       demo:临时表的表名(那么"/user/hive/warehouse/demo"这个路径下就会有demo这个文件夹,同时里边会有数据文件)
       \t:注意他自动创建的表要指定分隔符为tab键,这样在数据导出时才不会出错
       as:第一个as是本身创建表的时候必须要有的;第二个as是用来跟一个查询语句的必须的

(2),检查数据库连接

检查mysql中是否有这个数据库,也即检查数据库的连接

# 显示连接的数据库中有多少数据库
sqoop list-databases -connect jdbc:mysql://lky01:3306/sqoop -username root -password 123456
表项说明:
         lky01:是连接hadoop的主机名
         3306:是mysql服务的端口名
         sqoop:是是在mysql中建的数据库
(3),导出数据到Mysql数据库

查询出来的数据,也就是封装到临时表的数据,导出到mysql数据库中

1),在mysql数据库中先建表
create database sqoop;
use sqoop;
-- 创建数据表
create table test_mysql(number varchar(10));
-- 创建数据表2
create table test_mysql2(name varchar(20),number varchar(10));
2),执行sqoop命令

执行sqoop命令,将数据导入到mysql创建的表中

# 导入数据表
sqoop export --connect jdbc:mysql://lky01:3306/sqoop --table test_mysql \  
--username root --password 123456 \
--fields-terminated-by '\t' \
--export-dir /user/hive/warehouse/temp_table/000000_0
# 导入数据表2
sqoop export --connect jdbc:mysql://lky01:3306/sqoop --table test_mysql2 --username root --password 123456 \
--fields-terminated-by '\t' \ 
--export-dir /user/hive/warehouse/temp_table2/000000_0
3),表项说明
--export-dir "要导出的临表在hdfs在中的路径,其在user根路径下"
lky01:这里是连接hadoop的主机名
sqoop:mysql的数据库名(3306端口号后跟着的)
test_mysql:数据库中的表名
\t:是用来控制数据导入到mysql之后的换行符 
temp_table:是创建的临时表的名字

八、将Linux本地数据(需要有明确的分隔符)导入到Mysql中

# 将本地文件的数据(有明确的分隔符)导入到Mysql数据库中 : 在Mysql终端输入命令
load data infile '/var/lib/mysql-files/user_log' into table user_log fields terminated by '\t';

# 将本地文件(hdfs)的数据(有明确的分隔符)导入到hive中 :在hive终端输入命令
load data inpath '/var/lib/mysql-files/user_log' into table user_log fields terminated by '\t';

# 将本地文件(Linux)的数据(有明确的分隔符)导入到hive中 :在hive终端输入命令
load data local inpath '/var/lib/mysql-files/user_log' into table user_log fields terminated by '\t';

# 注意在导入的时候需要在指定路径下导入,因为Mysql在安装时限制了导入导出的目录权限
mysql> show variables like '%secure%';
+--------------------------+-----------------------+
| Variable_name            | Value                 |
+--------------------------+-----------------------+
| require_secure_transport | OFF                   |
| secure_auth              | ON                    |
| secure_file_priv         | /var/lib/mysql-files/ |
+--------------------------+-----------------------+

九、hive与hbase关联使用----> 建立关联表

1.在Hive中创建与HBase关联的数据表

create table hive_table(key int,web string,name string) 
row format serde 'org.apache.hadoop.hive.hbase.HBaseSerDe'
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
with serdeproperties("hbase.columns.mapping" = ":key,info:web,info:name")
tblproperties("hbase.table.name"="hbase_table");

-- 注意:
    key是固定不变的,类型是可变的;这里的info是列族;web和name是info列族下的列

2.在Hive中创建一个临时表

用于临时存放数据

create table temp(key int,web string,name string) 
row format delimited fields terminated by '|'
stored as textfile;

3.导入数据到表中

将Linux本地文件中数据传到临时表中,在hive终端输入命令

load data local inpath '/root/text.txt' into table temp;

4.验证

查看临时表中是否有数据

select * from temp limit 10;

5.在hive终端插入数据到关联表

将数据查询出来,然后插入到与HBase有关联的表

insert into table hive_table  select * from temp where key=101;

6.验证

查询Hive的表和HBase的表中是否有数据

-- 在hive终端输入
select * from hive_table;
-- 在hbase终端输入
scan 'hbase_table'

至此就可以实现在hive中执行完对表的操作后,将数据传到了hbase中

然后测试在hbase中操作当前表,然后实现hive中表的数据也实现修改

7.在Hbase终端插入数据

put 'hbase_table','99','info:web','test.com'
put 'hbase_table','99','info:name','xixi'
-- 注意:
多个列时,需要逐个使用put添加,不能指定多个

8.在Hbase中验证

在hbase shell中查看数据是否插入成功

scan 'hbase_table'
-- 或者
scan 'hbase_table',{COLUMN => ['info:web']}

9.在Hive中验证

select * from hive_table;

十、以上测试的原始数据格式

# 标题一到八的原始数据:
1:zhangsan:22:M
2:lisi:22:M
3:haha:22:M
4:xiaoming:23:M
# 标题九的原始数据:
100|micmiu.com|zhangsan
101|ctosun.com|lisi
102|baby.micimiu.com|haha

十一、在网页中查看log日志的方法

# 根据配置文件中指定的哪台机器中启动对应的进程,那么就使用谁的去连接
# yarn.resourcemanager.webapp.address,YARN的http端口
slave:8088
# MapReduce执行JobhistoryServer: mapreduce.jobhistory.webapp.address
slave:19888

十二、脚本打包---从hdfs到mysql的

1.创建文件夹

mkdir job
touch job/sqp.opt # 可以是先创建一个文件
vi job/sqp.opt  # 然后编辑一个文件,实际上可以直接vi一下,自动创建一个文件

2.在文件中写命令

sqoop export --connect jdbc:mysql://lky01:3306/sqoop --table test_hdfs \
--username root --password 123456 \
--export-dir '/sqoop/data/part-m-00000' \
--fields-terminated-by ':' -m 1

3.执行脚本

sqoop --options-file opt/sqp.opt

十三、其他可参考资料

1,可参考连接

大数据技术之_12_Sqoop学习_Sqoop 简介+Sqoop 原理+Sqoop 安装+Sqoop 的简单使用案例+Sqoop 一些常用命令及参数

2,命令参数详解

(1), sqoop import导入数据命令参数详解

常用命令:
   --connect <jdbc-uri>                         JDBC连接字符串                                         
   --connection-manager <class-name>            连接管理者                                             
   --driver <class-name>                        驱动类
   --hadoop-home <dir>                          指定$HADOOP_HOME路径
   -P                                           从命令行输入密码(这样可以保证数据库密码的安全性)
   --password <password>                        密码
   --username <username>                        用户名
   --verbose                                    打印信息


Import control arguments:
   --append                        添加到hdfs中已经存在的dataset上
                                   直接使用该参数就可向一个已经存在的目录追加内容了
   --as-avrodatafile               导入数据作为avrodata
   --as-sequencefile               导入数据作为SequenceFiles
   --as-textfile                   默认导入数据为文本
   --boundary-query <statement>    Set boundary query for retrieving max
                                   and min value of the primary key
   --columns <col,col,col...>      选择导入的列
   --compression-codec <codec>     压缩方式,默认是gzip
   --direct                        使用直接导入快速路径
   --direct-split-size <n>         在快速模式下每n字节使用一个split
-e,--query <statement>             通过查询语句导入
   --fetch-size <n>                一次读入的数量                            
   --inline-lob-limit <n>          Set the maximum size for an inline LOB
-m,--num-mappers <n>               通过实行多少个map,默认是4个,某些数据库8 or 16性能不错
   --split-by <column-name>        创建split的列,默认是主键
   --table <table-name>            导入的数据表
   --target-dir <dir>              HDFS 目标路径
   --warehouse-dir <dir>           HDFS parent for table destination
   --where <where clause>          WHERE clause to use during import
-z,--compress                      Enable compression


增量导入参数:
   --check-column <column>        Source column to check for incremental
                                  change
   --incremental <import-type>    Define an incremental import of type
                                  'append' or 'lastmodified'
   --last-value <value>           Last imported value in the incremental
                                  check column

输出行格式参数:
   --enclosed-by <char>               设置字段结束符号
   --escaped-by <char>                用哪个字符来转义
   --fields-terminated-by <char>      输出字段之间的分隔符
   --lines-terminated-by <char>       输出行分隔符
   --mysql-delimiters                 使用mysql的默认分隔符: , lines: \n escaped-by: \ optionally-enclosed-by: '

   --optionally-enclosed-by <char>    Sets a field enclosing character

输入参数解析:
   --input-enclosed-by <char>               Sets a required field encloser
   --input-escaped-by <char>                Sets the input escape
                                            character
   --input-fields-terminated-by <char>      输入字段之间的分隔符
   --input-lines-terminated-by <char>       输入行分隔符
                                            char
   --input-optionally-enclosed-by <char>    Sets a field enclosing
                                            character

Hive arguments:
   --create-hive-table                         创建hive表,如果目标表存在则失败

   --hive-delims-replacement <arg>             导入到hive时用自定义的字符替换掉 \n, \r, and \001

   --hive-drop-import-delims                   导入到hive时删除 \n, \r, and \001
   --hive-home <dir>                           重写$HIVE_HOME
   --hive-import                               Import tables into Hive
                                               (Uses Hive's default
                                               delimiters if none are
                                               set.)
   --hive-overwrite                            Overwrite existing data in
                                               the Hive table
   --hive-partition-key <partition-key>        hive分区的key
   --hive-partition-value <partition-value>    hive分区的值
                                              
   --hive-table <table-name>                   Sets the table name to use
                                               when importing to hive
   --map-column-hive <arg>                     类型匹配,sql类型对应到hive类型

(2), sqoop export导出数据命令参数详解

export主要参数
--direct     快速导入
--export-dir <dir>                            HDFS到处数据的目录
-m,--num-mappers <n>                          都少个map线程
--table <table-name>                          导出哪个表
--call <stored-proc-name>                     存储过程
--update-key <col-name>                       通过哪个字段来判断更新
--update-mode <mode>                          插入模式,默认是只更新,可以设置为allowinsert.
--input-null-string <null-string>             字符类型null处理
--input-null-non-string <null-string>         非字符类型null处理
--staging-table <staging-table-name>          临时表
--clear-staging-table                         清空临时表
--batch                                       批量模式

相关文章

网友评论

      本文标题:一口气搞定系列-Sqoop组件使用

      本文链接:https://www.haomeiwen.com/subject/ixwlnrtx.html