目录

  • Sqoop
  • Sqoop安装
  • 数据迁移
  • 导入表到HDFS
  • 通过where语句过滤导入表
  • 导入指定列
  • query查询导入数据
  • 错误解决


Sqoop

用途
Sqoop是一个用于在hadoop和关系数据库之间传输数据的工具。它可以将数据从RDBMS导入到HDFS。例如:HDFS、Hive、HBase。也可以从HDFS导出数据到RDBMS。Sqoop使用MapReduce导入和导出数据,提供并行操作和容错。

Sqoop安装

在安装Sqoop之前,确保已经安装了java、Hadoop、Zookeeper、HBase和Hive。如果还未装可以参考我以前的博文。本文安装的版本是1.4.6版本。

1、上传安装包到虚拟机:

hadoop 拷贝文件命令 hadoop数据导入_Sqoop


2、解压安装包到指定目录,并修改名称

tar -zxvf sqoop-1.4.6-cdh5.14.2.tar.gz -C /opt/
mv sqoop-1.4.6-cdh5.14.2/ sqoop

3、配置环境变量

vi /etc/profile

添加如下内容:

#路径
export SQOOP_HOME=/opt/sqoop
export PATH=$SQOOP_HOME/bin:$PATH

然后 source /etc/profile使配置生效。
(如果不配置环境变量,每次使用时需要在sqoop-import前加上sqoop的bin目录路径)
4、进入到sqoop下的conf文件,
重命名:sqoop-env-template.sh

mv sqoop-env-template.sh sqoop-env.sh

然后修改其内容:

export HADOOP_COMMON_HOME=/opt/hadoop
export HADOOP_MAPRED_HOME=/opt/hadoop
export HBASE_HOME=/opt/hbase
export HIVE_HOME=/opt/hive
export ZOOCFGDIR=/opt/zkpr
export ZOOKEEPER_HOME=/opt/zkpr

保存退出。
5、拷贝JDBC驱动
将JDBC驱动拷贝到sqoop的lib目录下

cp /opt/hive/lib/mysql-connector-java-5.1.38.jar /opt/sqoop/lib/

6、在虚拟机中安装unzip和wget

yum install -y unzip
yum install -y wget

7、进入到lib目录下,下载json的jar包:

wget http://www.java2s.com/Code/JarDownload/java-json/java-json.jar.zip

unzip解压

unzip java-json.jar.zip

hadoop 拷贝文件命令 hadoop数据导入_hadoop_02


目的是为了防止在执行语句的时候报下列异常:

Exception in thread “main” java.lang.NoClassDefFoundError:
org/json/JSONObject

8、通过sqoop help验证sqoop是否安装成功

sqoop help

hadoop 拷贝文件命令 hadoop数据导入_mysql_03


出现的警告信息可以忽略,出现下半部分的帮助命令即成功。

如果你想看的更舒服一点,可以用下面的办法把警告取消掉:

到sqoop 的bin目录下,进入configure-sqoop文件,找打出警告的提示信息然后把这三个内容用

:<<! !

的方式注释掉

:<<!
## Moved to be a runtime check in sqoop.
if [ ! -d "${HCAT_HOME}" ]; then
  echo "Warning: $HCAT_HOME does not exist! HCatalog jobs will fail."
  echo 'Please set $HCAT_HOME to the root of your HCatalog installation.'
fi

if [ ! -d "${ACCUMULO_HOME}" ]; then
  echo "Warning: $ACCUMULO_HOME does not exist! Accumulo imports will fail."
  echo 'Please set $ACCUMULO_HOME to the root of your Accumulo installation.'
fi
if [ ! -d "${ZOOKEEPER_HOME}" ]; then
  echo "Warning: $ZOOKEEPER_HOME does not exist! Accumulo imports will fail."
  echo 'Please set $ZOOKEEPER_HOME to the root of your Zookeeper installation.'
fi
!

再次执行sqoop help警告就消失了

hadoop 拷贝文件命令 hadoop数据导入_hadoop 拷贝文件命令_04


9、测试Sqoop是否能够连接数据库

sqoop list-databases --connect jdbc:mysql://hadoop01:3306/ --username root --password ok

hadoop01是主机名,username是用户名,password是mysql的密码。

hadoop 拷贝文件命令 hadoop数据导入_数据库_05


出现Mysql的数据库即为能够成功连接。

数据迁移

Sqoop安装成功后,我们就需要进行数据迁移的工作。

导入表到HDFS

