Hadoop-->Flume原理与应用

来源:互联网 发布:淘宝助手数据包 编辑:程序博客网 时间:2024/05/22 15:34

从这篇博文开始,将介绍hadoop相关内容,下图的hadoop的六层架构,对于每一个架构组件都有专门一篇博文来进行分析总结,并且会附上关键的配置步骤和实战代码。

这里写图片描述

这里写图片描述

本篇博文主要分析总结数据采集系统Flume的原理以及其应用。 

Flume主要应用与对非结构化数据(如日志)的收集。

  • 分布式、可靠、高可用的海量日志采集系统;
  • 数据源可定制,可扩展;
  • 数据存储系统可定制,可扩展。
  • 中间件:屏蔽了数据源和数据存储系统的异构性

Flume的特点:

  • 可靠性
    保证数据不丢失

  • 可扩展性
    各组件数目可扩展

  • 高性能
    吞吐率很高,能满足海量数据收集需求

  • 可管理性
    可动态增加和删除组件

  • 文档丰富,社区活跃
    已成为Hadoop生态系统标配

Flume NG基本架构

这里写图片描述

各种客户端产生客户日志,或者其他的数据,通过客户端将数据发给Flume组件Agent,Agent经过聚集以后可以将数据继续发给下一个Agent,经过进一步的聚集或者过滤之后把数据写到后端的存储系统例如HDFS。用户需要编写只有client,Agent只需要做一些配置即可。

每个Agent都是由三个组件构成的,分别为source,channel,sink。source是捕获数据的一个组件,将捕获到的数据写到channel里面。channel类似一个缓冲区(用来调节source和sink处理数据能力的不对等),sink将channel里面的数据分发给HDFS或者下一个Agent。这个Agent类似一个生产者消费者模式。

Flume NG核心概念

Event

  • Event是Flume数据传输的基本单元

  • Flume以事件的形式将数据从源头传送到最终的目的

  • Event由可选的header和载有数据的一个byte array构成。
    载有的数据对flume是不透明的。
    Header是容纳了key-value字符串对的无序集合,key在集合内是唯一的。
    Header可以在上下文路由中使用扩展。

    Flume里面每一行数据,或者每一条数据都称为一个事件,Flume就是将拿到的一个个日志或者是一条条数据封装成Event。然后由source获取到event发给channel。channel里面存储都是一个个Event。

Client

  • Client是一个将原始log包装成events并且发送它们到一个或多个agent的实体。
  • 目的是从数据源系统中解耦Flume。
  • 在flume的拓扑结构中不是必须的。
  • Client实例
    Flume log4j Appender
    可以使用Client SDK (org.apache.flume.api)定制特定的Client。

