sqoop是一款用于结合关系型数据库和hdfs(hive/hbase)的数据库之间数据相互传递的工具,可以将mysql/oracle等数据库中存在的表通过sqoop来传递给hive或着是hbase,同样也可以将hive或者是hbase中的表格传递给sqoop中,非常好用。此博客介绍sqoop的版本为1.4.6,主要涉及安装和使用:
sqoop作用
sqoop原理
把用户的指令解析编译成MR任务,发布到yarn上分布式执行
MR任务把输入和输出分别对接RDBMS和Hadoop就能完成数据的转移
sqoop版本
sqoop1:
1. 核心组件:TaskTranslator,解析编译用户指令,生成mr任务发布到yarn
2. cli、api :和用户交互,从用户接受命令,把命令发送给TaskTranslator
3. 优点:简单、灵活、易用,不需要做什么配置,指令即配置,指令可以马上执行
4. 缺点:支持shell和java等语言,对于其他语言无法支持
sqoop2
1. server端:
a)核心组件:TaskTranslator,解析编译用户指令,生成mr任务发布到yarn
b)Connector连接存储系统的中间组件
c)Metadata:
1)存储用户跟存储系统的连接信息:link
2)存储数据导入导出的指令信息:Job
d)RestServer:
1)对外接受客户端的服务
2)接受客户端的连接,接受客户端的指令,把指令发送给TaskTranslator
e)UiServer:对外接受客户端的服务
2. client端:cli、api、webui
3. 优点:
a)通用更强
b)会记录元数据包括存储系统连接信息和任务配置信息等
4. 缺点:
a)步骤稍显麻烦
b)对记录的连接需要使用Connector来连接
和sqoop一起工作的组件:
mysql(传统关系型数据库 )、hdfs(集群)、hive(安装在一个节点)、hbase(集群)、zookeeper
1. 下载 sqoop-1.4.6
2. 上次Linux,解压sqoop-1.4.6
[hadoop@hadoop01 ~]$ tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz
3. 设置环境变量
[hadoop@node1 ~]$ sudo vi /etc/profile
(以下是我的配置文件,仅供参考,你也可以在家目录下修改 .bash_profile文件,此文件也可以作为用户配置文件)
export JAVA_HOME=/home/hadoop/jdk1.7.0_67
export HADOOP_HOME=/home/hadoop/hadoop-2.7.1
export ZK_HOME=/home/hadoop/zookeeper-3.4.6
export HIVE_HOME=/home/hadoop/apache-hive-1.2.1-bin
export HBASE_HOME=/home/hadoop/hbase-1.1.2
export SQOOP_HOME=/home/hadoop/sqoop-1.4.6.bin__hadoop-2.0.4-alpha
export PATH=$PATH:${JAVA_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:${ZK_HOME}/bin:${HIVE_HOME}/bin:${HBASE_HOME}/bin:${SQOOP_HOME}/bin
4. 验证sqoop安装是否成功
[hadoop@node1 ~]$ sqoop help
(输出结果)
Warning: /home/hadoop/apps/sqoop-1.4.6/../hcatalog does not exist! HCatalog jobs will fail.
Please set $HCAT_HOME to the root of your HCatalog installation.
Warning: /home/hadoop/apps/sqoop-1.4.6/../accumulo does not exist! Accumulo imports will fail.
Please set $ACCUMULO_HOME to the root of your Accumulo installation.
18/12/18 02:51:27 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6
usage: sqoop COMMAND [ARGS]
Available commands:
codegen Generate code to interact with database records
create-hive-table Import a table definition into Hive
eval Evaluate a SQL statement and display the results
export Export an HDFS directory to a database table
help List available commands
import Import a table from a database to HDFS
import-all-tables Import tables from a database to HDFS
import-mainframe Import datasets from a mainframe server to HDFS
job Work with saved jobs
list-databases List available databases on a server
list-tables List available tables in a database
merge Merge results of incremental imports
metastore Run a standalone Sqoop metastore
version Display version information
See 'sqoop help COMMAND' for information on a specific command.
5. 设置 sqoop-1.4.6/conf 目录下配置文件
[hadoop@node1 ~]$ cp sqoop-env-template.sh sqoop-env.sh
[hadoop@node1 ~]$ vim sqoop-env.sh
(以下是我的配置文件,仅供参考)
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/home/hadoop/apps/hadoop-2.7.6
#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/home/hadoop/apps/hadoop-2.7.6
#set the path to where bin/hbase is available
export HBASE_HOME=/home/hadoop/apps/hbase-1.2.6
#Set the path to where bin/hive is available
export HIVE_HOME=/home/hadoop/apps/apache-hive-2.3.2-bin
#Set the path for where zookeper config dir is
export ZOOCFGDIR=/home/hadoop/apps/zookeeper-3.4.10/conf
[hadoop@node1 ~]$ vim sqoop-site.xml
(不进行配置)
6. 复制需要的 jar 包到目录 sqoop-1.4.6/lib 下
(以下命令参考)
[hadoop@node1 ~]$ cp $HADOOP_HOME/share/hadoop/common/hadoop-common-2.7.6.jar $SQOOP_HOME/lib
拷贝mysql的驱动包到sqoop的lib下:
[hadoop@node1 ~]$ cp mysql-connector-java-5.1.37-bin.jar $SQOOP_HOME/lib
注意:mysql-connector-java-5.1.37-bin.jar这个包很有用
7. 验证:
sqoop list-databases \
--connect jdbc:mysql://localhost:3306/ \
--username root \
--password root
Available commands:
codegen Generate code to interact with database records
create-hive-table Import a table definition into Hive
eval Evaluate a SQL statement and display the results
export Export an HDFS directory to a database table
help List available commands
import Import a table from a database to HDFS
import-all-tables Import tables from a database to HDFS
import-mainframe Import datasets from a mainframe server to HDFS
job Work with saved jobs
list-databases List available databases on a server
list-tables List available tables in a database
merge Merge results of incremental imports
metastore Run a standalone Sqoop metastore
version Display version information
See 'sqoop help COMMAND' for information on a specific command.
翻译:
codegen 生成java代码 pojo
create-hive-table 导入数据到hive表中
eval
export 导出
help
import 导入 关系型数据库----大数据平台
import-all-tables 将库下的所有的表导入hdfs
import-mainframe Import datasets from a mainframe server to HDFS
job Work with saved jobs
list-databases 显示所有数据库
list-tables 显示所有表
merge Merge results of incremental imports
metastore Run a standalone Sqoop metastore
version 版本信息
导入:
--connect 指定数据库链接url
--username 指定数据库的用户名
--password 指定数据库的密码
--table 指定要导出数据的mysql数据库表
-m 指定MapTask的个数
--target-dir 指定导出数据在HDFS上的存储目录
--fields-terminated-by 指定每条记录中字段之间的分隔符
--where 指定查询SQL的where条件
--query 指定查询SQL
--columns 指定查询列
一、sqoop数据导入:
help_keyword
--connect mysql连接url
--driver 驱动 (不需要指定)
--username mysql的用户名
--password mysql的密码
-m maptask的并行度
1) mysql 导入 hdfs
a) --table 用于指定mysql中的表
sqoop import \
--connect jdbc:mysql://localhost:3306/mysql \ mysql连接url
--username root \ mysql的用户名
--password 123456 \ mysql的密码
--table help_keyword \ 指定mysql中的表
-m 2 maptask的并行度
(默认路径:/user/hive/warehouse;默认的分割符:)
b) --fields-terminated-by:指定分割符 --target-dir:指定存储路径
sqoop import \
--connect jdbc:mysql://localhost:3306/mysql \
--username root \
--password 123456 \
--target-dir hdfs://bd1804/sqoop/target \ 指定路径
--fields-terminated-by '\t' \ 指定分隔符
--table help_keyword \
-m 2
c) 导出过滤条件的:select ....from....where:指定过滤条件
sqoop import \
--connect jdbc:mysql://localhost:3306/mysql \
--username root \
--password 123456 \
--where "name='JOIN'" \ where 指定过滤条件
--target-dir hdfs://bd1804/sqoop/target00 \
--fields-terminated-by '\t' \
--table help_keyword \ table 指定表
-m 2
d) sql语句进行导入:-e --query指定sql语句 --split-by指定maptask的切分字段
sqoop import \
--connect jdbc:mysql://localhost:3306/mysql \
--username root \
--password 123456 \
--target-dir hdfs://bd1804/sqoop/target01 \
--query "select help_keyword_id,name from help_keyword where \$CONDITIONS and name = 'JOIN'" \ 指定sql语句
--split-by help_keyword_id \ 指定maptask切分字段
--fields-terminated-by '\t' \ 指定分隔符
-m 4
(注意:1. where过滤条件后面必须跟$CONDITIONS
2. 单引号$CONDITIONS 不需要转义 “” $需要转义
3. --query和--table不可以同时使用
另,注意点:1.--split-by对非数字类型的字段支持不好。一般用于主键
及数字类型的字段。假设有一张表test,sqoop命令中--split-by 'id',
-m 10,会发生怎样奇特的事情。首先呢,sqoop会去查表的元数据等等,
重点说一下sqoop是如何根据--split-by进行分区的。首先sqoop会向关系
型数据库比如mysql发送一个命令:select max(id),min(id) from test。
然后会把max、min之间的区间平均分为10分,最后10个并行的map去找数据
库,导数据就正式开始啦!
)
e) --where 和 --columns 一起使用,指定字段导入
sqoop import \
--connect jdbc:mysql://localhost:3306/mysql \
--username root \
--password 123456 \
--columns "name" \ 指定字段导入
--where "name='JOIN'" \
--table help_keyword \
--target-dir hdfs://bd1804/sqoop/target03 \
-m 3
2) mql 导入 hive
(注意:Sqoop 导入关系型数据到 hive 的过程是先
导入到 hdfs,然后再 load 进入 hive)
a) 普通导入
示例1:
sqoop import \
--connect jdbc:mysql://hadoop02:3306/mysql \
--username root \
--password root \
--table help_keyword \
--hive-import \
-m 1
(注意:导入数据到 hive 表,默认表在 default 库下,表名一样,采用'\u0001'分隔)
示例2:
sqoop import \
--connect jdbc:mysql://hadoop02:3306/mysql \
--username root \
--password root \
--table help_keyword \
--fields-terminated-by "\t" \
--lines-terminated-by "\n" \
--hive-import \
--hive-overwrite \
--create-hive-table \
--hive-table mydb_test.new_help_keyword \
--delete-target-dir
(注意:表会自动创建,但是库不会。所以在执行该语句之前,
一定要确保 hive 的数据库mydb_test 是存在的,否则程序会报错)
b)增量导入
(增量导入是仅导入表中新添加的行的技术。它需要添加 'incremental',
'check-column', 和 'last-value' 选项来执行增量导入。下面的语法
结构用于 Sqoop 导入命令增量选项。)
示例:
sqoop import \
--connect jdbc:mysql://hadoop02:3306/mysql \
--username root \
--password root \
--table help_keyword \
--target-dir /user/hadoop/myimport3 \
--incremental append \ 指定增量导入
--check-column help_keyword_id \ 指定检查字段
--last-value 500 \ 增量导入的条件
-m 1
(此处结果不包含 help_keyword_id = 500 数据,数据是大于 500 的)
3)mysql 导入 hbase
示例:
sqoop import \
--connect jdbc:mysql://hadoop02:3306/mysql \
--username root \
--password root \
--table help_keyword \
--hbase-table new_help_keyword \
--column-family person \
--hbase-row-key h
字段解释:
--connect jdbc:mysql://hadoop04:3306/mysql 表示远程或者本地 Mysql 服务的 URI
--hbase-create-table 表示在 HBase 中建立表。
--hbase-table new_help_keyword 表示在 HBase 中建立表 new_help_keyword。
--hbase-row-key help_keyword_id 表示hbase表的rowkey是mysql表的help_keyword_id 字段
--column-family person 表示在表 new_help_keyword 中建立列族 person。
--username 'root' 表示使用用户 root 连接 mysql。
--password 'root' 连接 mysql 的用户密码
--table help_keyword 表示导出 mysql 数据库的 help_keyword 表。
二、数据导出
1) hdfs 导入 mysql
Export 常用参数:
--direct 快速导入
--export-dir HDFS 到处数据的目录
-m,--num-mappers 都少个 map 线程
--table 导出哪个表
--call 存储过程
--update-key 通过哪个字段来判断更新
--update-mode 插入模式,默认是只更新,可以设置为 allowinsert.
--input-null-string 字符类型 null 处理
--input-null-non-string 非字符类型 null 处理
--staging-table 临时表
--clear-staging-table 清空临时表
--batch 批量模式
步骤:
第一步:查看要导入mysql的数据:hadoop dfs -tail 文件名
第二步:在mysql表中建表
第三步:执行导出命令
示例:
sqoop export \
--connect jdbc:mysql://hadoop02:3306/sqoopdb \
--username root \
--password root \
--table sqoopstudent \
--export-dir /sqoopdata \
--fields-terminated-by ','
(注意:如果导出数据到 mysql 出现乱码,那么请参考这个解决方案:
https://my.oschina.net/u/559635/blog/498990)
2) hive 导入 mysql
sqoop export \
--connect jdbc:mysql://hadoop02:3306/sqoopdb \
--username root \
--password root \
--table uv_info \
--export-dir /user/hive/warehouse/uv/dt=2011-08-03 \
--input-fields-terminated-by '\t
(注意:其实跟直接导出 HDFS 数据到 MySQL 没什么两样)
3) Hbase 导入 mysql
很遗憾,现在还没有直接的命令将 HBase 的数据导出到 MySQL,一般采用如下 3 种方法:
1、将 Hbase 数据,扁平化成 HDFS 文件,然后再由 sqoop 导入
2、将 Hbase 数据导入 Hive 表中,然后再导入 mysql
3、直接使用 Hbase 的 Java API 读取表数据,直接向 mysql 导入,不需要使用 sqoop
1)sqoop导入原理
我们能得出一个结论,sqoop 工具是通过 MapReduce 进行导入作业的,sqoop进行数据导入流程大致可以用下面文字描述:
1、第一步,Sqoop 会通过 JDBC 来获取所需要的数据库元数据,例如,导入表的列名,数据类型等。
2、第二步,这些数据库的数据类型(varchar, number 等)会被映射成 Java 的数据类型(String, int等),根据这些信息,Sqoop 会生成一个与表名同名的类用来完成序列化工作,保存表中的 Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513每一行记录。
3、第三步,Sqoop 启动 MapReducer 作业
4、第四步,启动的作业在 input 的过程中,会通过 JDBC 读取数据表中的内容,这时,会使用 Sqoop 生成的类进行反序列化操作
5、第五步,最后将这些记录写到 HDFS 中,在写入到 HDFS 的过程中,同样会使用 Sqoop 生成的类进行反序列化
2)sqoop导出原理
Sqoop 进行数据导出,总体也是基于 mapreduce 任务。也可以描述为以下5步:
1、第一步,sqoop 依然会通过 JDBC 访问关系型数据库,得到需要导出数据的元数据信息
2、第二步,根据获取到的元数据的信息,sqoop 生成一个 Java 类,用来进行数据的传输载体。该类必须实现序列化和反序列化
3、第三步,启动 mapreduce 作业
4、第四步,sqoop 利用生成的这个 java 类,并行的从 hdfs 中读取数据
5、第五步,每个 map 作业都会根据读取到的导出表的元数据信息和读取到的数据,生成一批 insert 语句,然后多个 map 作业会并行的向数据库 mysql 中插入数据
(注意:所以,数据是从 hdfs 中并行的进行读取,也是并行的进入写入,那并行的读取是依赖 hdfs的性能,而并行的写入到 mysql 中,那就要依赖于 mysql 的写入性能了。)
1)import的主要参数
--connect jdbc连接地址
--connection-manager 连接管理者
--driver 驱动类
--hadoop-mapred-home $HADOOP_MAPRED_HOME
--help help信息
-P 从命令行输入密码
--password 密码
--username 账号
--verbose 打印信息
--connection-param-file 可选参数
Argument : Description :
--append 添加到hdfs中已经存在的dataset
--as-avrodatafile 导入数据作为avrodata
--as-sequencefile 导入数据位SequenceFiles
--as-textfile 默认导入数据为文本
--boundary-query 创建splits的边界
--columns 选择列
--direct 使用直接导入快速路径
--direct-split-size 在快速模式下每n字节使用一个split
--fetch-size 一次读入的数量
--inline-lob-limit 最大数值 an inline LOB
-m,--num-mappers 通过实行多少个map,默认是4个,某些数据库8 or 16性能不错
-e,--query 通过查询语句导入
--split-by 创建split的列,默认是主键
--table 要导入的表名
--target-dir HDFS 目标路径
--warehouse-dir HDFS parent for table destination
--where where条件
-z,--compress Enable compression
--compression-codec 压缩方式,默认是gzip
--null-string 字符列null值
--null-non-string 非字符列null值
2)export主要参数
--direct 快速导入
--export-dir HDFS到处数据的目录
-m,--num-mappers 都少个map线程
--table 导出哪个表
--call 存储过程
--update-key 通过哪个字段来判断更新
--update-mode 插入模式,默认是只更新,可以设置为allowinsert.
--input-null-string 字符类型null处理
--input-null-non-string 非字符类型null处理
--staging-table 临时表
--clear-staging-table 清空临时表
--batch 批量模式
3)转义字符相关参数。
Argument : Description :
--enclosed-by 设置字段结束符号
--escaped-by 用哪个字符来转义
--fields-terminated-by 字段之间的分隔符
--lines-terminated-by 行分隔符
--mysql-delimiters 使用mysql的默认分隔符: , lines: \n escaped-by: \ optionally-enclosed-by: '
--op
1. pg库导入hive
#!/bin/bash
source /etc/profile
source ./bash_profile
#connection info
#数据库ip
ip=10.20.129.20
#数据库port
port=1234
#数据库名称
db=dbname
#DB账号
username=username
#密码
password=password
#pg数据库表名
src_table=tablename
#hive表数据库
tar_db=spark_graphx
#hives表表名
tar_table=tablename
#pg_connect
connect=jdbc:postgresql://$ip:$port/$db
echo "*******************run sqoop********************"
sqoop import "-Dorg.apache.sqoop.splitter.allow_text_splitter=true" \
--connect $connect \
--username $username \
--password $password \
--query "select * from $table where \$CONDITIONS" \ #一定要加上 where \$CONDITIONS
--delete-target-dir \
--hive-database $tar_db \
--hive-table $tar_table \
--hive-import \
--target -dir /input/$tar_table \ #可以省略,为默认路径
-m 10 \
--split-by id
2. hive导入pg数据库
#!/bin/bash
source /etc/profile
source ./bash_profile
#connection info
#数据库ip
ip=10.20.129.20
#数据库port
port=1234
#数据库名称
db=dbname
#DB账号
username=username
#密码
password=password
#pg数据库表名
tar_table=tablename
#hive表数据库
src_db=spark_graphx
#hives表表名
src_table=tablename
#pg_connect
connect=jdbc:postgresql://$ip:$port/$db
hdfspath=hdfs://aicrs/user/hive/warehouse
hive_dbname=spark_graphx
echo "**********************想 pg 导入数据*****************************"
sqoop export \
--connect $connect \
--username $username \
--password $password \
--table $tar_table \
--export-dir $hdfspath/spark_graphx.db/give_credit \
--columns "id,name,age" \ #为数据库中的字段名称
--input-null-string '\\\\N' \
--input-null-non-string '\\\N' \
--input-fields-terminated-by "#" \
-m 30
(注意:hive导入到pg或mysql数据库中,需要在pg或mysql数据库中先建好表)
加:使用sqoop导mysql数据到hive中报错问题参考:
http://www.cnblogs.com/harrymore/p/9057096.html#_labelTop