sqoop-import \
--connect jdbc:mysql://hadoop01:3306/MySchool \
--driver com.mysql.jdbc.Driver \
--table student \
--username root \
--password ok \
--target-dir /data/work/sqoop \
--m 3

我们来分析一下这串代码:

\是表示换行;

sqoop-import是sqoop import的别名,二者是一样的;hadoop01:3306/MySchool,配置数据库连接为Mysql中的数据库;

table student:表名;

target-dir /data/work/sqoop:导入指定目录(HDFS)

–m 3:–m表示Mapper的数量。

执行成功后,我们可以登录HDFS查看一下上传的内容:

hadoop 拷贝文件命令 hadoop数据导入_Sqoop_06


hadoop 拷贝文件命令 hadoop数据导入_mysql_07


可以看到默认生成了四份文件,Sqoop把表格内容按一定规则分到这四个文件中,因为我的数据比较少,所以这里有两个文件的内容是空的,没有内分配到。我们可以到linux中查看相关的文件信息:

hdfs dfs -cat /data/work/sqoop/part-m-00003

hadoop 拷贝文件命令 hadoop数据导入_Sqoop_08

通过where语句过滤导入表

有时候我们可能不需要把所有的数据都上传到HDFS中,此时我们就可以通过where来过滤信息,只导入我们需要的数据。
还是以上述的数据为列,我只要id大于1011的:

sqoop-import \
--connect jdbc:mysql://hadoop01:3306/MySchool \
--driver com.mysql.jdbc.Driver \
--table student \
--where "stu_id>1011" \
--username root \
--password ok \
--delete-target-dir \
--target-dir /data/work/sqoopwhere
--m 3

–where “stu_id>1011” :指定where条件;

–delete-target-dir:如果目标目录存在,则删除;

hadoop 拷贝文件命令 hadoop数据导入_hadoop 拷贝文件命令_09


同一会分成四个文件,查看信息可以看到id为1的已经筛选掉:

hadoop 拷贝文件命令 hadoop数据导入_数据库_10

导入指定列

我们只选择stu_id,stu_name,stu_sex三列作为数据导入

sqoop import \
--connect jdbc:mysql://hadoop01:3306/MySchool \
--table student \
--columns "stu_id,stu_name,stu_sex" \
--username root \
--password ok \
--delete-target-dir \
--target-dir /data/work/sqoopColumn

我这里省略了–driver com.mysql.jdbc.Driver

columns “stu_id,stu_name,stu_sex”:我们所选取的列

hadoop 拷贝文件命令 hadoop数据导入_数据库_11


hadoop 拷贝文件命令 hadoop数据导入_hadoop_12

query查询导入数据

我们把姓李的数据导入:

sqoop import \
--connect jdbc:mysql://hadoop01:3306/MySchool \
--query "select * from student where stu_name like '李%' and \$CONDITIONS" \
--username root \
--password ok \
--split-by stu_id \
--delete-target-dir \
--target-dir /data/work/sqoopQuery
--m 3

当我们查询的时候,可以省略–table;

所有的查询都应该以 $CONDITIONS结束。即使没有查询条件也要 where $CONDITIONS.sqoop内部使用该条件将记录范围分发给所有Mapper。使用query查询,一定使用双引号,不能使用单引号

split-by stu_id :指定用于分割数据的列为stu_id,不可省略。

假如我们有30条数据,那么在我们插入的数据的时候会按照stu_id平均分成3份(–m 3 )。

对于指定的划分字段也要根据实际情况指定。假如一个订单表,其中包括时间和订单量两列。第一天订单量为10,第二天为20,第三天为30,此时如果以天数为划分,那么就会造成划分的不均,所以在指定划分时也要考虑下这方面的问题。

hadoop 拷贝文件命令 hadoop数据导入_Sqoop_13


hadoop 拷贝文件命令 hadoop数据导入_hadoop 拷贝文件命令_14

错误解决

1、第一次使用时,如果报访问被拒的错误:

java.sql.SQLException: Access denied for user 'root'@'192.168.136.221' (using password: YES) 可以在mysql中设置远程连接的权限:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'ok' WITH GRANT OPTION;

2、遇到密码过期的问题:
可以进入mysql的user库,查看到期的host

select user,host,Password,password_expired from user;

hadoop 拷贝文件命令 hadoop数据导入_hadoop_15


Y表示到期,这时我们可以重新设置为N;

update user set password_expired ='N'

3、导入数据到HDFS时,报错:

Exception in thread "main" java.lang.NoClassDefFoundError: org/json/JSONObject

缺少相应的jar包,上传java-json.jar包到sqoop的lib目录下
jar包链接 提取码:v7tj