001_数据采集工具Flume与 Sqoop

数据采集工具Flume与 Sqoop

知识点01:思考

  1. 在线教育项目中的需求和模块是什么?

    • 需求
      • 基于不同维度的数据分析提高报名转化率
        • 访问转咨询
        • 意向转报名
      • 基于不同维度的数据分析提高学员学习质量
        • 考勤分析
    • 模块/主题
      • 访问分析主题
      • 咨询分析主题
      • 意向分析主题
      • 报名分析主题
      • 考勤分析主题
  2. 整个项目架构中使用到了哪些技术?

    • 数据生成:MYSQL业务数据库系统
      • 访问与咨询:客服系统
      • 意向与报名:CRM系统
      • 考勤分析:学员管理系统
    • 数据采集:Sqoop
    • 数据存储:Hive
    • 数据处理:HiveSQL【MR】
    • 数据应用:MySQL + FineBI
    • 可视化交互工具:Hue
    • 任务流调度系统:Oozie
    • 集群管理工具:CM
    • 版本控制工具:Git
  3. 常用的数据源有哪些?

    • 业务数据
    • 用户行为数据
    • 爬虫数据
    • 运维数据
    • 第三方数据

知识点02:目标

  1. 学习Flume的使用
    • 目标:怎么学习Flume的使用?
    • Flume介绍:功能和应用场景
    • Flume使用:基本使用,学习Flume的使用技巧
  2. 掌握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:发送数据

知识点05:Flume的开发规则

  • 目标掌握Flume的基本开发规则

  • 实施

    • step1:开发一个Flume的参数配置文件

      • 需要在配置文件中定义Agent
        • 定义Agent的名称
        • 定义Source:从哪读取数据
        • 定义Channel:将数据缓存在哪
        • 定义Sink:将数据发送到哪
      • 一个文件可以有多个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命令来使用
        • 增量采集
      • 应用场景:实现动态监听采集单个文件的数据
        • 缺点:如果日志是多个文件的动态变化
    • 测试实现

      • 需求:动态采集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的功能与应用?
      • 功能:数据缓存在磁盘中
      • 应用:数据量大,性能要求不高

知识点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
    • 本质

      • 底层就是MapReduce程序:大多数都是三大阶段的MapReduce
        • Input、Map、Output
      • 将Sqoop的程序转换成了MapReduce程序,提交给YARN运行,实现分布式采集
      • 原理
        • 导入
          • Input:DBInputFormat
          • Output:TextOutputFormat
        • 导出
          • Input:TextInputFormat
          • Output:DBOutputFormat
    • 特点

      • 必须依赖于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之间数据的导入和导出
      • 应用
        • 数据同步
        • 数据迁移

知识点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

      
      
      
      
  • 小结

    • 了解即可
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值