Sqoop 是Apache下一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql、postgresql…)间进行数据的传输,可以实现关系型数据库(例如 : MySQL ,Oracle ,Postgres等)与Hadoop的HDFS之间数据互相导入、导出。
概括起来:该层充当“搬运工”的角色,主要做两件事
1:负责外部数据(多是关系型库数据)导入到分布式文件系统(HDFS);
2:将大数据分析后的结果(HDFS)进行导出至关系型数据库表中。
Sqoop作为数据导入导出工具,只需要作为客户端在一台服务器上安装即可。
Sqoop命令接口接收客户端导入导出指令—>任务转化器负责将客户端指令转化为MR任务并进行优化,提交Yarn上运行,并进行监控—>MR任务负责DB和HDFS之间数据读写。
可见:Sqoop使得用户从MR编程中解脱出来,降低了实现DB与HDFS数据导入导出的难度,一切交由Sqoop代劳。
1:Sqoop目前有Sqoop1(sqoop1.4.X) 和Sqoop2(sqoop 1.99.X) 两个版本,如图:
Sqoop1安装配置和使用:
解压、重命名安装包:
tar -zxvf sqoop-1.4.6-cdh5.5.2.tar.gz
mv sqoop-1.4.6-cdh5.5.2 sqoop
配置环境变量:
vi etc/profile
保存配置:source /etc/profile
配置sqoop-env.sh
cd /opt/mysoft/sqoop/conf
mv sqoop-env-template.sh sqoop-env.sh
vi sqoop-env.sh
拷贝Mysql jar包到sqoop/lib
Mysql导入到HDFS:
导入全表:
sqoop import --connect jdbc:mysql://192.168.110.6:3306/pingdingshan --username root --password root --target-dir hdfs://qiku1:9000/sqoop --fields-terminated-by ‘\001’ --table book --m 1
连接mysql名为pingdingshan的数据库,用户名和密码,将库中名为book的表名导出到hdfs的/sqoop目录下,以’\001’分隔。
按条件导入表
sqoop import --connect jdbc:mysql://192.168.110.6:3306/pingdingshan --username root --password root --target-dir hdfs://qiku1:9000/sqoop2 --query “select * from shop where total_value>300 and $CONDITIONS” --fields-terminated-by ‘\001’ --m 1
连接pingdingshan数据库,将shop中字段名total_value大于300的记录导入到hdfs的/sqoop2下
备注:and $CONDITIONS 作为条件,必不可少。
参数中, --m 对应mapReduce任务个数 ,为3:输出三个目录文件,为1:输出一个目录文件。
Hive加载
进入hive命令行
选择数据库
创建外部表:
create external table book(id int,book_name string) row format delimited fields terminated by ‘\001’ location ‘hdfs://qiku1:9000/sqoop’;
创建外部表,将hdfs的/sqoop下的数据加载到book表中
备注:这里务必要于从MYSQL导入到HDFS的间隔字符一致
HDFS导出到MySQL
sqoop export --connect ‘jdbc:mysql://192.168.110.6:3306/pingdingshan?useUnicode=true&characterEncoding=utf-8’ --username root --password root --table book2 --export-dir /sqoop --input-fields-terminated-by ‘\001’
注意:间隔要与HDFS一致。
Sqoop1 导入脚本
借助编写脚本文件批量导入,需要先做如下处理:
1: 编辑/opt/mysoft/sqoop/bin/configure-sqoop
删除或者注释掉如下内容:否则在调用脚本文件时,提示对应错误
然后再次重启Hadoop
编写脚本文件
vi yjy.sh
#!/bin/bash
#source /etc/profile
export JAVA_HOME=/opt/mysoft/jdk
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
#set hadoop env
export HADOOP_HOME=/opt/mysoft/hadoop
export PATH=${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:$PATH
#set hive env
export SQOOP_HOME=/opt/mysoft/sqoop
export PATH=${SQOOP_HOME}/bin:$PATH
sheng=('11%' '12%' '13%' '14%' '15%' '21%' '22%' '23%' '31%' '32%' '33%' '34%' '35%' '36%' '37%' '41%' '42%' '43%' '44%' '45%' '46%' '50%' '51%' '52%' '53%' '54%' '61%' '62%' '63%' '64%' '65%' '71%')
for s in ${sheng[@]};
do
#--append 适合将每次导入的数据,允许放在同一个目录下
#--split-by 适合选取类型为数字类型的主键,因为sqoop会根据这个取满足条件的所有记录中的最大主键值和最小主键值,然后 (max1-min1)/2 ,数据均匀分布到 map任务上,避免数据倾斜,所以不适合选字符类型
sql="select * from pingdingshan.ceb2_invt_head_qiku where buyer_id_number like '$s' and \$CONDITIONS"
sqoop import --append --connect jdbc:mysql://192.168.110.6:3306/hnblc --username root --password root --query "${sql}" --fields-terminated-by '\001' --target-dir hdfs://qiku1:9000/invt/head/$s --split-by decl_time --m 2
done
备注:一般的:–split-by field1 --m 3 ,一般都会选取filed1为主键的字段(且为数字类型),因为sqoop的数据分配规则为:select min(field1), max(field1) from myTable where 条件:假如总记录数为600,
然后分配数据,每个任务(假如:–m 3)的总数据记录数为 600/3=200
假如filed1不是数字类型,是字符串,则一般不合适作为split-by 对象()
调用脚本:
sh yjy.sh
查看每台机器上的进程:
发现有 MRAppMaster进程在某一台启动;
另外有执行任务的YarnChild进程 (若导出的—m 2 的化,会发现在集群中同时有两个YarnChild进程在跑: 也可能在同一个机器上执行两个yarnChild,前提是本机器资源足够大(内存+cpu cores):注意一定要注意数据足够大,不能这个进程几秒执行完,还没来得及jps)