数据收集之Flume实战

1、Flume介绍


三大组件:Source、Channel、Sink

Source:

从Client上收集数据并对数据进行格式化,以Event(事件)的形式传递给单个或者多个Event

Channel:

短暂的存储容器,将从Source接收到的Event进行缓存直接被Sink消费掉,Channel是Source和Sink之间的桥梁,Channel是一个完整的事务,能保证了数据在收发时的一致性,并且一个Channel可以同时和任意数量的Source和Sink建立连接。

Sink:

从Channel中消费数据(Event)并传递到存储容器(Hbase、HDFS)或其他的Source中。

工作流程:

把数据从数据源(Source)收集过来,在将收集到的数据送到指定的目的地(Sink)

为了保证输送过程一定成功,在送到目的地(Sink)之前,会先缓存数据(Channel),待数据真正到达目的地(Sink)后,flume在删除自己缓存的数据。

什么是Event?

  1. event将传输的数据进行封装,是flume传输数据的基本单位,如果是文本文件,通常是一行记录。
  2. event也是事务的基本单位
  3. event从source,流向channel,再到sink,本身为一个字节数组,并可以携带headers信息。

Agent

Flume以Agent最小的独立运行单元,Agent依赖于JVM,一个Agent的运行伴随一个JVM实例的产生。

一台机器可以运行多个Agent,一个Agent中可以包含多个Source、channel、sink。

1.1、Source组件

常用的source类型

描述

Avro Source

监听Avro端口并且以外部Avro客户端接受Event,需指定被监听IP和端口号

Exec Source

可以通过指定的Linux操作命令对日志进行读取,使用exec时需指定使用的命令

Spooling Directory Source

读取目录里的文件,当出现新文件时会读取该文件并获取数据(文件在读取过程中不能修改)

NetCat Source

监听指定的端口并将接收到的数据每一行转换为一个事件

Kafka Source

作为消费者,从Kafka的topic读取消息

Http Source

接受Http的GET和POST请求作为Flume的事件

Taildir Source

监控目录里的正则匹配文件,并支持断点续传

1.2、Channel组件

常用的Channel类型

描述

Memory Channel

存储Event在内存队列中,如果宕机可能会造成数据的丢失,具有很高的吞吐量

JDBC Channel

将Event存储在持久化的数据库中

Kafka Channel

将Event存储在Kafka中,Kafka提供了高可用和复制性,当Kafka或Agent崩溃时数据也不会丢失

File Channel

将Event持久化在本地文件系统里(性能较差)但可以保证数据不会丢失

Spillable Memory Channel

Event数据存储在内存和磁盘上,当内存队列满了将会持久化到磁盘文件

1.3、Sink组件

常用的sink类型

描述

Logger sink

将数据写到Flume的log中,通常用于测试或调试

Avro sink

将数据发送到其他Avri source

File Roll Sink

将数据放到本地文件系统中,根据时间或者大小生成文件

Kafka Sink

将文件写入Kafka中

HBase Sink

将数据写入HBase中

AsyncHBase Sink

使用异步的方式将数据写入HBase

Hive Sink

将数据写入Hive

HDFS Sink

将数据写入HDFS

ElasticSearch Sink

将数据写入ElasticSearch

MorphlineSolr Sink

将数据吸入Solr

2、安装Flume

2.1、先安装jdk

2.2、安装flume

配置flume运行大小

cd /usr/local/flume/conf
cp flume-env.sh.template flume-env.sh
vim flume-env.sh
export JAVA_OPTS="-Xms512m -Xmx1024m -Dcom.sum.management.jmxremote"

2.3、编写flume

a1.sources=r1
a1.sinks=k1
a1.channels=c1

#定义source
a1.sources.r1.type=netcat
a1.sources.r1.bind=linux-27309
a1.soruces.r1.port=44444

#定义channel
a1.channels.c1.type=memory
a1.channels.c1.capacity=10000
a1.channels.c1.transactionCapacity = 100

#定义sink
a1.sinks.k1.type=logger

#绑定
a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1

2.4、运行flume

flume-ng agent -n a1 -c /usr/local/flume/conf/ -f ./demo.agent -Dflume.root.logger=INFO,console

2.5、测试

telnet localhost 44444

3、实战Flume收集数据到hdfs

要求:数据采集

通过nginx先记录用户访问数据

3.1、安装nginx

(1)解压nginx压缩包

tar -zxvf nginx-1.22.1.tar.gz  -C /usr/local/

(2)到nginx目录下的configure编译

