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. Container With Most Water 解答

    Question Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate ...

  2. 【LeetCode练习题】Minimum Path Sum

    Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to b ...

  3. 从设计模式说起JAVA I/O流

    从设计模式说起JAVA I/O流 之前写过一篇I/O流的入门介绍,直到最近看了设计模式,顺带理下I/O流的设计思路. JAVA类库中的I/O类分成输入和输出两部分,通过继承,任何自InputStrea ...

  4. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  5. Python3.X与Python2.x的区别

    一张图说明Python2.x与Python3.x的不同. Python3.x默认使用Unicode编码.支持中文. 更多介绍请看:https://segmentfault.com/a/11900000 ...

  6. IOS使用C#预处理命令,多种SDK共存

    当我们使用Unity接 91,XY助手等等SDK时候. 我们需要使用[DllImport("__Internal")] 来声明一个C++的方法调用. 不同的SDK总会有不同的方法. ...

  7. FileUpload的使用案例

    文件上传 1.www.apache.org下载commons fileupload 和 commons io 2.创建jsp并附上如下代码 <%@ page language="jav ...

  8. Unity uGUI 登录界面

    小记:进入冬季,天气确实变冷了,即使这样也不能作为自己不学习的理由!!! 昨天咱们一起学习了UGUI的Button的相关知识,那么今天咱们做一个简单的登录Demo,有些人可能不屑但是多学点总没什么坏处 ...

  9. C# Socket 简易的图片传输

    关于网络的数据传输我就是个小白,所以今天学习一下简易的Socket图片传输. 客户端和服务器的连接咱们上次已经学过了,咱们先从简易的文件传输入手.下面开始代码分析了. Server.cs using ...

  10. 根据一个旅游网站的psd素材还原的静态页面

    自学web前端的html.css和jquery两个月,想检验下自己的学习成果,遂从网上下了个关于旅游网站的psd素材,自己照着素材还原网站的静态页面. 这是我制作好的静态页面的压缩文件:旅游网站首页. ...