目录
- 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、上传安装包到虚拟机:
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
目的是为了防止在执行语句的时候报下列异常:
Exception in thread “main” java.lang.NoClassDefFoundError:
org/json/JSONObject
8、通过sqoop help验证sqoop是否安装成功
sqoop help
出现的警告信息可以忽略,出现下半部分的帮助命令即成功。
如果你想看的更舒服一点,可以用下面的办法把警告取消掉:
到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警告就消失了
9、测试Sqoop是否能够连接数据库
sqoop list-databases --connect jdbc:mysql://hadoop01:3306/ --username root --password ok
hadoop01是主机名,username是用户名,password是mysql的密码。
出现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查看一下上传的内容:
可以看到默认生成了四份文件,Sqoop把表格内容按一定规则分到这四个文件中,因为我的数据比较少,所以这里有两个文件的内容是空的,没有内分配到。我们可以到linux中查看相关的文件信息:
hdfs dfs -cat /data/work/sqoop/part-m-00003
通过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:如果目标目录存在,则删除;
同一会分成四个文件,查看信息可以看到id为1的已经筛选掉:
导入指定列
我们只选择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”:我们所选取的列
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,此时如果以天数为划分,那么就会造成划分的不均,所以在指定划分时也要考虑下这方面的问题。
错误解决
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;
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