flume-拦截器

  有的时候希望通过Flume将读取的文件再细分存储,比如讲source的数据按照业务类型分开存储,具体一点比如类似:将source中web、wap、media等的内容分开存储;比如丢弃或修改一些数据。这时可以考虑使用拦截器Interceptor。

  flume通过拦截器实现修改和丢弃事件的功能。拦截器通过定义类继承org.apache.flume.interceptor.Interceptor接口来实现。用户可以通过该节点定义规则来修改或者丢弃事件。Flume支持链式拦截,通过在配置中指定构建的拦截器类的名称。在source的配置中,拦截器被指定为一个以空格为间隔的列表。拦截器按照指定的顺序调用。一个拦截器返回的事件列表被传递到链中的下一个拦截器。当一个拦截器要丢弃某些事件时,拦截器只需要在返回事件列表时不返回该事件即可。若拦截器要丢弃所有事件,则其返回一个空的事件列表即可。

  先解释一下一个重要对象Event:event是flume传输的最小对象,从source获取数据后会先封装成event,然后将event发送到channel,sink从channel拿event消费。event由头(Map<String, String> headers)和身体(body)两部分组成:Headers部分是一个map,body部分可以是String或者byte[]等。其中body部分是真正存放数据的地方,headers部分用于本节所讲的interceptor。

Flume中拦截器的作用就是对于event中header的部分可以按需塞入一些属性,当然你如果想要处理event的body内容,也是可以的,但是event的body内容是系统下游阶段真正处理的内容,如果让Flume来修饰body的内容的话,那就是强耦合了,这就违背了当初使用Flume来解耦的初衷了。

1.初识拦截器接口

public interface Interceptor {
public void initialize(); public Event intercept(Event event); public List<Event> intercept(List<Event> events);
public void close(); public interface Builder extends Configurable {
public Interceptor build();
}
}

  1、public void initialize()运行前的初始化,一般不需要实现(上面的几个都没实现这个方法);

  2、public Event intercept(Event event)处理单个event;

  3、public List<Event> intercept(List<Event> events)批量处理event,实际上市循环调用上面的2;

  4、public void close()可以做一些清理工作,上面几个也都没有实现这个方法;

  5、 public interface Builder extends Configurable 构建Interceptor对象,外部使用这个Builder来获取Interceptor对象。

  如果要自己定制,必须要完成上面的2,3,5。

这个地方你可能有个很眼熟Configurable   这个拦截器的接口也继承了配置的接口,因为很多东西都是从配置读取出来的,所以你自己开发的之后上来一定脑子里面要有一个必须要实现的方法,即便说你不需要读取配置,你也给我写上!

2.TimestampInterceptor拦截器示例分析

1.initialize()方法解析

 @Override
public void initialize() {
// no-op
}

这个地方官方的几个拦截器都没有实现,我也没实现过。

2.close()方法解析

 @Override
public void close() {
// no-op
}

这个地方是一个关闭的方法。

3.Event intercept(Event event) 方法解析

    Map<String, String> headers = event.getHeaders();
if (preserveExisting && headers.containsKey(TIMESTAMP)) {
// we must preserve the existing timestamp
} else {
long now = System.currentTimeMillis();
headers.put(TIMESTAMP, Long.toString(now));
}
return event;

简单的循环调用了intercept对event逐一处理

4.public List<Event> intercept(List<Event> events)方法解析

    for (Event event : events) {
intercept(event);
}
return events;

批量的处理event,和上面的3相结合处理。

5.TimestampInterceptor的具体实现

  public static class Builder implements Interceptor.Builder {

    private boolean preserveExisting = PRESERVE_DFLT;

    @Override
public Interceptor build() {
return new TimestampInterceptor(preserveExisting);
} @Override
public void configure(Context context) {
preserveExisting = context.getBoolean(PRESERVE, PRESERVE_DFLT);
} }

该内部类实现了Interceptor的接口Builder,必须得有一个无参的构造方法,通过该构造方法就实例化了一个拦截器对象

6.该方法即拦截器的核心内容

1、如果拿到的event的header中本身包括timestamp这个key并且预留保存属性为true,我们就直接返回该event就行了。

2、否则的话,我们生成一个时间戳,并将这个时间戳放到event的header中,作为一个属性保存,再返回给event。

拦截器总结

1.拦截器被指定为一个以空格为间隔的列表,拦截器按照指定的顺序调用。

2.核心是返回一个拦截器对象。

3.实现自己的event处理机制。

自己写的event打包拦截器