./configure

(3)安装

make && make install

(4)配置nginx的conf文件

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /data/access/access.log  main; ## 配置日志记录的位置

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

(5)到nginx的sbin目录下启动nginx

./nginx

3.2、安装hadoop

tar -zxvf hadoop-2.7.3.tar.gz -C /opt

3.3、启动flume

(1)编写agent

a1.sources=r1
a1.sinks=k1
a1.channels=c1


a1.sources.r1.type=taildir
a1.sources.r1.positionFile=/data/flume/taildir_position.json
a1.sources.r1.filegroups=f1
a1.sources.r1.filegroups.f1=/data/access/access.log
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=timestamp

a1.channels.c1.type=memory
a1.channels.c1.capacity=10000
a1.channels.c1.transactionCapacity=100

a1.sinks.k1.type=hdfs
a1.sinks.k1.hdfs.path=/data/hainiu/access_log/%Y/%m%d
a1.sinks.k1.hdfs.rollInterval=300
a1.sinks.k1.hdfs.rollSize=0
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.filePrefix=access_%Y%m%d
a1.sinks.k1.hdfs.fileSuffix=.log.snappy
a1.sinks.k1.hdfs.fileType=CompressedStream
a1.sinks.k1.hdfs.codeC=snappy

a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1

(2)启动agent

flume-ng agent -n a1 -c /usr/local/flume/conf/ -f ./access.agent -Dflume.root.logger=INFO,console

4、实战Flume收集数据到Kafka

(1)配置agent

kafka.agent

a1.sources=r1
a1.sinks=k1
a1.channels=c1


a1.sources.r1.type=TAILDIR
a1.sources.r1.positionFile=/data/flume/data/taildir_position_access.json
a1.sources.r1.filegroups=f1
a1.sources.r1.filegroups.f1=/data/access/access.log


a1.channels.c1.type=memory
a1.channels.c1.capacity=10000
a1.channels.c1.transactionCapacity=100


a1.sinks.k1.type=org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers=kafka1-52837:9092
a1.sinks.k1.kafka.topic=access

a1.sources.r1.channels=c1
a1.sinks.k1.channel=c1

(2)启动nginx

(3)启动flume

flume-ng agent -n a1 -c /usr/local/flume/conf/ -f ./kafka.agent -Dflume.root.logger=INFO,console

(4)启动kafka消费者

kafka-console-consumer.sh --bootstrap-server kafka1-52837:9092 --topic access

5、实战Flume收集数据到hdfs和kafka

(1)启动kafka

kafka-console-consumer.sh --bootstrap-server kafka1-52837:9092 --topic accesscomplex

(2)编写accesscomplex的agent

accesscomplex.agent

a1.sources=r1
a1.channels=c1 c2
a1.sinks=k1 k2

a1.sources.r1.type=taildir
a1.sources.r1.positionFile=/data/flume/position.json
a1.sources.r1.filegroups=f1
a1.sources.r1.filegroups.f1=/data/access/access.log
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type.timestamp=true

a1.channels.c1.type=memory
a1.channels.c1.capacity=10000
a1.channels.c1.transactionCapacity=100

a1.sinks.k1.type=hdfs
a1.sinks.k1.hdfs.path=/data/hainiu/access_log/%Y/%m%d
a1.sinks.k1.hdfs.rollInterval=300
a1.sinks.k1.hdfs.rollSize=0
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.filePrefix=access_%Y%m%d
a1.sinks.k1.hdfs.fileSuffix=.log.snappy
a1.sinks.k1.hdfs.fileType=CompressedStream
a1.sinks.k1.hdfs.codeC=snappy

a1.sinks.k2.type=org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k2.kafka.bootstrap.servers=kafka1-52837:9092
a1.sinks.k2.kafka.topic=accesscomplex

a1.sources.r1.channels=c1 c2
a1.sinks.k1.channel=c1
a1.sinks.k2.channel=c2

(3)重启nginx

/usr/local/nginx/sbin/nginx -s reload

6、扩展

一、put事务

1、doPut操作,将批数据写入到临时缓存区,Putlist中

2、doCommit操作:检查channel队列中是否有足够空间用来存放数据

3、如果channel空间不够,就会执行回滚数据的操作(doRollBack)

二、take事务

1、doTake操作,将数据写入临时缓存区,Takelist中

2、doCommit操作:将数据对外通过sink对外发送,如果发送成功,则清楚takelist的数据

3、如果发送失败则数据回滚

7、总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值