Flume1.9自定义Source和Sink实战

本文介绍了如何自定义Apache Flume的Source和Sink,通过实例展示了如何创建模拟数据源添加前缀,以及如何配置Sink给数据添加前后缀并输出到控制台。涉及配置文件的定制和实际操作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

在了解了flume的工作原理之后,在一定程度上可能会有自定义输入源和输出目的地的需求,因此本文做了一个简单的demo,以备后查

自定义Source 

Source是负责接收数据到Flume Agent的组件。Source组件可以处理各种类型、各种格式的日志数据,包括avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy。官方提供的source类型已经很多,但是有时候并不能满足实际开发当中的需求,此时我们就需要根据实际需求自定义某些source

概述 

Flume 1.10.0 Developer Guide — Apache Flume根据官方说明自定义MySource需要继承AbstractSource类并实现Configurable和PollableSource接口。

实现相应方法:

getBackOffSleepIncrement()//暂不用

getMaxBackOffSleepInterval()//暂不用

configure(Context context)//初始化context(读取配置文件内容)

process()//获取数据封装成event并写入channel,这个方法将被循环调用。

使用场景:读取MySQL数据或者其他文件系统

  

案例需求 

自定义source,模拟数据源,并给每条数据添加前缀,输出到控制台。前缀可从flume配置文件中配置

编码 

1.创建一个快速maven工程 

 

2.增加pom依赖 

PS: 版本最好和客户端版本一直,否则可能出现不兼容的情况

 <dependency>
        <groupId>org.apache.flume</groupId>
        <artifactId>flume-ng-core</artifactId>
        <version>1.9.0</version>
  </dependency>
package com.flume;

import org.apache.flume.Context;
import org.apache.flume.EventDeliveryException;
import org.apache.flume.PollableSource;
import org.apache.flume.conf.Configurable;
import org.apache.flume.event.SimpleEvent;
import org.apache.flume.source.AbstractSource;

import java.util.HashMap;

/**
 * <p>
 * 功能描述:自定义的source需要继承以下类,并实现其中的方法
 * </p>
 *
 * @author MILLA
 * @version 1.0
 * @since 2022/06/15 10:50
 */
public class MyFlumeSource extends AbstractSource implements Configurable, PollableSource {
    //定义配置文件将来要读取的字段
    private Long delay;
    private String field;

    /**
     * @return 接收数据将数据封装成event,写入channel
     * @throws EventDeliveryException
     */
    @Override
    public Status process() throws EventDeliveryException {
        try {
            //创建事件头信息
            HashMap<String, String> headerMap = new HashMap<>(16);
            //创建事件
            SimpleEvent event = new SimpleEvent();
            //循环封装事件
            for (int i = 0; i < 5; i++) {
                //给事件设置头信息
                event.setHeaders(headerMap);
                //给事件设置内容
                event.setBody((field + "-" + i).getBytes());
                //将事件写入channel
                getChannelProcessor().processEvent(event);
                Thread.sleep(delay);
            }
        } catch (Exception e) {
            return Status.BACKOFF;
        }
        return Status.READY;

    }

    @Override
    public long getBackOffSleepIncrement() {
        return 0;
    }

    @Override
    public long getMaxBackOffSleepInterval() {
        return 0;
    }

    /**
     * 从配置文件中获取一些固定的配置
     *
     * @param context
     */
    @Override
    public void configure(Context context) {
        delay = context.getLong("delay");
        field = context.getString("field", "I am a default value");
    }
}

 3.打包之后,将生生成的jar拷贝到flume/lib文件下

mvn clean package -DskipTests

 创建flume配置

vi mysource.conf
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = com.flume.MyFlumeSource
a1.sources.r1.delay = 1000
a1.sources.r1.field = customerSource

# Describe the sink
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

启动任务查看效果 

../../apache-flume-1.9.0-bin/bin/flume-ng agent \
-c ../../apache-flume-1.9.0-bin/conf/ \
-n a1 \
-f mysource.conf -Dflume.root.logger=INFO,console

