'''
导入是指从非大数据集群向大数据集群(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 批量模式
网友评论