RICH-ATONE

flume自定义拦截器解决数据漂移问题及切分日志日期

flume中的数据漂移问题解决:

在flume-kafka-flume中

flume1:taildir source -- kafka channel

flume2:kafka source -- File channel -- HDFS sink

第二层flume的kafka source上挂上一个拦截器,用来修改由第一层flume中kafka channel产生的timestamp时间戳,用数据中的自带的时间戳来替换

1.以下为hadoop104中的flume的HDFSSink配置

## sink1
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = /origin_data/gmall/log/topic_log/%Y-%m-%d
a1.sinks.k1.hdfs.filePrefix = log-
a1.sinks.k1.hdfs.round = false 

2.数据上传到HDFS之后,%Y-%m-%d会转为具体的年月日,一条数据具体进入那天的路径,也就是说%Y-%m-%d具体转换成什么值,是由Flume Event中的一个header决定的。该header的key为“timestamp”,value为具体的一个时间戳,时间戳是哪一天,那%Y-%m-%d就会转成哪一天。

3.默认情况下Flume的Event中是没有timestamp这个header的,但是Kafka Source会为其加上该header,value为当前系统的时间戳。所以,如果不人为加拦截器去修改timestamp,那%Y-%m-%d 最终就会和系统时间保持一致。

4.如果加上如下拦截器,获取日志中的时间戳,作为该header的值,那就能保证%Y-%m-%d和数据的时间保持一致了了,也就不用修改系统时间了。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class TimestampInterceptor implements Interceptor {
 @Override
 public void initialize() {
 }
 @Override
 public Event intercept(Event event) {
 //获取Event中的body,并转为String字符串  byte[] body = event.getBody();
 String log = new String(body, StandardCharsets.UTF_8);
 //解析日志,得到json对象  JSONObject jsonObject = JSON.parseObject(log);

 if(jsonObject.containsKey("ts")){
 //获取json对象中的ts字段,即为日志的时间戳  String ts = jsonObject.getString("ts");

 //为event加入timestamp的header   event.getHeaders().put("timestamp",ts);
 }
 return event;
 }
 @Override
 public List<Event> intercept(List<Event> list) {

 for (Event event : list) {
 intercept(event);
 }
 return list;
 }
 @Override
 public void close() {
 }
 public static class Builder implements Interceptor.Builder{

 @Override
 public Interceptor build() {
 return new TimestampInterceptor();
 }
 @Override
 public void configure(Context context) {
 }
 }
}

  

5.思考

添加这个时间戳是为了能够保证当天生成的日志数据一定能上传到当天的hdfs目录下,就比如2021-03-15 23:59:59生成的日志文件,然后数据经过第一层的flume采集,加上kafka的缓冲,然后到hadoop104上的第二层的flume的时候,时间肯定就会到2021-03-16 00:00:XX了,这样一来,如果采用当前系统时间作为timestamp的话,2021-03-15的日志数据就会上传到hdfs上的2021-03-16的目录下,因此我们添加这个时间戳拦截器是非常有必要的。

参考:

flume自定义拦截器中常见的坑与maven打jar包两步走

posted on 2021-06-17 17:31  RICH-ATONE  阅读(459)  评论(0编辑  收藏  举报

导航