public class EventCompressor extends AbstractFlumeInterceptor {
//static final String COMPRESS_FORMAT = "gzip"; @Override
public void initialize() {
// NOPE
} @Override
public Event intercept(Event event) {
Map<String, String> headers = event.getHeaders(); byte[] body = Compressor.compress(event.getBody()); //headers添加是否打包标志 headers.put(HeaderConstants.DEF_COMPRESS, HeaderConstants.VAL_COMPRESS_GZIP);
event.setBody(body);
return event;
}
@Override
public void close() {
// NOPE
} public static class Builder implements Interceptor.Builder {
@Override
public void configure(Context context) {
// NOPE
} @Override
public Interceptor build() {
return new EventCompressor();
}
}

自己的拦截器实例

因为flume 的数据采集到发送到kafka,如果一次一条数据的话很小,因此我把body取出来打包成大约40k左右的包来发送,还有一点kafka官方给出的一条消息大小为10k的时候kafka吞吐量达到最大效果。

flume【源码分析】分析Flume的拦截器的更多相关文章

  1. [从源码学设计] Flume 之 memory channel

    [从源码学设计] Flume 之 memory channel 目录 [从源码学设计] Flume 之 memory channel 0x00 摘要 0x01 业务范畴 1.1 用途和特点 1.2 C ...

  2. DispatcherServlet源码注解分析

    DispatcherServlet的介绍与工作流程 DispatcherServlet是SpringMVC的前端分发控制器,用于处理客户端请求,然后交给对应的handler进行处理,返回对应的模型和视 ...

  3. Spring Boot核心技术之Rest映射以及源码的分析

    Spring Boot核心技术之Rest映射以及源码的分析 该博客主要是Rest映射以及源码的分析,主要是思路的学习.SpringBoot版本:2.4.9 环境的搭建 主要分两部分: Index.ht ...

  4. MapReduce的ReduceTask任务的运行源码级分析

    MapReduce的MapTask任务的运行源码级分析 这篇文章好不容易恢复了...谢天谢地...这篇文章讲了MapTask的执行流程.咱们这一节讲解ReduceTask的执行流程.ReduceTas ...

  5. Activity源码简要分析总结

    Activity源码简要分析总结 摘自参考书籍,只列一下结论: 1. Activity的顶层View是DecorView,而我们在onCreate()方法中通过setContentView()设置的V ...

  6. MapReduce的MapTask任务的运行源码级分析

    TaskTracker任务初始化及启动task源码级分析 这篇文章中分析了任务的启动,每个task都会使用一个进程占用一个JVM来执行,org.apache.hadoop.mapred.Child方法 ...

  7. TaskTracker任务初始化及启动task源码级分析

    在监听器初始化Job.JobTracker相应TaskTracker心跳.调度器分配task源码级分析中我们分析的Tasktracker发送心跳的机制,这一节我们分析TaskTracker接受JobT ...

  8. MongoDB源码分析——mongod程序源码入口分析

    Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...

  9. FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  10. FFmpeg源码简单分析:libswscale的sws_scale()

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

随机推荐

  1. (转载)HDU4565

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565 这个博客讲的比较好:http://blog.csdn.net/ljd4305/article/d ...

  2. 修改MySQL 5.5的max_allowed_packet属性的方法

    今天在部署一个实验系统的时候,报出下面这个错: Your 'max_allowed_packet' variable is set to less than 16777216 Byte (16MB). ...

  3. MySql 取一天的开始时间和结束时间

    -- 取一开的开始时间 SELECT str_to_date(DATE_FORMAT(NOW(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'); -- 取第二天的开始时间 sele ...

  4. 清除mac上安装软件的用户信息

    有时候在mac系统上安装了一些软件后,尽管你将该软件卸载之后,可是原来的登录信息依然存在, 那么你就可以到下面的这个目录中查看一下,是否残留有信息文件.

  5. linux内存操作----kernel 3.5.X copy_from_user()和copy_to_user()

    前面的一篇文章中简单的描写叙述了一下内存映射的内容,http://blog.csdn.net/codectq/article/details/25658813,这篇文章作为用户把内存规划好之后,在用户 ...

  6. Html、CSS、JavaScript 实时效果在线编辑器 - 学习的好工具,算不算?!

    关于 二维码 与 NFC 之间的出身贫贱说 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 ...

  7. STL之nth_element()(取容器中的第n大值)

    nth_element()函数 头文件:#include<algorithm> 作用:nth_element作用为求第n大的元素,并把它放在第n位置上,下标是从0開始计数的,也就是说求第0 ...

  8. mysql5.7 二进制包安装

    1. 下载包 wget   http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.12-linux-glibc2.5-x86_64.tar.gz 2. 解 ...

  9. EF 事务处理 (InnoDB Engine的MySQL表也可以)

    备忘 1. 亲测(可以嵌套使用) using (TransactionScope scope = new TransactionScope()) { //操作1 XXEntities.Current. ...

  10. sql相关操作

    1.两个不同数据库对应字段相应操作 //操作模版:insert into data2.table2(字段1,字段2,字段) select 字段j,字段k,字段m from data1.table1举例 ...