目录
1 Hub
Hub (Hadoop User Experience)官网:https://gethue.com/
由于大数据框架很多,为了解决某个问题,一般来说会用到多个框架,但是每个框架又都有自己的web UI监控界面,对应着不同的端口号。比如HDFS(50070/9870)、YARN(8088)、MapReduce(19888)等。这个时候有一个统一的web UI界面去管理各个大数据常用框架是非常方便的。这就使得对大数据的开发、监控和运维更加的方便。
Hue是一个开源的Apache Hadoop UI系统,Cloudera为了解决上述的问题,研发设计了Cloudera Desktop,Hue就是由Cloudera Desktop演化而来,最后Cloudera公司将其贡献给Apache基金会的Hadoop社区,它是基于Python Web框架Django实现的。
功能
- 支持基于文件浏览器访问HDFS
- 支持基于Hive编辑器来开发和运行Hive查询
- 支持基于Solr进行搜索的应用,并提供可视化的数据视图,以及仪表板
- 支持基于Impala的应用进行交互式查询
- 支持Spark编辑器和仪表板
- 支持Pig编辑器,并能够提交脚本任务
- 支持Oozie编辑器,可以通过仪表板提交和监控Workflow、Coordinator和Bundle
- 支持HBase浏览器,能够可视化数据、查询数据、修改HBase表
- 支持Metastore浏览器,可以访问Hive的元数据,以及HCatalog
- 支持Job浏览器,能够访问MapReduce Job(MR1/MR2-YARN)
- 支持Job设计器,能够创建MapReduce/Streaming/Java Job
- 支持Sqoop 2编辑器
- 支持ZooKeeper浏览器和编辑器
- 支持MySql、PostGresql、Sqlite和Oracle数据库查询编辑器
- 支持使用sentry基于角色的授权以及多租户的管理
- ……
Hub架构及基本原理
Hue Server:Hue的服务端进程,启动后会开放一个Hue的Web UI,负责接收并处理用户在Web UI上的请求
Hue UI:Hue的Web界面,默认端口为8888,用于提供与用户交互的界面,可以浏览所有集成的服务
Hue DB:Hue的元数据存储,保存Hue中所有连接、配置、操作的信息等等
基本原理:
本质:一个通用的大数据软件的客户端,相当于将Hive、Hadoop、Spark等软件的客户端融合为一个整体
step1:启动Hue Server后,Hue Server会与其他大数据软件的服务端构建连接,并开放Hue UI
step2:用户在Hue UI中进行操作,Hue Server将对应的操作提交给对应软件的服务端进行请求,并将信息记录在Hue DB中
step3:Hue Server将软件服务端的结果展示在Hue UI中返回给用户
2 数据库同步工具Sqoop
Apache Sqoop是在Hadoop生态体系和RDBMS体系之间传送数据的一种工具。来自于Apache软件基金会提供。
Sqoop工作机制是将导入或导出命令翻译成mapreduce程序来实现。在翻译出的mapreduce中主要是对inputformat和outputformat进行定制。
Hadoop生态系统包括:HDFS、Hive、Hbase等
RDBMS体系包括:Mysql、Oracle、DB2等
Sqoop可以理解为:“SQL 到 Hadoop 和 Hadoop 到SQL”。
- Sqoop1版本:单纯的工具,直接实现程序的转换的
- 没有服务端进程,不需要启动进程
- Sqoop2版本:基于Sqoop1的功能之上,引入CS模式【如果用的MySQL版本比较高,建议使用Sqoop2】
Sqoop导入与导出!
2.1 Sqoop导入
1 全量导入MySQL表数据到HDFS
MySQL选项
–connect: 指定连接的RDBMS数据库的地址(JDBC指定)
–username: 指定数据库的用户名
–password: 指定数据库的密码
–table: 指定数据库中的表
–columns: 指定导入的列名
–where: 指定导入行的过滤条件
-e/–query: 指定导入数据的SQL语句,不能与–table一起使用,必须指定where条件,where中必须指定$CONDITIONS
HDFS选项
–target-dir: 指定导入的HDFS路径
–delete-target-dir: 指定如果导入的HDFS路径已存在就提前删除
–fields-terminated-by: 指定导入HDFS的文件中列的分隔符
其他选项
-m: 指定底层MapReduce程序的MapTask的个数
–split-by: MySQL没有主键时,必须添加该参数指定多个MapTask划分数据的方式,MySQL有主键也可以使用该参数
数据准备,插入mysql脚本:
--MySQL中创建一张没有主键的表
use sqoopTest;
CREATE TABLE `tb_tohdfs2` (
`id` int(11) NOT NULL,
`name` varchar(100) NOT NULL,
`age` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--插入数据
insert into tb_tohdfs2 values(1,"laoda",18);
insert into tb_tohdfs2 values(2,"laoer",19);
insert into tb_tohdfs2 values(9,"laosan",20);
insert into tb_tohdfs2 values(100,"laosi",21);
insert into tb_tohdfs2 values(300,"laowu",22);
insert into tb_tohdfs2 values(600,"laoliu",23);
insert into tb_tohdfs2 values(700,"laoqi",24);
insert into tb_tohdfs2 values(800,"laoba",25);
eg:将MySQL中tb_tohdfs2表的id和name导入HDFS的/sqoop/import/test01目录,指定Map个数为2个
[root@hadoop01 ~]# sqoop import \
> --connect jdbc:mysql://hadoop01:3306/sqoopTest \
> --username root \
> --password 123456 \
> --table tb_tohdfs2 \
> --columns id,name \
> --delete-target-dir \
> --target-dir /sqoop/import/test01 \
> --split-by id \
> -m 2
为了验证在HDFS导入的数据,可使用以下命令查看导入的数据:
hdfs dfs -cat /sqoop/import/test01/part-m-00000
注意:指定多个MapTask时,分为两种情况
情况一:如果MySQL表有主键,可以直接指定,自动根据主键的值来划分每个MapTask处理的数据
情况二:如果MySQL表没有主键,会报错,加上--split-by
指定按照哪一列进行划分数据即可
2 spood全量导入MySQL数据到hive
第一次导入用全量导入
Old API
–hive-import: 指定导入数据到Hive,也可更改为–hive-overwrite(overwrite只针对需要覆盖目标表清空)
–hive-database: 指定原生方式导入Hive的数据库名称
–hive-table: 指定原生方式导入的Hive的表名
New API
–hcatalog-database: 指定使用hcatalog方式导入Hive的数据库名称
–hcatalog-table: 指定使用hcatalog方式导入Hive的数据库名称
①、老版本api导入方法:自己在Hive中建表,从关系数据库导入文件到hive中
[root@hadoop01 ~]# sqoop import \
> --connect jdbc:mysql://hadoop01:3306/sqoopTest \
> --username root \
> --password 123456 \
> --table tb_tohdfs \
> --hive-import \
> --hive-database default \
> --hive-table fromsqoop1 \
> --fields-terminated-by '\t' \
> -m 1
②、新版本API导入hive:使用更多更简洁,会自动识别字符自动导入到hive
[root@hadoop01 ~]# sqoop import \
> --connect jdbc:mysql://hadoop01:3306/sqoopTest \
> --username root \
> --password 123456 \
> --table tb_tohdfs \
> --hcatalog-database default \
> --hcatalog-table fromsqoop2 \
> -m 1
执行成功后可在hive中常看到导入的数据
区别 | 原生方式【–hive】 | Hcatalog方式[–hcatalog] |
---|---|---|
数据格式 | 较少:textfile | 支持多种特殊格式:orc/rcfile/squencefile/json等 |
导入方式 | 允许覆盖 | 不允许覆盖,只能追加 |
字段匹配 | 顺序匹配,字段名可以不相等 | 字段名匹配,名称必须相等 |
3 增量导入
–incremental:指定Sqoop增量采集方式
- append:适合于只有新增的场景
- lastmodified:适合于既有新增,也有更新的场景
–check-column:指定用哪一列来作为增量的依据(大部分选择主键列)
- id主键,默认从0开始;
- 第一次采集:id > 0,采集了4条记录,最后一个元素id = 4
- 第二次采集:id > 4,采集id > 4的其他记录(相对于上一次,都是新增内容)
–last-value:指定的那一列上一次的最后一个值是什么
① Append模式增量导入
要求:必须有一列自增的值,按照自增的int值进行判断
特点:只能导入新增的数据,无法导入更新的数据
场景:数据只会发生新增,不会发生更新的场景 => 用户登录表日志表
第一次导入,Sqoop同步脚本:
sqoop import \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_tohdfs \
--target-dir /sqoop/import/test02 \
--fields-terminated-by '\t' \
--check-column id \
--incremental append \
--last-value 0 \
-m 1
第二次产MySQL生新的数据
insert into tb_tohdfs values(null,"laowu",22);
insert into tb_tohdfs values(null,"laoliu",23);
insert into tb_tohdfs values(null,"laoqi",24);
insert into tb_tohdfs values(null,"laoba",25);
第二次导入
sqoop import \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_tohdfs \
--target-dir /sqoop/import/test02 \
--fields-terminated-by '\t' \
--incremental append \
--check-column id \
--last-value 4 \
-m 1
② Lastmodified模式增量导入:适合于既有新增,也有更新的场景
要求:必须包含动态时间变化这一列,按照数据变化的时间进行判断
特点:既导入新增的数据也导入更新的数据
场景:工作中一般用不到,无法满足要求
eg:数据准备
-- MYSQL中创建测试表
use sqoopTest;
create table tb_lastmode (
id int(11) not null auto_increment,
word varchar(200) not null,
lastmode timestamp not null default current_timestamp on update current_timestamp,
primary key (id)
) engine=innodb default charset=utf8;
-- MYSQL中插入测试数据
insert into tb_lastmode values(null,'hadoop',null);
insert into tb_lastmode values(null,'spark',null);
insert into tb_lastmode values(null,'hbase',null);
第一次采集
sqoop import \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_lastmode \
--target-dir /sqoop/import/test03 \
--fields-terminated-by '\t' \
--incremental lastmodified \
--check-column lastmode \
--last-value '2023-01-01 00:00:00' \
-m 1
数据发生变化
insert into tb_lastmode values(null,'hive',null);
update tb_lastmode set word = 'sqoop' where id = 1;
第二次采集,Lastmodified模式:append、merge-key
sqoop import \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_lastmode \
--target-dir /sqoop/import/test03 \
--fields-terminated-by '\t' \
--merge-key id \
--incremental lastmodified \
--check-column lastmode \
--last-value '2022-10-14 05:23:01' \
-m 1
–merge-key:将相同ID的数据进行合并
注意1:为什么第二次增量采集需要添加一个–merge-key参数呢?
答:我们通过时间只能判别哪些数据是某个时间新增以及更新的。新增不用管,但是更新的数据需要进行合并操作
注意2:如果MySQL中有数据更新,则在Sqoop中需要对数据进行合并操作,由于有合并操作,则Sqoop底层的MapReduce,也会执行Reduce阶段。
在实际工作中,由于append和lastmodified使用场景优先,我们更多会采用如下方式实现采集新增及更新数据。
tb_tohdfs人为添加两个字段createTime(添加时间),updateTime(更新时间)
假设今天是2022年10月18日,采集前一天的数据10月17号(既要采集新增又要采集更新数据)
createTime:2022-10-17 11:05:30
sqoop import \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--query 'select * from tb_tohdfs where substr(createTime, 1, 10)="2022-10-17" or substr(updateTime, 1, 10)="2022-10-17" and $CONDITIONS' \
--target-dir /sqoop/import/test03 \
--fields-terminated-by '\t' \
-m 1
③ 导入表数据子集(query查询)
注意事项:
-e/–query 与 --table只能二选一;
并且必须要添加where条件,并且where条件后面必须带一个$CONDITIONS 这个字符串,来实现并行运行mr的;
如果使用-e/–query,外层必须用单引号,不能用双引号;
sqoop import \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
-e 'select * from tb_tohdfs where substr(create_time,1,10) = 昨天的日期 or substr(update_time,1,10) = 昨天的日期 and $CONDITIONS' \
# 输出目录不能提前存在,每次输出目录都需要不同
--target-dir /sqoop/import/昨天的日期 \
--fields-terminated-by '\t' \
-m 1
2.2 Sqoop导出
4 全量导出
eg1:将HDFS的某个目录下的数据导出到MySQL
hadoop fs -mkdir /tmp/tb_url
hadoop fs -put /export/data/url.txt /tmp/tb_url
sqoop export \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_url \
--export-dir /tmp/tb_url \
--input-fields-terminated-by '\t' \
-m 1
- 如果不指定HDFS文件的分隔符,导致导出到MySQL会失败
eg2:将Hive的某张表的数据导出到MySQL,先truncate清空mysql中的数据
sqoop export
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_url \
--hcatalog-database default \
--hcatalog-table tb_url \
-m 1
5 增量导出
增量导出方式**
- updateonly:只增量导出更新的数据,不能导出新增的数据
- allowinsert:既导出更新的数据,也导出新增的数据
- updateonly
准备数据集
mkdir -p /export/data
vim /export/data/url.txt
1 http://facebook.com/path/p1.php?query=1
2 http://www.baidu.com/news/index.jsp?uuid=frank
3 http://www.jd.com/index?source=baidu
上传数据Hadoop的HDFS中的/export目录
hadoop fs -mkdir /export
hadoop fs -put /export/data/url.txt /export
使用全量导出第一天的数据
sqoop export \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_url \
--export-dir /export \
--input-fields-terminated-by '\t' \
-m 1
准备数据集(只有更新操作)
vim /export/data/url.txt
1 http://facebook.com/path/p1.php?query=1
2 http://www.baidu.com/news/index.jsp?uuid=frank
3 http://www.itheima.com
上传数据Hadoop的HDFS中的/export目录,覆盖已有文件
hadoop fs -rm /export/url.txt
hadoop fs -put /export/data/url.txt /export/
使用增量导出更新的数据
sqoop export \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_url \
--export-dir /export \
--input-fields-terminated-by '\t' \
--update-key id \
--update-mode updateonly \
-m 1
allowinsert(重点,底层使用的是replace into => update + insert)
修改url.txt
vim /export/data/url.txt
1 http://bigdata.itcast.com/path/p1.php?query=1
2 http://www.baidu.com/news/index.jsp?uuid=frank
3 http://www.itheima.com
4 http://www.itcast.cn
覆盖/export中的原数据
hadoop fs -rm /export/url.txt
hadoop fs -put /export/data/url.txt /export/
增量导出
sqoop export \
--connect jdbc:mysql://hadoop01:3306/sqoopTest \
--username root \
--password 123456 \
--table tb_url \
--export-dir /export \
--input-fields-terminated-by '\t' \
--update-key id \
--update-mode allowinsert \
-m 1
6 Sqoop排错手段
1.在终端中根据提示看错误,
如:关键字打错:无法识别关键字arguments;目录不存在文件不存在
2.在hub编辑器-YARN HistoryServer-作业-syslog日志中查看执行脚本
YARN的History Server查看Job任务执行情况 => Sqoop底层就是MapReduce => Job => YARN进行调度