注释掉mysource.conf中的a1.sources.r1.field = customerSource配置,重新启动效果如下 

 自定义Sink

Sink不断地轮询Channel中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个Flume Agent

Sink是完全事务性的。在从Channel批量删除数据之前,每个Sink用Channel启动一个事务。批量事件一旦成功写出到存储系统或下一个Flume Agent,Sink就利用Channel提交事务。事务一旦被提交,该Channel从自己的内部缓冲区删除事件。

Sink组件目的地包括hdfs、logger、avro、thrift、ipc、file、null、HBase、solr、自定义。官方提供的Sink类型已经很多,但是有时候并不能满足实际开发当中的需求,此时我们就需要根据实际需求自定义某些Sink

概述 

官方也提供了自定义source的接口:

Flume 1.10.0 Developer Guide — Apache Flume根据官方说明自定义MySink需要继承AbstractSink类并实现Configurable接口。

实现相应方法:

configure(Context context)//初始化context(读取配置文件内容)

process()//从Channel读取获取数据(event),这个方法将被循环调用。

使用场景:读取Channel数据写入MySQL或者其他文件系统

案例需求 

使用flume接收数据,并在Sink端给每条数据添加前缀和后缀,输出到控制台。前后缀可在flume任务配置文件中配置

 编码

在上一个工程上增加自定义Sink代码

package com.flume;

import org.apache.flume.Channel;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.EventDeliveryException;
import org.apache.flume.Transaction;
import org.apache.flume.conf.Configurable;
import org.apache.flume.sink.AbstractSink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * 功能描述:自定义的sink
 * </p>
 *
 * @author MILLA
 * @version 1.0
 * @since 2022/06/15 11:33
 */
public class MyFlumeSink extends AbstractSink implements Configurable {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractSink.class);

    private String prefix;
    private String suffix;

    @Override
    public Status process() throws EventDeliveryException {
        //声明返回值状态信息
        Status status;
        //获取当前Sink绑定的Channel
        Channel ch = getChannel();
        //获取事务
        Transaction txn = ch.getTransaction();
        //声明事件
        Event event;
        //开启事务
        txn.begin();
        //读取Channel中的事件,直到读取到事件结束循环
        while (true) {
            event = ch.take();
            if (event != null) {
                break;
            }
        }
        try {
            //处理事件(打印)
            LOG.info("Sink输出: " + prefix + new String(event.getBody()) + suffix);
            //事务提交
            txn.commit();
            status = Status.READY;
        } catch (Exception e) {
            //遇到异常,事务回滚
            txn.rollback();
            status = Status.BACKOFF;
        } finally {
            //关闭事务
            txn.close();
        }
        return status;
    }

    @Override
    public void configure(Context context) {
        //读取配置文件内容,有默认值
        prefix = context.getString("prefix", "hello:");
        //读取配置文件内容,无默认值
        suffix = context.getString("suffix");
    }
}

创建flume配置 

 vi mysink.conf
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
# 指定自定义的source
a1.sources.r1.type = com.flume.MyFlumeSource
a1.sources.r1.delay = 1000
a1.sources.r1.field = o(∩_∩)o

# Describe the sink
# 指定自定义的sink
a1.sinks.k1.type =com.flume.MyFlumeSink
a1.sinks.k1.prefix = pre-
a1.sinks.k1.suffix = -suf


# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

启动任务 

../../apache-flume-1.9.0-bin/bin/flume-ng agent \
-c ../../apache-flume-1.9.0-bin/conf/ \
-n a1 \
-f mysink.conf -Dflume.root.logger=INFO,console

 执行效果

 

 总结

自定义的数据源可以换成从数据库、文件系统、爬虫等等

自定义的输出可以是写入数据库,文件系统等等

同时也将自定义的数据源和自定义的输出整合了起来

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值