Sqoop 的安装及使用
目录
7.4,MySQL to HBase(使用查询方式指定列,控制部分导入)
7.6,MySQL to HDFS(部分导入 --where)
7.7,MySQL to HDFS(部分导入 --columns)
(介绍的Sqoop版本为sqoop-1.4.6-cdh5.15.2)
1,Sqoop 简介
1.1,名词 Sqoop:SQL–to–Hadoop
1.2,Sqoop是一个用来将关系型数据库和Hadoop中的数据进行相互转移的工具(桥梁),可以将一个关系型数据库(例如Mysql、Oracle)中的数据导入到Hadoop(例如HDFS、Hive、Hbase)中,也可以将Hadoop(例如HDFS、Hive、Hbase)中的数据导入到关系型数据库(例如Mysql、Oracle)中
1.3,利用MapReduce,批处理方式进行数据传输
1.4,运行环境:linux、hadoop、zookeeper、hbase、hive,关系型数据库对mysql的支持最好
2,功能
2.1,关系型数据库与非关系型数据库之间的数据转换工具
3,解决的痛点
3.1,大量数据同步任务,耗时居高不下。
3.2,关系型数据库与非关系型数据库之间的同步问题。
3.3,多数使用hadoop技术处理大数据业务的企业,有大量的数据存储在关系型数据中。
3.4,数据量的递增带来的一系列问题等等...
4,sqoop架构图
如上图所示:Sqoop工具接收到客户端的shell命令或者Java api命令后,通过Sqoop中的任务翻译器(Task Translator)将命令转换为对应的MapReduce任务,而后将关系型数据库和Hadoop中的数据进行相互转移,进而完成数据的拷贝。
5,Sqoop的安装及出现的问题
5.1,相关资料
下载地址:http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.6-cdh5.15.2.tar.gz
命令查考:http://sqoop.apache.org/docs/1.4.6/SqoopUserGuide.html
5.2,安装
下载完文件:sqoop-1.4.6-cdh5.15.2.tar.gz
5.3,配置环境变量:
vim /etc/profile
export SQOOP_HOME=/root/opt/sqoop/sqoop-1.4.6-cdh5.15.2
export PATH=$PATH:$SQOOP_HOME/bin
刷新配置:source /etc/profile
5.4,sqoop配置:
cd ${sqoop_home}/conf/
cp sqoop-env-template.sh sqoop-env.sh
修改配置项
vim sqoop-env.sh
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/root/opt/hadoop/hadoop-2.6.0-cdh5.15.2
#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/root/opt/hadoop/hadoop-2.6.0-cdh5.15.2
#set the path to where bin/hbase is available
export HBASE_HOME=/root/opt/hadoop/hadoop-2.6.0-cdh5.15.2
#Set the path to where bin/hive is available
#export HIVE_HOME=
#Set the path for where zookeper config dir is
export ZOOCFGDIR=/root/opt/zookeeper-3.4.10
5.5,相关数据库驱动包上传
上传相关数据库驱动包到lib下,如mysql同步,需要mysql的驱动包 mysql-connector-java-5.1.44-bin.jar
5.6,测试
sqoop help
5.7,去掉相关警告
注释掉 ${sqoop_home}/bin/configure-sqoop 中关于告警的信息或者增加变量配置
6,Sqoop常用参数说明
参数使用 sqoop help 查看
6.1,通用参数
--connect 指定jdbc的连接
--username 数据库用户名
--password 数据库密码
示例:
--password xxx (明文)
--P (交互式的制定数据库密码)
--password-file (密码放在文件中)(验证没有通过,待深入)
6.2,导入控制参数
--query
sqoop import --connect jdbc:mysql://xx.xx.xx.xx:3306/test --username root --password root --query "select * from table-name where id >= xx AND \$CONDITION" --target-dir /hakkero/data_report --m 1
注意:AND \$CONDITION 是必须的,告诉这是带条件的语句
--table tablename --where “id>=xx”
--columns 字段名(列名)
6.3,目的目录
--target-dir /hdfs_paths
6.4,分隔符
--fields-terminated-by '|' 情况下用 ‘,' 进行数据分割
--escaped-by 转义字符
6.5,控制导入的并行度
--m 或者--num-mappers 【int】
控制导入时MR作业的map任务数量,后接一个整数值,用于表示MR的并行度。在进行并行导入的时候,sqoop会使用split-by 进行负载切分(按照标的PK进行切分),首先获取切分字段Max和Min值,在根据Max和Min值去进行切分,举例:--m 4 。mysql.id [1,1000],sqoop会直接使用4个Map任务,如果主键是id可以均匀的进行切分,那么Map任务的压力是一样的;如果不幸,切分字段不是均匀分布的话,会导致任务的不平衡。注意:sqoop目前不能使用多个字段作为切分字段。 应该使用该--split-by参数明确选择其他列。例如,--split-by employee_id。如果您的表没有索引列,或者具有多列键,那么您还必须手动选择一个拆分列。
6.6,类型映射(导入hive时用)
--map-column-hive id=String,age=Int
7,Sqoop的使用场景与案例
7.1,测试数据库连接(交互式输入密码)
sqoop list-databases --connect jdbc:mysql://xx.xx.xx.xx:3306/test --username root -P
7.2,MySQL to HDFS (全表导入)
shell命令中 \ 转义字符串的使用
sqoop import \
--connect jdbc:mysql://xx.xx.xx.xx:3306/test \
--username root \
--password root \
--table table_test \
--target-dir /path \
--m 1
a) 目录不能已存在
b) 没指定-m或splite-by时,表必须有PK
7.3,MySQL to HDFS(增量导入)
使用 文件 存放 命令脚本
${Sqoop_home}/bin 下创建文本(不限制后缀名)
创建文本:touch mysql_to_hdfs.im
编辑文本内容:vim mysql_to_hdfs.im
注意:指令参数各一行,不能有空格
import
--connect
jdbc:mysql://xx.xx.xx.xx:3306/test
--username
root
--password
root
--table
table_test
--split-by
date
--m
1
--target-dir
/hadoop_hdfs/paths
--merge-key
date
--incremental
lastmodified
--check-column
date
--last-value
'2019-09-08'
使用方式:sqoop --options-file mysql_to_hdfs.im
注意:--check-column
用来指定检查列,这些列在增量导入时用来检查这些数据是否作为增量数据进行导入,和关系行数据库中的自增字段及时间戳类似
这些被指定的列的类型不能使用任意字符类型,如char、varchar等类型都是不可以的;
--incremental 参数指定要执行的增量导入的类型(append/lastmodified)
append 追加,应指定模式:可以使用 --check-column (col)指定检查列,--last-value (value) check列的值要大于指定的value。
lastmodified 更新策略,当源表的行可能被更新时,使用此模式,并且每次更新会将上次修改的列的值设置为当前时间戳
7.4,MySQL to HBase(使用查询方式指定列,控制部分导入)
使用--query,必须删除–table参数
sqoop import \
--connect jdbc:mysql://xxx.xx.xx.xx:3306/test \
--username root \
--password root \
--query “select id, date from table_test where \$CONDITIONS” \
--hbase-table mysql_to_hbase_test \
--hbase-create-table \
--hbase-row-key id \
--column-family column1 \
--hbase-bulkload \
--merge-key date \
--incremental lastmodified \
--check-column date \
--last-value '2019-11-06 17:22:47.0'
导入到HBase中之后,字段都在一个列族下
疑问:原来在HBase中存在的表,使用phoenix能查到吗?
7.5,MySQL to HBase(增量导入)
使用job的形式:
sqoop job --create mysql_to_hbase_job_test -- import \
--connect jdbc:mysql://xxx.xx.xx.xx:3306/e=test \
--username root \
--password root \
--query “select id, date from table_test where \$CONDITIONS” \
--hbase-table mysql_to_hbase_test \
--hbase-create-table \
--hbase-row-key id \
--column-family column1 \
--hbase-bulkload \
--merge-key date \
--incremental lastmodified \
--check-column date \
--last-value '2019-11-06 17:22:47.0'
执行job:
sqoop job --exec mysql_to_hbase_job_test
查看job:mysql_to_hbase_job_test
sqoop job --show mysql_to_hbase_job_test
画外音:同步作业中如果用到日期作为条件,可以使用job的方式,自动更新last-value的值,达到同步最新数据的目的
扩展(
显示job作业:sqoop job --list
创建:sqoop job --create xx
删除:sqoop job --delete xx
执行:sqoop job --exec xx
查看:sqoop job --show xx
)
7.6,MySQL to HDFS(部分导入 --where)
sqoop import \
--connect jdbc:mysql://xx.xx.xx.xx:3306/test \
--username root\
--password root \
--table table_test \
--where “id<=5” \
--target-dir /paths \
--m 1
7.7,MySQL to HDFS(部分导入 --columns)
sqoop import \
--connect jdbc:mysql://xx.xx.xx.xx:3306/hakkero \
--username root \
--password root \
--table table_test \
--colums id,date \
--target-dir /paths\
--m 2
8,Sqoop与DataX的比较
DataX功能图:
9,总结
Sqoop的使用成本相比DataX而言较高,环境支撑较为复杂,依赖性强。效率受到两方面的限制:1,架构,受限于node的数据,虽然理论上可以通过增加map的num来提高效率,但是node的机器数就决定了它的最大num值;2,关系型数据的最大连接数,关系型数据库有 主键 且最好是 整型(可以很好地分配map的负载压力),如果用于split 的PK是varchar,会导致负载不均衡,不能很好地分配任务。不支持事务,任务执行失败,同步过后的数据不能回滚。功能与DataX 比较相差不大,支持的数据库类型没有DataX全面。适合已经使用hadoop生态技术,并有同步数据需求的场景。