文章目录
数据采集工具Flume与 Sqoop
知识点01:思考
-
在线教育项目中的需求和模块是什么?
- 需求
- 基于不同维度的数据分析提高报名转化率
- 访问转咨询
- 意向转报名
- 基于不同维度的数据分析提高学员学习质量
- 考勤分析
- 基于不同维度的数据分析提高报名转化率
- 模块/主题
- 访问分析主题
- 咨询分析主题
- 意向分析主题
- 报名分析主题
- 考勤分析主题
- 需求
-
整个项目架构中使用到了哪些技术?
- 数据生成:MYSQL业务数据库系统
- 访问与咨询:客服系统
- 意向与报名:CRM系统
- 考勤分析:学员管理系统
- 数据采集:Sqoop
- 数据存储:Hive
- 数据处理:HiveSQL【MR】
- 数据应用:MySQL + FineBI
- 可视化交互工具:Hue
- 任务流调度系统:Oozie
- 集群管理工具:CM
- 版本控制工具:Git
- 数据生成:MYSQL业务数据库系统
-
常用的数据源有哪些?
- 业务数据
- 用户行为数据
- 爬虫数据
- 运维数据
- 第三方数据
知识点02:目标
- 学习Flume的使用
- 目标:怎么学习Flume的使用?
- Flume介绍:功能和应用场景
- Flume使用:基本使用,学习Flume的使用技巧
- 掌握Sqoop的使用
- 目标:掌握Sqoop所有导入导出的常用参数的使用
- Sqoop介绍:功能、基本原理、应用场景
- Sqoop使用:导入和导出
知识点03:Flume的功能与应用
-
目标:掌握Flume的功能与应用场景
- Flume是什么?
- 为什么要用Flume,什么场景下使用Flume?
-
路径
- step1:功能
- step2:特点
- step3:应用
-
实施
- 功能
- 数据采集:将数据从一个地方采集到另外一个地方
- 数据生成:业务存储位置中
- 需求:将各种不同的数据来源统一化采集到统一的数据存储中
- 数据存储:统一化存储
- 实现分布式实时数据流的数据采集,可以将各种各样不同数据源的数据实时采集到各种目标地中
- 数据采集:将数据从一个地方采集到另外一个地方
- 特点
- 实时采集:时效性非常高,数据一产生就立即可以被采集
- 功能全面:支持从各种地方采集数据,可以将采集到的数据写入各种目标地
- 采集:文件、网络端口
- 发送:HDFS、Hive、Hbase、Kafka……
- 允许自定义开发
- 开发相对简单:所有的功能在底层都已经封装了,只要开发一个配置文件,定义采集谁,发送到哪就可以
- 可以实现分布式采集:不是分布式工具,将Flume部署在多台机器,一起采集
- 应用
- 应用于实时文件、网络数据流采集场景
- 美团的Flume设计架构
- https://tech.meituan.com/2013/12/09/meituan-flume-log-system-architecture-and-design.html
- 功能
-
小结
- Flume的功能和应用场景是什么?
- 功能:实时的分布式数据流采集
- 应用:实时文件和网络数据流
知识点04:Flume的基本组成
-
目标:掌握Flume的基本组成
-
路径
- step1:Agent
- step2:Source
- step3:Channel
- step4:Sink
- step5:Event
-
实施
-
官方:flume.apache.org
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EACkcumN-1623125056317)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507095910117.png)]
- http://flume.apache.org/releases/content/1.7.0/FlumeUserGuide.html
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oUEkHbZh-1623125056318)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507100111078.png)]
-
Agent:一个Agent表示一个Flume程序,实现采集数据源的数据,将数据采集发送到目标地
- 将WebServer的日志采集以后写入HDFS
-
任何一个Agent实现数据采集,都必须由三个基本组件构成
- Source、Channel、Sink
-
Source:负责监听数据源的数据变化,如果数据源产生新的数据,就立即进行采集
- 负责实现数据采集
- 将数据源的每一行数据变成一个Event对象,发送给Channel
-
Channel:负责接收Source采集到的数据,供Sink来读取数据
- 采集数据的临时缓存的
-
Sink:负责从Channel中读取采集的数据,将数据写入目标地
- 最终实现数据发送的组件
-
Event:数据流传输的最小的封装的单元,将每一行封装为一个Event
-
结构
header:类似于一个Map集合存储,默认为空的,可以选择性在header放KV对,一些属性的配置等 body:类似于一个字节数组,存放真正的这条数据的内容
-
作用:实现每一条数据的封装
-
-
-
小结
- Flume中的Agent是什么,由什么组成?
- 一个Agent就是一个Flume程序
- 组成:Source、Channel、SInk
- Source、Channel、Sink的功能分别是什么?
- Source:采集数据
- Channel:缓存数据
- Sink:发送数据
- Flume中的Agent是什么,由什么组成?
知识点05:Flume的开发规则
-
目标:掌握Flume的基本开发规则
-
实施
-
step1:开发一个Flume的参数配置文件
- 需要在配置文件中定义Agent
- 定义Agent的名称
- 定义Source:从哪读取数据
- 定义Channel:将数据缓存在哪
- 定义Sink:将数据发送到哪
- 一个文件可以有多个Agent,具体区分每个Agent通过Agent名称来区分
- 需要在配置文件中定义Agent
-
step2:运行flume的agent程序,运行这个程序所在的文件,指定agent的名称即可
-
用法
flume-ng <command> [options]...
-
使用
flume-ng agent -c/--conf 指定Flume配置文件目录 --name/-n 指定Agent的名称 --conf-file/-f 指定要运行的文件
-
版本:
- flume-og:以前的老版本,见不到的
- flume-ng:现在使用的版本
-
-
-
小结
-
如何开发一个Flume程序?
-
step1:开发一个文件,定义Agent【名称、source、channel、sink】
-
step2:运行这个文件
flume-ng agent -c conf_dir -n agentName -f agentFile
-
-
知识点06:Flume开发测试
-
目标:实现Flume程序的开发测试
-
实施
-
需求:采集Hive的日志、临时缓存在内存中、将日志写入Flume的日志中并打印在命令行
-
source:采集一个文件数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRaC1wna-1623125056319)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507103323742.png)]
- Exec Source:通过执行一条Linux命令来实现文件的动态采集
-
channel:Flume提供了各种channel用于缓存数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4m0CGSJ8-1623125056320)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507103901326.png)]
- mem channel:将数据缓存在内存中
-
sink:Flume提供了很多种sink
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2jL0Vsou-1623125056321)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507104151330.png)]
- Logger Sink:将数据写入日志中
-
-
开发
-
创建测试目录
cd /export/server/flume-1.6.0-cdh5.14.0-bin mkdir usercase
-
复制官方示例
cp conf/flume-conf.properties.template usercase/hive-mem-log.properties
-
开发配置文件
# The configuration file needs to define the sources, # the channels and the sinks. # Sources, channels and sinks are defined per a1, # in this case called 'a1' #define the agent a1.sources = s1 a1.channels = c1 a1.sinks = k1 #define the source a1.sources.s1.type = exec a1.sources.s1.command = tail -f /export/server/hive-1.1.0-cdh5.14.0/logs/hiveserver2.log #define the channel a1.channels.c1.type = memory a1.channels.c1.capacity = 10000 #define the sink a1.sinks.k1.type = logger #bond a1.sources.s1.channels = c1 a1.sinks.k1.channel = c1
-
-
运行
flume-ng agent -c conf/ -f usercase/hive-mem-log.properties -n a1 -Dflume.root.logger=INFO,console
-
结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tEeeMECa-1623125056322)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507104747650.png)]
-
-
小结
- 实现测试即可
知识点07:常用Source:Exec
-
目标:掌握Exec Source的功能与应用场景
-
路径
- step1:功能与应用场景
- step2:测试实现
-
实施
-
功能与应用场景
- 功能:通过执行一条Linux命令来实现数据动态采集
- 固定搭配tail -f命令来使用
- 增量采集
- 应用场景:实现动态监听采集单个文件的数据
- 缺点:如果日志是多个文件的动态变化
- 功能:通过执行一条Linux命令来实现数据动态采集
-
测试实现
- 需求:动态采集hiveserver的日志文件,输出在Flume的日志并打印在命令行中
- 开发:参考知识点06
-
-
小结
- Exec Source的功能与应用场景是什么?
- 功能:通过执行一条Linux命令来实现文件的数据采集
- 应用:动态监听单个文件
知识点08:常用Source:Taildir
-
目标:掌握Taildir Source的功能与应用场景
-
路径
- step1:功能与应用场景
- step2:测试实现
-
实施
-
功能与应用场景
-
应用场景
-
需求:当前日志文件是一天一个,需要每天将数据实时采集到HDFS上
-
数据:Linux
/tomcat/logs/2020-01-01.log 2020-01-02.log …… 2020-11-10.log
-
问题:能不能exec source进行采集?
- 不能,exec只能监听采集单个文件
-
解决:Taildir Source
-
-
功能:从Apache Flume1.7版本开始支持,动态监听采集多个文件
- 如果用的是1.5或者1.6,遇到这个问题,需要自己手动编译这个功能
-
-
测试实现
-
需求:让Flume动态监听一个文件和一个目录下的所有文件
-
准备
cd /export/server/flume-1.6.0-cdh5.14.0-bin mkdir position mkdir -p /export/data/flume echo " " >> /export/data/flume/bigdata01.txt
mkdir -p /export/data/flume/bigdata
- 开发 ```properties # define sourceName/channelName/sinkName for the agent a1.sources = s1 a1.channels = c1 a1.sinks = k1 # define the s1 a1.sources.s1.type = TAILDIR #指定一个元数据记录文件 a1.sources.s1.positionFile = /export/server/flume-1.6.0-cdh5.14.0-bin/position/taildir_position.json #将所有需要监控的数据源变成一个组,这个组内有两个数据源 a1.sources.s1.filegroups = f1 f2 #指定了f1是谁:监控一个文件 a1.sources.s1.filegroups.f1 = /export/data/flume/bigdata01.txt #指定f1采集到的数据的header中包含一个KV对 a1.sources.s1.headers.f1.headerKey1 = value1 #指定f2是谁:监控一个目录下的所有文件 a1.sources.s1.filegroups.f2 = /export/data/flume/bigdata/.* #指定f2采集到的数据的header中包含一个KV对 a1.sources.s1.headers.f2.headerKey1 = value2 a1.sources.s1.fileHeader = true # define the c1 a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # def the k1 a1.sinks.k1.type = logger #source、channel、sink bond a1.sources.s1.channels = c1 a1.sinks.k1.channel = c1
-
结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhaLu8q5-1623125056323)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507112002320.png)]
-
元数据文件的功能:/export/server/flume-1.6.0-cdh5.14.0-bin/position/taildir_position.json
-
问题:如果Flume程序故障,重启Flume程序,已经被采集过的数据还要不要采集?
-
需求:不需要,不能导致数据重复
-
功能:记录Flume所监听的每个文件已经被采集的位置
[ {"inode":104525289,"pos":35,"file":"/export/data/flume/bigdata01.txt"},{"inode":67862260,"pos":52,"file":"/export/data/flume/bigdata/itcast01.txt"},{"inode":67862262,"pos":52,"file":"/export/data/flume/bigdata/itcast02.txt"} ]
-
-
补充:工作中可能会见到其他的source
- Kafka Source:监听读取Kafka数据
- Spooldir Source:监控一个目录,只要这个目录中产生一个文件,就会全量采集一个文件
- 缺点:不能动态监控文件,被采集的文件是不能发生变化的
-
-
-
小结
- taildir Source的功能与应用场景是什么?
- 功能:动态采集文件
- 应用:动态监听多个文件的变化实现多个文件动态采集
知识点09:常用Channel:file和mem
-
目标:掌握file channel与mem channel的功能与应用
-
实施
-
mem Channel:将数据缓存在内存中
-
特点:读写快、容量小、安全性较差
-
应用:小数据量的高性能的传输
-
-
file Channel:将数据缓存在文件中
-
特点:读写相对慢、容量大、安全性较高
-
应用:数据量大,读写性能要求不高的场景下
-
-
常用属性
- capacity:缓存大小:指定Channel中最多存储多少条event
- transactionCapacity:每次传输的大小
-
-
小结
- mem channel的功能与应用?
- 功能:将数据缓存在内存中
- 应用:数据量小,性能高
- file channel的功能与应用?
- 功能:数据缓存在磁盘中
- 应用:数据量大,性能要求不高
- mem channel的功能与应用?
知识点10:常用Sink:HDFS
-
目标:掌握HDFS Sink的功能与应用
-
路径
- step1:HDFS sink的功能
- step2:指定文件大小
- step3:指定分区
-
实施
-
HDFS sink的功能
-
常用的SINk
- Kafka SInk:实时
- HDFS SInk:离线
-
问题:为什么离线采集不直接写入Hive,使用Hive sink
- 原因一:数据可能不是结构化的数据文件
- 原因二:Hive表必须为分桶结构表,数据文件类型必须为ORC类型
-
功能:将Flume采集的数据写入HDFS
-
问题:Flume作为HDFS客户端,写入HDFS数据
- Flume必须知道HDFS地址
- Flume必须拥有HDFS的jar包
-
解决
-
方式一:Flume写地址的时候,指定HDFS的绝对地址
hdfs://node1:8020/nginx/log
- 手动将需要的jar包放入Flume的lib目录下
-
方式二:在Flume中配置Hadoop的环境变量,将core-site和hdfs-site放入Flume的配置文件目录
-
-
-
-
需求:将Hive的日志动态采集写入HDFS
# The configuration file needs to define the sources, # the channels and the sinks. # Sources, channels and sinks are defined per a1, # in this case called 'a1' #定义当前的agent的名称,以及对应source、channel、sink的名字 a1.sources = s1 a1.channels = c1 a1.sinks = k1 #定义s1:从哪读数据,读谁 a1.sources.s1.type = exec a1.sources.s1.command = tail -f /export/server/hive-1.1.0-cdh5.14.0/logs/hiveserver2.log #定义c1:缓存在什么地方 a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 #定义k1:将数据发送给谁 a1.sinks.k1.type = hdfs a1.sinks.k1.hdfs.path = hdfs://node1:8020/flume/test1 #s1将数据给哪个channel a1.sources.s1.channels = c1 #k1从哪个channel中取数据 a1.sinks.k1.channel = c1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FXl7ExiR-1623125056324)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507114957991.png)]
-
指定文件大小
-
问题:Flume默认写入HDFS上会产生很多小文件,都在1KB左右,不利用HDFS存储
-
解决:指定文件大小
hdfs.rollInterval:按照时间间隔生成文件 hdfs.rollSize:指定HDFS生成的文件大小 hdfs.rollCount:按照event个数生成文件
# The configuration file needs to define the sources, # the channels and the sinks. # Sources, channels and sinks are defined per a1, # in this case called 'a1' #定义当前的agent的名称,以及对应source、channel、sink的名字 a1.sources = s1 a1.channels = c1 a1.sinks = k1 #定义s1:从哪读数据,读谁 a1.sources.s1.type = exec a1.sources.s1.command = tail -f /export/server/hive-1.1.0-cdh5.14.0/logs/hiveserver2.log #定义c1:缓存在什么地方 a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 #定义k1:将数据发送给谁 a1.sinks.k1.type = hdfs a1.sinks.k1.hdfs.path = hdfs://node1:8020/flume/test1 #指定按照时间生成文件,一般关闭 a1.sinks.k1.hdfs.rollInterval = 0 #指定文件大小生成文件,一般120 ~ 125M对应的字节数 a1.sinks.k1.hdfs.rollSize = 10240
#指定event个数生成文件,一般关闭
a1.sinks.k1.hdfs.rollCount = 0#s1将数据给哪个channel
a1.sources.s1.channels = c1
#k1从哪个channel中取数据
a1.sinks.k1.channel = c1[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OcGnWxHg-1623125056325)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507115734043.png)]
-
-
指定分区
-
问题:如何实现分区存储,每天一个或者每小时一个目录?
-
解决:添加时间标记目录
# The configuration file needs to define the sources, # the channels and the sinks. # Sources, channels and sinks are defined per a1, # in this case called 'a1' #定义当前的agent的名称,以及对应source、channel、sink的名字 a1.sources = s1 a1.channels = c1 a1.sinks = k1 #定义s1:从哪读数据,读谁 a1.sources.s1.type = exec a1.sources.s1.command = tail -f /export/server/hive-1.1.0-cdh5.14.0/logs/hiveserver2.log #定义c1:缓存在什么地方 a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 #定义k1:将数据发送给谁 a1.sinks.k1.type = hdfs a1.sinks.k1.hdfs.path = hdfs://node1:8020/flume/log/daystr=%Y%m%d #指定按照时间生成文件,一般关闭 a1.sinks.k1.hdfs.rollInterval = 0 #指定文件大小生成文件,一般120 ~ 125M对应的字节数 a1.sinks.k1.hdfs.rollSize = 10240 #指定event个数生成文件,一般关闭 a1.sinks.k1.hdfs.rollCount = 0 a1.sinks.k1.hdfs.useLocalTimeStamp = true #s1将数据给哪个channel a1.sources.s1.channels = c1 #k1从哪个channel中取数据 a1.sinks.k1.channel = c1
-
-
其他参数
#指定生成的文件的前缀 a1.sinks.k1.hdfs.filePrefix = nginx #指定生成的文件的后缀 a1.sinks.k1.hdfs.fileSuffix = .log #指定写入HDFS的文件的类型:普通的文件 a1.sinks.k1.hdfs.fileType = DataStream
-
-
小结
- HDFS sink的功能与应用?
- 功能:将数据采集写入HDFS
- 应用:归档,代替Hive Sink
知识点11:Sqoop的功能与应用
-
目标:掌握Sqoop的功能与应用场景
-
路径
- step1:功能
- step2:本质
- step3:应用
- step4:测试
-
实施
-
功能
- 用于实现MySQL等RDBMS数据库与HDFS之间的数据导入与导出
- 导入导出相对HDFS而言
- 导入:MySQL => HDFS
- 导出:HDFS => MySQL
- 用于实现MySQL等RDBMS数据库与HDFS之间的数据导入与导出
-
本质
- 底层就是MapReduce程序:大多数都是三大阶段的MapReduce
- Input、Map、Output
- 将Sqoop的程序转换成了MapReduce程序,提交给YARN运行,实现分布式采集
- 原理
- 导入
- Input:DBInputFormat
- Output:TextOutputFormat
- 导出
- Input:TextInputFormat
- Output:DBOutputFormat
- 导入
- 底层就是MapReduce程序:大多数都是三大阶段的MapReduce
-
特点
- 必须依赖于Hadoop:MapReduce + YARN
- MapReduce是离线计算框架,Sqoop离线数据采集的工具,只能适合于==离线业务平台==
-
应用
- 数据同步:定期将离线的数据进行采集同步到数据仓库中
- 增量:只同步采集新增的数据【增加 + 更新】
- 数据迁移:将历史数据【MySQL、Oracle】存储到HDFS中
- 全量:每次同步所有数据
- 数据同步:定期将离线的数据进行采集同步到数据仓库中
-
测试
- 1.x版本:单纯的工具,直接实现程序的转换的
- 2.x版本:基于1.x的功能之上,引入CS模式
sqoop list-databases --connect jdbc:mysql://node3:3306 --username root --password 123456
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xegS8IuY-1623125056326)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507151247368.png)]
-
-
小结
- Sqoop的功能与应用场景?
- 功能:实现RDBMS与HDFS之间数据的导入和导出
- 应用
- 数据同步
- 数据迁移
- Sqoop的功能与应用场景?
知识点12:Sqoop导入:HDFS
-
目标:实现Sqoop导入数据到HDFS中
-
路径
- step1:准备数据
- step2:导入语法
- step3:测试导入
- step4:常用参数
-
实施
-
准备数据
-
MySQL创建数据库==【在MySQL中执行】==
create database sqoopTest; use sqoopTest;
-
MySQL创建数据表==【在MySQL中执行】==
CREATE TABLE `tb_tohdfs` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `age` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
MySQL插入数据==【在MySQL中执行】==
insert into tb_tohdfs values(null,"laoda",18); insert into tb_tohdfs values(null,"laoer",19); insert into tb_tohdfs values(null,"laosan",20); insert into tb_tohdfs values(null,"laosi",21);
-
-
导入语法
sqoop import --help usage: sqoop import [GENERIC-ARGS] [TOOL-ARGS]
- 需要
-
采集谁:MySQL
- JDBC URL
- 用户名、密码
- 表名
- 写入谁:HDFS
- 指定HDFS地址
-
测试导入
-
需求1:将MySQL中tb_tohdfs表的数据导入HDFS的/sqoop/import/test01目录中
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --target-dir /sqoop/import/test01
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXZUCMqq-1623125056327)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210607160508821.png)]
-
问题
- 启动了4个Map,没有必要
- 默认以逗号为分隔符
-
-
常用参数
-
需求2:将tb_tohdfs表的id和name导入HDFS的/sqoop/import/test01目录,并且用制表符分隔
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --columns id,name \ --delete-target-dir \ --target-dir /sqoop/import/test01 \ --fields-terminated-by '\t' \ -m 1
- –columns:指定导入哪些列
- –delete-target-dir:提前删除输出目录
- –fields-terminated-by:指定输出分隔符
- -m:指定map个数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q9i0fl0x-1623125056327)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210607161217575.png)]
-
需求3:将tb_tohdfs表中的id >2的数据导入HDFS的/sqoop/import/test01目录中
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --where 'id > 2' \ --delete-target-dir \ --target-dir /sqoop/import/test01 \ --fields-terminated-by '\t' \ -m 1
-
–where:指定行的过滤
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QwZrjuMk-1623125056328)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210607161400935.png)]
-
-
需求4:将tb_tohdfs表中的id>2的数据中id和name两列导入/sqoop/import/test01目录中
-
方案一
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --columns id,name \ --where 'id > 2' \ --delete-target-dir \ --target-dir /sqoop/import/test01 \ --fields-terminated-by '\t' \ -m 1
-
方案二
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ -e 'select id,name from tb_tohdfs where id > 2 and $CONDITIONS' \ --delete-target-dir \ --target-dir /sqoop/import/test01 \ --fields-terminated-by '\t' \ -m 1
- -e,–query :使用SQL语句读取数据.只要使用SQL语句,必须在where子句中加上$CONDITIONS
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G1r3pqn3-1623125056328)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210607161654416.png)]
-
-
-
-
-
小结
- 实现导入HDFS即可
知识点13:Sqoop导入:Hive
-
目标:实现Sqoop导入MySQL数据到Hive表中
-
路径
- step1:准备数据
- step2:直接导入
- step3:hcatalog导入
-
实施
-
准备数据:在Hive 中创建一张表
use default; create table fromsqoop( id int, name string, age int );
-
直接导入
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --hive-import \ --hive-database default \ --hive-table fromsqoop \ --fields-terminated-by '\001' \ -m 1
-
–hive-database:指定Hive的数据库
-
–hive-import:申明导入Hive表
-
–hive-table:指定导入哪张表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CAjhvTAb-1623125056329)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210607162215509.png)]
-
原理
- step1:先通过MR将数据采集写入HDFS
- step2:通过load语句将HDFS上的采集的文件加载到Hive表中
-
-
hcatalog导入
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --hcatalog-database default \ --hcatalog-table fromsqoop \ --fields-terminated-by '\001' \ -m 1
- 原理:通过获取Hive的元数据,直接将表的目录作为输出目录
-
-
小结
- 实现导入Hive表
知识点14:Sqoop导入:增量
-
目标:掌握Sqoop如何实现增量导入
-
路径
- step1:增量需求
- step2:Sqoop中的两种增量方式
- step3:append
- step4:lastmodifield
- step5:特殊方式
-
实施
-
增量需求
-
第一天:产生数据
+----+--------+-----+ | 1 | laoda | 18 | | 2 | laoer | 19 | | 3 | laosan | 20 | | 4 | laosi | 21 |
-
第二天的0点:采集昨天的数据
sqoop import --connect jdbc:mysql://node3:3306/sqoopTest --username root --password 123456 --table tb_tohdfs --target-dir /sqoop/import/test02 -m 1 +----+--------+-----+ | 1 | laoda | 18 | | 2 | laoer | 19 | | 3 | laosan | 20 | | 4 | laosi | 21 |
-
第二天:产生新的数据
| 5 | laowu | 22 | | 6 | laoliu | 23 | | 7 | laoqi | 24 | | 8 | laoba | 25 | +----+--------+-----+
-
第三天:采集昨天的数据
sqoop import --connect jdbc:mysql://node3:3306/sqoopTest --username root --password 123456 --table tb_tohdfs --target-dir /sqoop/import/test02 -m 1
-
问题:每次导入都是所有的数据,每次都是全量
- 数据重复
-
-
Sqoop中的两种增量方式
-
设计:用于对某一列值进行判断,只要大于上一次的值就会被导入
-
参数
Incremental import arguments: --check-column <column> Source column to check for incremental change --incremental <import-type> Define an incremental import of type 'append' or 'lastmodified' --last-value <value> Last imported value in the incremental check column
- –check-column:以哪一列的值作为增量的基准
- –last-value:指定上一次这一列的值是什么
- –incremental:指定增量的方式
- append
- lastmodified
-
-
append
-
要求:必须有一列自增的值,按照自增的int值进行判断
-
特点:只能导入增加的数据,无法导入更新的数据
-
测试
-
第一次导入
sqoop import \ --connect jdbc:mysql://node3: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 1 \ -m 1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s3bFSFYB-1623125056329)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210607163206626.png)]
-
第二次产生新的数据
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);- 第二次导入 ```shell sqoop import \ --connect jdbc:mysql://node3: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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ekgw5QCh-1623125056330)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210607163409578.png)]
-
-
-
lastmodifield
-
要求:必须包含动态时间变化这一列,按照数据变化的时间进行判断
-
特点:既导入新增的数据也导入更新的数据
-
测试
-
MySQL中创建测试数据
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; 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://node3: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 '2021-06-06 16:09:32' \ -m 1
-
数据发生变化
insert into tb_lastmode values(null,'hive',null); update tb_lastmode set word = 'sqoop' where id = 1;
-
第二次采集
sqoop import \ --connect jdbc:mysql://node3: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 '2021-06-07 16:37:43' \ -m 1
- –merge-key:将相同ID的数据进行合并
-
-
-
特殊方式
- 问题:append和lastmodifield都不适用
- append不能采集更新的数据
- lastmodifield的时间列大部分业务表时没有的
- 业务数据表中一般由两个时间字段
- create_time:数据创建时间
- update_time:数据更新时间
- 今天采集昨天的数据
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \
–username root
–password 123456
-e ‘select * from tb_tohdfs where substr(create_time,1,10) = 昨天的日期 and substr(update_time,1,10) = 昨天的日期 and $CONDITIONS’
–target-dir /sqoop/import/昨天的日期目录
–fields-terminated-by ‘\t’
-m 1- 要求:必须每次将最新导入的数据放到一个目录单独存储,不能相同
-
-
小结
-
Sqoop中如何实现增量导入?
- 自带的增量
- append
- 要求:必须有一列自增Int列
- 特点:只能采集新增的,不能采集更新的
- lastmodifield
- 要求:必须有时间变化列
- 特点:都可以实现增量采集
- 自己实现的增量
- 通过where对时间字段进行过滤
- 指定分区目录
-
知识点15:Sqoop导出:全量
-
目标:实现Sqoop全量导出数据到MySQL
-
路径
- step1:准备数据
- step2:全量导出
-
实施
-
准备数据
-
MySQL中创建测试表
use sqoopTest; CREATE TABLE `tb_url` ( `id` int(11) NOT NULL, `url` varchar(200) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
Hive中创建表,并加载数据
vim /export/datas/lateral.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 use default; create table tb_url( id int, url string ) row format delimited fields terminated by '\t'; load data local inpath '/export/data/lateral.txt' into table tb_url;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Xs246YC-1623125056330)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507162752199.png)]
-
-
全量导出
-
导出HDFS
sqoop export \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_url \ --export-dir /user/hive/warehouse/tb_url \ --input-fields-terminated-by '\t' \
-m 1
- 导出Hive
sqoop export
–connect jdbc:mysql://node3:3306/sqoopTest
–username root
–password 123456
–table tb_url
–hcatalog-database default
–hcatalog-table tb_url
–input-fields-terminated-by ‘\t’
-m 1 -
-
-
小结
- 实现导出即可
知识点16:Sqoop导出:增量
-
目标:实现Sqoop增量导出到MySQL
-
路径
- step1:增量导出场景
- step2:增量导出方式
- step3:updateonly
- step4:allowinsert
-
实施
-
增量导出场景
-
Hive中有一张结果表:存储每天分析的结果
--第一天:10号处理9号 id daystr UV PV IP 1 2020-11-09 1000 10000 500 insert into result select id,daystr,uv,pv ,ip from datatable where daystr=昨天的日期 --第二天:11号处理10号 id daystr UV PV IP 1 2020-11-09 1000 10000 500 2 2020-11-10 2000 20000 1000
-
MySQL:存储每一天的结果
1 2020-11-09 1000 10000 500
-
-
增量导出方式
- updateonly:只增量导出更新的数据
- allowerinsert:既导出更新的数据,也导出新增的数据
-
updateonly
-
修改lateral.txt数据
1 http://www.itcast.com/path/p1.php?query=1 2 http://www.baidu.com/news/index.jsp?uuid=frank 3 http://www.jd.com/index?source=baidu 4 http://www.heima.com
-
重新加载覆盖
load data local inpath '/export/data/lateral.txt' overwrite into table tb_url;
-
增量导出
sqoop export \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_url \ --export-dir /user/hive/warehouse/tb_url \ --input-fields-terminated-by '\t' \ --update-key id \ --update-mode updateonly \ -m 1
-
-
allowerinsert
-
修改lateral.txt
1 http://bigdata.itcast.com/path/p1.php?query=1
2 http://www.baidu.com/news/index.jsp?uuid=frank
3 http://www.jd.com/index?source=baidu
4 http://www.heima.com- 覆盖表中数据
load data local inpath ‘/export/data/lateral.txt’ overwrite into table tb_url;
- 增量导出 ```shell sqoop export \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_url \ --export-dir /user/hive/warehouse/tb_url \ --input-fields-terminated-by '\t' \ --update-key id \ --update-mode allowinsert \ -m 1
-
-
-
小结
- Sqoop如何实现增量导出?
- updateonly:只能增量导出更新的数据
- allowerinsert:可以实现增量导出更新和新增的数据
知识点17:Sqoop Job
-
目标:了解Sqoop Job的功能与应用
-
路径
- step1:增量导入的问题
- step2:Sqoop Job的使用
-
实施
-
增量导入的问题
-
增量导入每次都要手动修改上次的值执行,怎么解决?
sqoop import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --target-dir /sqoop/import/test04 \ --fields-terminated-by '\t' \ --incremental append \ --check-column id \ --last-value 4 \ -m 1
-
-
Sqoop Job的使用
-
MySQL插入数据
insert into tb_tohdfs values(null,'laojiu',26); insert into tb_tohdfs values(null,'laoshi',27);
-
创建job
sqoop job --create job01 \ -- import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password 123456 \ --table tb_tohdfs \ --target-dir /sqoop/import/test04 \ --fields-terminated-by '\t' \ --incremental append \ --check-column id \ --last-value 8 \ -m 1
- 创建job,不会运行程序,只是在元数据中记录信息
-
列举job
sqoop job --list
-
查看job的信息
sqoop job --show jobName
-
运行job
sqoop job --exec jobName
-
删除job
sqoop job --delete jobName
-
-
-
小结
- 了解即可
知识点18:Sqoop密码问题与脚本封装
-
目标:了解Sqoop密码的问题及脚本的封装
-
路径
- step1:Sqoop中的数据库密码
- step2:Sqoop封装脚本
-
实施
-
Sqoop中的数据库密码
-
如何解决手动输入密码和密码明文问题?
-
方式一:在sqoop的sqoop-site.xml中配置将密码存储在客户端中,比较麻烦,一般不用
-
方式二:将密码存储在文件中,通过文件的权限来管理密码
sqoop job --create job02 \ -- import \ --connect jdbc:mysql://node3:3306/sqoopTest \ --username root \ --password-file file:///export/data/sqoop.passwd \ --table tb_tohdfs \ --target-dir /sqoop/import/test05 \ --fields-terminated-by '\t' \ --incremental append \ --check-column id \ --last-value 4 \ -m 1
-
–password-file
-
读取的是HDFS文件,这个文件中只能有一行密码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PLZtRAIR-1623125056330)(Day15_数据采集工具Flume与 Sqoop.assets/image-20210507164655626.png)]
-
-
-
Sqoop封装脚本
-
如何封装Sqoop的代码到文件中?
-
step1:将代码封装到一个文件中
vim /export/data/test.sqoop
import --connect jdbc:mysql://node3:3306/sqoopTest --username root --password-file file:///export/data/sqoop.passwd --table tb_tohdfs --target-dir /sqoop/import/test05 --fields-terminated-by '\t' -m 1
- 要求:一行只放一个参数
-
step2:运行这个文件
sqoop --options-file /export/data/test.sqoop
-
-
-
小结
- 了解即可