数据采集整体架构如下图所示:
更加详细的架构图:
- 为什么要集成Flume+Kafka?
可能很多人会跟我有相同的问题,这里采集数据为什么要集成Flume+Kafka?我通过搜集资料了解到:我们采集过来的数据,通常会进行存储或者是提供给Spark/Flink/Storm做实时处理的,但是由于Flume没有缓存,是直接采集数据的,当采集数据的速度大于处理速度的时候就会造成数据积压或者丢失,这时候Kafka就发挥作用了,Kafka是一个消息队列,它可以将数据缓存到内存或者写到磁盘上,有很好的缓冲效果,可以起到一个消峰的作用。 - Flume用什么Source?为什么?
读取日志文件可以用以下Source:
①ExecSource:不安全,可能会丢数据!
②SpoolingDirSource:可以读取一个目录下的文件,读取过程中要保证目录是封闭的,即在读取过程中不能往目录追加日志,这样肯定不行,因为在生产环境中日志数据是源源不断生成的。
③TailDirSource:接近实时读取指定文件或者目录!所以使用此Source! - 拦截器具体实现
要想写一个拦截器,首先要实现拦截器Interceptor接口,然后实现所需要实现的方法。在介绍拦截器功能之前,先来说一下数据的格式:数据分为两种启动日志和事件日志。拦截器除了拦截格式有误的数据还给不同的数据的投做不同的标记,比如在启动日志数据的Header加上topic_start,在事件日志的Header家伙是哪个topic_event。启动日志里面必定包含{“en”:“start”},所以很好区分,用一个if语句即能搞定。再来看看启动日志的格式是以“{”开头,“}”结尾的JSON串,而事件日志则是:时间戳|{} 的格式,所以要验证时间戳是否合法还有大括号的完整性。
这里的拦截器主要实现了以下功能:
具体实现代码如下:
package cn.edu.lingnan.dw.flume;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
//自定义拦截器
public class MyInterceptor implements Interceptor {
private List<Event> results = new ArrayList<Event>(