Agent

  • 一个Agent包含Source, Channel, Sink和其他组件;
  • 它利用这些组件将events从一个节点传输到另一个节点或最终目的;
  • agent是flume流的基础部分;
  • flume为这些组件提供了配置、生命周期管理、监控支持。

    这里写图片描述

    Agent之Source:
    • Source负责接收event或通过特殊机制产生event,并将events批量的放到一个或多个Channel。(注意可以是一个source对应多个channel)
    • 包含event驱动和轮询2种类型
    • Source必须至少和一个channel关联
    • 不同类型的Source:
      与系统集成的Source: Syslog, Netcat
      自动生成事件的Source: Exec
      监听文件夹下文件变化:Spooling Directory Source,Taildir Source
      用于Agent和Agent之间通信的IPC Source: Avro、Thrift   
          
          
    Agent之Source:Spooling Directory Source
    • 监听一个文件夹下新产生的文件,并读取内容,发至channel;
      注意事项:
        ①已经产生的文件不能进行任意修改,不然会停止处理;
        ②建议将文件(唯一文件名)写到一个临时目录下,之后move到监听目录下。
        
      这里写图片描述

      也就是Spooling Directory Source会监听上图中监听目录下新产生的新文件,一旦产生新文件,Spooling Directory Source会对读取该新文件并将其发送至channel。但是监听目录下的新产生的文件被修改(例如被相同文件名的文件覆盖)那么操作就会停止。为了避免这种情况发生,我们可以建立一个临时目录,把新产生的文件先放进临时目录,并且对其以时间戳进行重命名再放进监听目录。

      Spooling Directory Source关键参数说明:
      这里写图片描述

      a1.channels = ch-1a1.sources = src-1a1.sources.src-1.type = spooldira1.sources.src-1.channels = ch-1a1.sources.src-1.spoolDir=/var/log/apache/flumeSpoola1.sources.src-1.fileHeader = true
    Agent之Source:TailDir
    • 监听文件内容,一旦新写入一行新数据,则读取之
    • 支持断点续读,定期将最新读取数据的偏移量写入json文件
    • 根据文件修改时间决定读取优先级,最新的文件优先读取
    • 读取完的文件不会做任何处理(比如删除,重命名等)
    • 目前仅支持文本文件

      Source:TailDir关键参数说明:
      这里写图片描述

      a1.sources = r1a1.channels = c1a1.sources.r1.type = TAILDIRa1.sources.r1.channels = c1//保存断点的文件a1.sources.r1.positionFile=/var/log/flume/taildir_position.json//对文件进行分组,两组文件放在不同的目录下,表示要监听两个目录a1.sources.r1.filegroups = f1 f2a1.sources.r1.filegroups.f1=/var/log/test1/example.log//在文件头部插入数据,便于后面数据路由a1.sources.r1.headers.f1.headerKey1 = value1a1.sources.r1.filegroups.f2 = /var/log/test2/.*log.*a1.sources.r1.headers.f2.headerKey1 = value2a1.sources.r1.headers.f2.headerKey2 = value2-2a1.sources.r1.fileHeader = true
    Agent之Source:Exec
    • 可执行任意Unix命令
    • 无容错性
    a1.sources = r1a1.channels = c1a1.sources.r1.type = execa1.sources.r1.command = tail -F /var/log/securea1.sources.r1.channels = c1
    Agent之Channel
    • Channel位于Source和Sink之间,用于缓存event;
    • 当Sink成功将event发送到下一跳的channel或最终目的,event从Channel移除。
    • 不同的Channel提供的持久化水平也是不一样的:
      Memory Channel: volatile(channel在内存中,数据可能会丢失
      File Channel: 基于WAL(预写式日志Write-Ahead Logging)实现,支持断点续读,故有保存断点文件参数。(channel 在磁盘文件中)
      JDBC Channel: 基于嵌入Database实现
    • Channel支持事务,提供较弱的顺序保证
    • 可以和任何数量的Source和Sink工作
      -
    Agent之Channel:Memory
    • 关键参数说明
      这里写图片描述
    a1.channels = c1a1.channels.c1.type = memorya1.channels.c1.capacity = 10000a1.channels.c1.transactionCapacity = 10000a1.channels.c1.byteCapacityBufferPercentage = 20a1.channels.c1.byteCapacity = 800000
    Agent之Channel:File
    • 关键参数说明
      这里写图片描述
      a1.channels = c1a1.channels.c1.type = file//保存断点的文件地址a1.channels.c1.checkpointDir = /mnt/flume/checkpoint//channel从source读取出来的数据暂时存储在下面这个文件内a1.channels.c1.dataDirs = /mnt/flume/data
    Agent之Sink
    • Sink负责将event传输到下一跳或最终目的,成功完成后将event从channel移除。
    • 必须作用于一个确切的channel。
    • 不同类型的Sink:
      存储event到最终目的的终端Sink. 比如: HDFS, HBase
      自动消耗的Sink. 比如: Null Sink(把接收到的数据丢掉)
      用于Agent间通信的IPC sink: Avro

      -

    Agent之Sink:HDFS
    • 关键参数说明(此时sink接HDFS)
      这里写图片描述
      满足上图后三行中三个滚动条件中任意一个,则滚动产生一个文件。
        a1.channels = c1        a1.sinks = k1        a1.sinks.k1.type = hdfs //表示这个sink后面接hdfs        a1.sinks.k1.channel = c1        a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/%S        a1.sinks.k1.hdfs.filePrefix = events-        a1.sinks.k1.hdfs.round = true        a1.sinks.k1.hdfs.roundValue = 10        a1.sinks.k1.hdfs.roundUnit = minute


常用拓扑实例1

当客户访问网站时,这发送请求到节点(服务器)上,服务器就会记录一条日志,这条日志就可能写在节点的磁盘上,我们有很多这样的节点,可以在每台节点上部署下图所示的Agent:
这里写图片描述

上图中采用pooldir类型的source(监听一个文件夹下新产生的文件,并读取内容,发至channel),Channel采用文件类型,sink后面接的是HDFS。那么这么一个Agent如何部署起来呢?

// 我们这个Agent就叫LogAgentLogAgent.sources = apache //命名LogAgent.sourcesLogAgent.channels = fileChannel //命名 LogAgent.channelsLogAgent.sinks = HDFS // 命名 LogAgent.sinksLogAgent.sources.apache.type = pooldir // 指定sources 类型LogAgent.sources.apache.channels = fileChannel //指定sources后面接的channel,即数据需要传入的指定channelLogAgent.sources.apache.spoolDir =/logs // 指定sources的监听目录LogAgent.sinks.HDFS.channel = fileChannel //指定sink前面接的channelLogAgent.sinks.HDFS.type = hdfs //指定sinks类型TwitterAgent.sinks.HDFS.hdfs.path=hdfs://hadoop1:8020/data/logs/%Y/%m/%d/%H/  //指定HDFS文件目录LogAgent.sinks.HDFS.hdfs.batchSize = 1000 //每次写1000条LogAgent.sinks.HDFS.hdfs.rollSize = 0LogAgent.sinks.HDFS.hdfs.rollCount = 10000 //当达到10000条产生一个文件LogAgent.channels.fileChannel.type = memory //指定channel 类型LogAgent.channels.apache.capacity = 10000 //指定channel存放的Event最大数目LogAgent.channels.apache.transactionCapacity = 100 //每次事物中,从source服务的数据或写入sink的数据

运行命令:
$ bin/flume-ng agent -n LogAgent -c conf -f conf/flume-conf.properties

常用拓扑实例2

这里写图片描述

上图中App-1利用Flume SDK的API直接把日志发送给Avro Source(用于Agent和Agent之间通信的IPC Source),然后写到fileChannel里面,再经过Avro sink把数据传给下一个Agent。由下一个Agent传入HDFS上。

第一层(Tier 1)配置实例

// 命名Agent内的三个组件名称a1.channels = c1a1.sources = r1a1.sinks = k1 k2a1.sinkgroups = g1 //因为有两个sink从同一个channel读数据,故组成一个group,但是他们后面链接的不是同一个Agent,即写入的位置不同a1.sinkgroups.g1.processor.type = LOAD_BALANCEa1.sinkgroups.g1.processor.selector = ROUND_ROBIN //两个sink轮询的从channel读数据a1.sinkgroups.g1.processor.backoff = truea1.channels.c1.type = FILE //指定channel类型a1.sources.r1.channels = c1 //指定sources链接的channela1.sources.r1.type = AVRO // 指定source类型a1.sources.r1.bind = 0.0.0.0 //绑定的IPa1.sources.r1.port = 41414 // 绑定的端口a1.sinks.k1.channel = c1a1.sinks.k1.type = AVRO// 名称为k1的sink会把数据写到a21.example.org位置a1.sinks.k1.hostname = a21.example.orga1.sinks.k1.port = 41414a1.sinks.k2.channel = c1a1.sinks.k2.type = AVRO// 名称为k2的sink会把数据写到a22.example.org位置a1.sinks.k2.hostname = a22.example.orga1.sinks.k2.port = 41414

第二层(Tier 2)配置实例

a2.channels = c1a2.sources = r1a2.sinks = k1a2.channels.c1.type = FILEa2.sources.r1.channels = c1a2.sources.r1.type = AVROa2.sources.r1.bind = 0.0.0.0a2.sources.r1.port = 41414a2.sinks.k1.channel = c1a2.sinks.k1.type = HDFSa2.sinks.k1.hdfs.path = hdfs://namenode.example.orga2.sinks.k1.hdfs.fileType = DataStream

日志分析系统:日志收集模块

这里写图片描述

这里写图片描述
注意上图中的sources采用的Exec类型,执行的command=tail -F /home/bigdata/datasource/record.list,就是监听/home/bigdata/datasource/record.list这个文件(这个文件内会产生数据源),一旦有变化就写入channel里面。

在日志分析中启动Flume系统,来收集数据,关键的操作步骤

1) 先启动namenode,datanode。
2) 修改节点中Flume安装目录里面的conf/XXX.properties配置代码如下,注意一些本地文件目录:

