Sqoop使用
# sql to hadoop
导出数据:从Hadoop 的文件系统中导出数据到关系数据库mysql 等 Sqoop的本质还是一个命令行工具,和HDFS,Hive 相比,并没有什么高深的理论。
测试连接
sqoop list-databases --connect jdbc:mysql://hadoop100 --username root --password 123456789
把数据导入hdfs
sqoop import --connect jdbc:mysql://8.8.8.100/test --username root --password 123456789 --table emp --delete-target-dir
sqoop import \
--connect jdbc:mysql://8.8.8.100/test \
--username root \
--password 123456789 \
--table emp \
--delete-target-dir
sqoop import \
--connect jdbc:mysql://hadoop100:3306/test \
--username root \
--password 123456789 \
--table emp \
--target-dir /user/test \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
数据导入到hive
sqoop import \
--connect jdbc:mysql://hadoop100:3306/test \
--username root \
--password 123456789 \
--table emp \
--num-mappers 1 \
--hive-import \
--fields-terminated-by "\t" \
--hive-overwrite \
--hive-table emp_hive
数据导入hbase(手动建表)
sqoop import \
--connect jdbc:mysql://hadoop100:3306/test \
--username root \
--password 123456789 \
--table emp \
--columns "id,name,degree,salary,dept" \
--column-family "info" \
--hbase-create-table \
--hbase-row-key "id" \
--hbase-table "hbase_emp" \
--num-mappers 1 \
--split-by id
hdfs数据导出
先建表
sqoop export --connect "jdbc:mysql://192.168.94.137/test?useUnicode=true&characterEncoding=utf-8" --username root -password lishy2019 --export-dir /user/root/emp1/part-m-00000 --table EMP --fields-terminated-by ','
sqoop作业
# 1.导入数据
在Sqoop中,“导入”概念指:从非大数据集群(RDBMS)向大数据集群(HDFS,HIVE,HBASE)中传输数据,叫做:导入,即使用import关键字。
# 关系型数据库(RDBMS)导入到HDFS
在mysql新建一张表并插入数据
mysql -uroot -p123456789
create database company;
create table company.staff(
id int(4) primary key not null auto_increment,
name varchar(255),
sex varchar(255));
insert into company.staff(name, sex) values('Thomas', 'Male');
insert into company.staff(name, sex) values('Catalina', 'FeMale');
关系型数据库到HDFS
全部导入
bin/sqoop import \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--table staff \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
查询导入
bin/sqoop import \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query 'select name,sex from staff where id <=1 and $CONDITIONS;'
如果query后使用的是双引号,则$CONDITIONS前必须加转移符,防止shell识别为自己的变量。
导入指定列
bin/sqoop import \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns id,sex \
--table staff
使用sqoop关键字筛选查询导入数据
bin/sqoop import \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--table staff \
--where "id=1"
[banana@hadoop100 ~]$ sqoop import --connect jdbc:mysql://8.8.8.100/test --username root --password 123456789 --table emp --delete-target-dir 省略一万字 20/03/30 15:27:08 ERROR tool.ImportTool: Import failed: No primary key could be found for table emp. Please specify one with --split-by or perform a sequential import with '-m 1'. 原因:未加参数--num-mappers 提示可以看出,在我们从mysql中导出的表没有设定主键,提示我们使用把--split-by或者把参数-m设置为1,这里大家会不会问到,这倒是是为什么呢? Sqoop通可以过–split-by指定切分的字段,–m设置mapper的数量。通过这两个参数分解生成m个where子句,进行分段查询。 split-by 根据不同的参数类型有不同的切分方法,如表共有100条数据其中id为int类型,并且我们指定–split-by id,我们不设置map数量使用默认的为四个,首先Sqoop会取获取切分字段的MIN()和MAX()即(–split -by),再根据map数量进行划分,这是字段值就会分为四个map:(1-25)(26-50)(51-75)(75-100)。 根据MIN和MAX不同的类型采用不同的切分方式支持有Date,Text,Float,Integer, Boolean,NText,BigDecimal等等。 所以,若导入的表中没有主键,将-m 设置称1或者设置split-by,即只有一个map运行,缺点是不能并行map录入数据。(注意,当-m 设置的值大于1时,split-by必须设置字段) 。 split-by即便是int型,若不是连续有规律递增的话,各个map分配的数据是不均衡的,可能会有些map很忙,有些map几乎没有数据处理的情况。 ———————————————— 原文链接(错误集锦):https://blog.csdn.net/yu0_zhang0/article/details/79069251
# 关系型数据库(RDBMS)到Hive
bin/sqoop import \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--table staff \
--num-mappers 1 \
--hive-import \
--fields-terminated-by "\t" \
--hive-overwrite \
--hive-table staff_hive
该过程分为两步,第一步将数据导入到HDFS,第二步将导入到HDFS的数据迁移到Hive仓库,第一步默认的临时目录是/user/用户名/表名
ERROR hive.HiveConfig: Could not load org.apache.hadoop.hive.conf.HiveConf. Make sure HIVE_CONF_DIR is set correctly 原因: 未设置HIVE_CONF_DIR vim ~/.bashrc hive环境变量配置 export HIVE_HOME=/soft/hive export HIVE_CONF_DIR=$HIVE_HOME/conf export PATH=$PATH:$HIVE_HOME/bin
20/03/29 20:40:06 INFO ipc.Client: Retrying connect to server: 0.0.0.0/0.0.0.0:10020. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS) Caused by: java.net.ConnectException: Your endpoint configuration is wrong; 原因:主机10020端口连接不上,应该是hadoop集群中datanode访问namenode的10020端口的问题,使用10020端口是jobhistory服务,在检查配置文件mapred-site.xml未发现错误
mapreduce.jobhistory.address 主机名:10020 执行$HADOOP_HOME/sbin/mr-jobhistory-daemon.sh start historyserver 主机10020端口开放 mapreduce.jobhistory.webapp.address 主机名:19888
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf 原因:缺少了hive-common-2.3.3.jar包,在hive的lib目录下,拷贝到sqoop的lib目录下即可。 cp /soft/hive/lib/hive-common-2.3.6.jar /soft/sqoop/lib/ hbase环境变量配置配置 export HBASE_HOME=/soft/hbase export PATH=$PATH:$HBASE_HOME/bin Zookeeper环境变量配置 export ZOOKEEPER_HOME=/soft/zookeeper export PATH=$ZOOKEEPER_HOME/bin:$PATH
# RDBMS到Hbase
bin/sqoop import \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--table staff \
--columns "id,name,sex" \
--column-family "info" \
--hbase-create-table \
--hbase-row-key "id" \
--hbase-table "hbase_company" \
--num-mappers 1 \
--split-by id
若没有自动创建 需手动创建
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.hbase.client.HBaseAdmin.
(Lorg/apache/hadoop/conf/Configuration;) 我已经将以下提到的jar手动添加到SQOOP_HOME/lib中- 1: hbase-client-1.2.0.jar 2: hbase-common-1.2.0.jar 3: hbase-mapreduce-2.2.0.jar 4: hbase-protocol-1.2.0.jar 5: hbase-server-1.2.0.jar 6: hbase-zookeeper-2.2.0.jar 7: protobuf-java-2.5.0.jar
版本不兼容???(sqoop1.4.7手动创建都不好使???) sqoop1.4.6只支持hbase1.0.1之前的版本自动创建表
# 2.导出数据
# HIVE/HDFS到RDBMS
bin/sqoop export \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--table staff1 \
--num-mappers 1 \
--export-dir /user/hive/warehouse/staff_hive \
--input-fields-terminated-by "\t"
MySQL表如果不存在 不会自动创建?useUnicode=true&characterEncoding=utf-8
# sqoop job
sqoop job命令的基本用法:
- 创建job:--create
- 删除job:--delete
- 执行job:--exec
- 显示job:--show
- 列出job:--list
创建一个job(注意-- import中间有个空格,切勿忽视)
sqoop job --create firstjob \
-- import \
--connect jdbc:mysql://hadoop1:3306/company \
--username root \
--password 123456789 \
--table staff \
--target-dir /user/test \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
sqoop job --list
# Sqoop job安全配置
默认情况下,创建的每个job在运行的时候都不会进行安全的认证。如果我们希望限制指定的sqoop job的执行,只有经过认证以后才能执行,这时候可以使用sqoop job的安全选项。Sqoop安装目录下,通过修改配置文件conf/sqoop-site.xml可以对job进行更高级的配置。实际上,我们使用了Sqoop的metastore工具,它能够对Sqoop进行细粒度的配置。 我们要将MySQL数据库中的数据同步到Hive表,每次执行sqoop job都需要输入访问MySQL数据库的连接账号信息,可以设置sqoop.metastore.client.record.password的值为true。如果在conf/sqoop-site.xml中增加如下配置,会将连接账号信息存储到Sqoop的metastore中:
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
<description>If true, allow saved passwords in the metastore. </description>
</property>
如果想要限制从外部调用执行Sqoop job,如将Sqoop job提交给Oozie调度程序,也会通过上面Sqoop的metastore配置的内容来进行验证。 另外,Sqoop的metastore工具,可以允许我们指定为外部,例如使用外部主机上的MySQL数据库来存储元数据,可以在conf/sqoop-site.xml配置如下:
<property>
<name>sqoop.metastore.client.autoconnect.url</name>
<value>jdbc:mysql://10.95.3.49:3306/sqoop_metastore</value>
<description>The connect string to use when connecting to a
job-management metastore. If unspecified, uses ~/.sqoop/.
You can specify a different path here.
</description>
</property>
<property>
<name>sqoop.metastore.client.autoconnect.username</name>
<value>shirdrn</value>
<description>The username to bind to the metastore.
</description>
</property>
<property>
<name>sqoop.metastore.client.autoconnect.password</name>
<value>108loIOL</value>
<description>The password to bind to the metastore.
</description>
</property>
还有一个可与选择的配置项是,可以设置是否自动连接到外部metastore数据库,通过如下配置指定:
<property>
<name>sqoop.metastore.client.enable.autoconnect</name>
<value>false</value>
<description>If true, Sqoop will connect to a local metastore for job management when no other metastore arguments are provided.
</description>
</property>
# 脚本打包
编写脚本
vim job_HDFS_RDBMS.opt
脚本内容(导出数据到mysql)
export
--connect
jdbc:mysql://hadoop1:3306/company
--username
root
--password
123456789
--table
staff
--num-mappers
1
--export-dir
/user/hive/warehouse/staff_hive
--input-fields-terminated-by
"\t"
执行脚本
bin/sqoop --options-file opt/job_HDFS2RDBMS.opt