Flume

自定义flume的sink

 

目标:自定义sink,将rocketmq中的数据落地到本地文件

source的process方法相当于Event的生产者,不断向Channel中发送Event

sink的process方法相当于Event的消费者,不断从Channel中取出Event进行处理

总体流程:

1、通过getChannel方法 获取channel对象;

Channel ch = getChannel(); //获取当前sink绑定的channel

2、通过take方法从channel中取出Event

event = ch.take(); //取出消息Event

3、通过getBody获取消息的详细内容

byte[] msg = event.getBody(); //获取消息的详细内容

4、保存到本地,或者保存到HDFS

 

模版

public class MySink extends AbstractSink implements Configurable {

    // 创建 Logger 对象
    private static final Logger logger = LoggerFactory.getLogger(AbstractSink.class);
    
    private String prefix;
    private String suffix;


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



    /**
     * 1.获取 Channel
     * 2.从 Channel 获取事务和数据
     * 3.发送数据
     */
    @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 {
            // 处理事件(打印)
            logger.info(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 start() {
        // Initialize the connection to the external repository (e.g. HDFS) that this Sink will forward Events to ..
        // 初始化与外部存储库(例如HDFS)的连接,此接收器会将事件转发到。
    }

    @Override
    public void stop () {
        // Disconnect from the external respository and do any additional cleanup (e.g. releasing resources or nulling-out field values) ..
        // 断开与外部存储库的连接,然后进行其他任何清理操作(例如,释放资源或清空字段值)。
    }
}


详细解读:

 

核心:两个方法:

1、configure 获取配置信息

  @Override
    public void configure(Context context) {

    }

2、process  核心处理

    关键的几个点:

(1)getChannel方法(在父类AbstractSink中实现)

  取得当前sink绑定的channel对象,即拿到了要获取数据的channel

public synchronized Channel getChannel() {
    return this.channel;
}

(2) Channel接口提供了对事务进行操作的两个方法:

@Public
@Stable
public interface Channel extends LifecycleAware, NamedComponent {
    void put(Event var1) throws ChannelException;

    Event take() throws ChannelException;

    Transaction getTransaction();
}

getTransaction   获取事务 

取得事务对象,保证该数据被自定义的sink成功消费,消费成功,就进行事务提交,commit;同时Event将会从channel队列中删除;

如果没有成功消费,那么使用 

txn.rollback();//遇到异常,事务回滚

进行事务回滚,该Event仍然保留在channel队列里,等待下一次消费,保证消息不丢失。

take   取出消息Event (事件)

然后获取消息的详细内容 getBody 方法

byte[] mssage = event.getBody(); //获取消息的详细内容

接下来就可以进行消息保存到本地文件,或者传入到HDFS等。

 

@Override
    public Status process() throws EventDeliveryException {
        Channel ch = getChannel(); //获取当前sink绑定的channel
        //get the transaction 获取事务
        Transaction txn = ch.getTransaction();
     
        try {
            //begin the transaction
            txn.begin();
            Event event = null; //声明事件
            //读取channel中的事件,直到读取到事件结束循环
            while (true) {
                event = ch.take(); //取出消息Event
                if (event != null) break;
            }

            byte[] msg = event.getBody(); //获取消息的详细内容
            //保存到本地文件
            
            txn.commit();//提交事务
            return Status.READY;
        } catch (Throwable th) {
            txn.rollback();//遇到异常,事务回滚
            if (th instanceof Error) throw (Error) th;
            else throw new EventDeliveryException(th);
        } finally {
            txn.close();//关闭事务

         
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

                     

 自定义sink需要继承 AbstractSink类,然后实现 Configurable接口

public interface Configurable {
    void configure(Context var1);
}

主要是实现接口中的 

void configure(Context var1);

方法。

作用是:获取配置信息。

Context类提供了很多获取配置信息的方法

getBoolean

getInteger

getDouble

getString

getFloat

等等。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值