logAgent.sources = logSourcelogAgent.channels = fileChannellogAgent.sinks = hdfsSink# For each one of the sources, the type is definedlogAgent.sources.logSource.type = execlogAgent.sources.logSource.command = tail-F/home/bigdata/datasource/record.list //这个文件夹是存放产生的数据,source会从这个地址接收数据# The channel can be defined as follows.logAgent.sources.logSource.channels = fileChannel# Each sink's type must be definedlogAgent.sinks.hdfsSink.type = hdfslogAgent.sinks.hdfsSink.hdfs.path=hdfs://bigdata:9000/flume/record/%Y-%m-%d/%H%M //hdfs的地址,也就是sink把接收的数据传到这个地址。//这个在配置hadoop环境时,在hadoop安装目录的etc/hadoop修改的core-site.xml里修改的<name>fs.default</name> 对应的value。logAgent.sinks.hdfsSink.hdfs.filePrefix= transaction_loglogAgent.sinks.hdfsSink.hdfs.rollInterval= 600logAgent.sinks.hdfsSink.hdfs.rollCount= 10000logAgent.sinks.hdfsSink.hdfs.rollSize= 0logAgent.sinks.hdfsSink.hdfs.round = truelogAgent.sinks.hdfsSink.hdfs.roundValue = 10logAgent.sinks.hdfsSink.hdfs.roundUnit = minutelogAgent.sinks.hdfsSink.hdfs.fileType = DataStreamlogAgent.sinks.hdfsSink.hdfs.useLocalTimeStamp = true#Specify the channel the sink should uselogAgent.sinks.hdfsSink.channel = fileChannel# Each channel's type is defined.logAgent.channels.fileChannel.type = file//保存fileChannel断点的地址logAgent.channels.fileChannel.checkpointDir=/home/bigdata/apache-flume-1.7.0-bin/dataCheckpointDir// file类型的channel是将接收到的数据放在磁盘的某个地址logAgent.channels.fileChannel.dataDirs=/home/bigdata/apache-flume-1.7.0-bin/dataDir

3.)修改节点中Flume安装目录里面的conf/flume-env.sh配置代码如下

FLUME_CLASSPATH="$HADOOP_HOME/share/hadoop/common/hadoop-common-2.7.3.jar" 

这里先要在linux下环境变量配置好HADOOP_HOME

4)然后直接运行命令:

flume-ng agent --conf /usr/local/hadoop/apache-flume-1.7.0-bin/conf --conf-file /usr/local/hadoop/apache-flume-1.7.0-bin/conf/flume-conf-logAnalysis.properties --name logAgent -Dflume.root.logger=DEBUG,console -Dflume.monitoring.type=http -Dflume.monitoring.port=34545

注意命令中的/usr/local/hadoop/apache-flume-1.7.0-bin是你本地flume的安装目录,flume-conf-logAnalysis.properties就是上面那个配置文件XXX.properties,这个文件对Agent三个组件进行了配置。

原创粉丝点击