大数据日志收集Flume

558 阅读3分钟

一、Flume概述

简介:Flume是一个分布式、可靠、高可用的海量日志聚合系统,目前最新版本称为Flume NG(next generation)

功能:Flume能将不同数据源的海量日志数据进行高效收集、聚合、移动,最后存储到一个中心化的数据存储系统中

使用案例:利用Flume高效地采集日志,同时对日志进行聚合,避免小文件的产生,然后将聚合后的数据通过管道移动到存储系统进行后续的数据分析和挖掘。

二、Flume设计概览

Agent是Flume的核心设计,也是Flume一个基本单元;Agent由三部分组成Source、Channel、Sink(如下图)

1635147289044.png Flume NG数据采集的工作机制如下。

1)Source接收数据,生产者

可以接收外部源发送过来的数据。不同的Source可以接收不同的数据格式。比如目录池(Spooling Directory)数据源,可以监控指定文件夹中的新文件变化,如果目录中有新文件产生,就会立刻读取其内容。

2)Channel:管道,生产消费者中的存储媒介

1.接收Source的输出,直到有Sink消费掉Channel中的数据。

2.Channel中的数据直到进入下一个Agent的Channel中或进入终端系统才会被删除

3.当Sink写入失败后可以自动重启,不会造成数据丢失,因此很可靠。

上面的2、3点都保证了数据的可靠性

3)Sink消费者

会消费Channel中的数据,然后发送给外部源(比如数据可以写入HDFS或HBase中)或下一个Agent的Source。

Agent核心组成

1.Source

通过Flume自带的Source(如下图)可以支持多种数据来源,比如Avro、Log4j、Syslog和HTTP,也可以自定义Souce,以IPC或RPC的方式接入自己的应用

1635149361309.png Source也可以直接读取文件,有两种方式Exec Source、Spool Source

  • Exec Source:通过Unix文件操作指令tail -f 文件名
  • Spool Source:监测新增文件,并采集文件中的数据

一般常用的就是Kafka Source

2.Channel

Channel是中转Event的一个临时存储,保存由Source组件传递过来的Event,目前比较常用的Channel有两种。

  • Memory Channel:内存中存储Event,不稳定,但是速度快
  • File Channel:持久化隧道,它将持久化所有的Event到磁盘中

1635149747745.png

3.Sink

Sink在设置存储数据时,可以向文件系统、数据库、Hadoop中存储数据。

在日志数据较少时,可以将数据存储在文件系统中,并且设定一定的时间间隔保存数据。在日志数据较多时,可以将相应的日志数据存储到Hadoop中,便于日后进行相应的数据分析。

1635149871245.png

4.Event

上面还谈到了Event,也就是所说到的数据。Flume是一个基于事件驱动的架构,Event产生后,监听数据变换,此后Agent才会做之后的数据处理工作

Event在代码中的表现形式如下

package org.apache.flume;
import java.util.Map;
public interface Event {
    Map<String, String> getHeaders();
    void setHeaders(Map<String, String> var1);
    byte[] getBody();
    void setBody(byte[] var1);
}

创建Event常用API

public class EventBuilder {
    public EventBuilder() {
    }
    public static Event withBody(byte[] body, Map<String, String> headers) {
        Event event = new SimpleEvent();
        if (body == null) {
            body = new byte[0];
        }
        event.setBody(body);
        if (headers != null) {
            event.setHeaders(new HashMap(headers));
        }
        return event;
    }
    public static Event withBody(byte[] body) {
        return withBody((byte[])body, (Map)null);
    }
    public static Event withBody(String body, Charset charset, Map<String, String> headers) {
        return withBody(body.getBytes(charset), headers);
    }
    public static Event withBody(String body, Charset charset) {
        return withBody(body, charset, (Map)null);
    }
}