自定义Flume Sink:ElasticSearch Sink
Flume Sink的目的是从Flume Channel中获取数据然后输出到存储或者其他Flume Source中。Flume Agent启动的时候,它会为每一个Sink都启动一个SinkRunner的对象,SinkRunner.start()方法会启动一个新的线程去管理每一个Sink的生命周期。每一个Sink需要实现start()、Stop()和process()方法。你可以在start方法中去初始化Sink的参数和状态,在stop方法中清理Sink的资源。最关键的是process方法,它将处理从Channel中拿出来的数据。另外如果Sink有一些配置则需要实现Configurable接口。
由于Flume官方提供的Sink往往不能满足要求,所以我们自定义Sink来实现定制化的需求,这里以ElasticSearch为例。在Sink中实现所以文档的简单的Insert功能。例子使用Flume 1.7。
1. 编写代码
首先新建类ElasticSearchSink类继承AbstractSink类,由于还希望有自定义的Sink的配置,所以实现Configurable接口。
public class ElasticSearchSink extends AbstractSink implements Configurable
ElasticSearch的IP以及索引的名称可以配置在配置文件里面,配置文件就是使用flume的conf文件。你可以重写Configurable的configure的方法去获取配置,代码如下:
@Override
public void configure(Context context)
{
esHost = context.getString("es_host");
esIndex = context.getString("es_index");
}
注意里面的配置项“es_host”和“es_index”在conf配置文件中的语法:
agent.sinks = sink1
agent.sinks.sink1.type = nick.test.flume.ElasticSearchSink
agent.sinks.sink1.es_host = 192.168.50.213
agent.sinks.sink1.es_index = vehicle_event_test
接下来就是实现process方法,在这个方法中需要获取channel,因为数据都是从channel中获得的。获取消息之前,需要先获取一个Channel是事务,处理完成之后需要commit和关闭这个事务。这样才能让channel知道这个消息已经消费完成,它可以从它的内部队列中删除这个消息。如果消费失败,需要重新消费的话,可以rollback这个事务。事务的引入是flume对消息可靠性保证的关键。
process方法需要返回一个Status类型的枚举,Ready和BackOff。如果你到了一个消息,并正常处理了,需要使用Ready。如果拿到的消息是null,则可以返回BackOff。所谓BackOff(失效补偿)就是当sink获取不到 消息的时候, Sink的PollingRunner 线程需要等待一段backoff时间,等channel中的数据得到了补偿再来进行pollling 操作。
完整的代码如下:
public class ElasticSearchSink extends AbstractSink implements Configurable
{
private String esHost;
private String esIndex; private TransportClient client; @Override
public Status process() throws EventDeliveryException
{ Status status = null;
// Start transaction
Channel ch = getChannel();
Transaction txn = ch.getTransaction();
txn.begin();
try
{
Event event = ch.take(); if (event != null)
{
String body = new String(event.getBody(), "UTF-8"); BulkRequestBuilder bulkRequest = client.prepareBulk();
List<JSONObject> jsons = new ArrayList<JSONObject>(); JSONObject obj = JSONObject.parseObject(body); String vehicleId = obj.getString("vehicle_id");
String eventBeginCode = obj.getString("event_begin_code");
String eventBeginTime = obj.getString("event_begin_time"); //doc id in index
String id = (vehicleId + "_" + eventBeginTime + "_" + eventBeginCode).trim(); JSONObject json = new JSONObject();
json.put("vehicle_id", vehicleId); bulkRequest.add(client.prepareIndex(esIndex, esIndex).setSource(json)); BulkResponse bulkResponse = bulkRequest.get(); status = Status.READY;
}
else
{
status = Status.BACKOFF;
} txn.commit();
}
catch (Throwable t)
{
txn.rollback();
t.getCause().printStackTrace(); status = Status.BACKOFF;
}
finally
{
txn.close();
} return status; } @Override
public void configure(Context context)
{
esHost = context.getString("es_host");
esIndex = context.getString("es_index");
} @Override
public synchronized void stop()
{
super.stop();
} @Override
public synchronized void start()
{
try
{
Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(esHost), 9300));
super.start(); System.out.println("finish start");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
2. 打包、配置和运行
由于是自定义的Sink,所以需要打成jar包,然后copy到flume的lib文件夹下。然后配置agent的配置文件,最后启动flume就可以了。本例中,我使用了kafkasource、memorychannel和自定义的sink,完整的配置文件如下:
agent.sources = source1
agent.channels = channel1
agent.sinks = sink1 agent.sources.source1.type = org.apache.flume.source.kafka.KafkaSource
agent.sources.source1.channels = channel1
agent.sources.source1.batchSize = 1
agent.sources.source1.batchDurationMillis = 2000
agent.sources.source1.kafka.bootstrap.servers = 192.168.50.116:9092,192.168.50.117:9092,192.168.50.118:9092,192.168.50.226:9092
agent.sources.source1.kafka.topics = iov-vehicle-event
agent.sources.source1.kafka.consumer.group.id = flume-vehicle-event-nick agent.sinks.sink1.type = nick.test.flume.ElasticSearchSink
agent.sinks.sink1.es_host = 192.168.50.213
agent.sinks.sink1.es_index = vehicle_event_test agent.sinks.sink1.channel = channel1 agent.channels.channel1.type = memory
agent.channels.channel1.capacity = 1000

自定义Flume Sink:ElasticSearch Sink的更多相关文章
- 自定义flume的hbase sink 的序列化程序
package com.hello.hbase; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import ...
- Flume NG中的ElasticSearch Sink
ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...
- flink-----实时项目---day07-----1.Flink的checkpoint原理分析 2. 自定义两阶段提交sink(MySQL) 3 将数据写入Hbase(使用幂等性结合at least Once实现精确一次性语义) 4 ProtoBuf
1.Flink中exactly once实现原理分析 生产者从kafka拉取数据以及消费者往kafka写数据都需要保证exactly once.目前flink中支持exactly once的sourc ...
- Flume的Avro Sink和Avro Source研究之二 : Avro Sink
啊,AvroSink要复杂好多:< 好吧,先确定主要问题: AvroSink为啥这么多代码?有必要吗?它都有哪些逻辑需要实现? 你看,avro-rpc-quickstart里是这么建client ...
- Hadoop实战-Flume之Hdfs Sink(十)
a1.sources = r1 a1.sinks = k1 a1.channels = c1 # Describe/configure the source a1.sources.r1.type = ...
- flume 测试 hive sink
测试flume,将数据送到hive表中,首先建表. create table order_flume( order_id string, user_id string, eval_set string ...
- Flume配置Failover Sink Processor
1 官网内容 2 看一张图一目了然 3 详细配置 source配置文件 #配置文件: a1.sources= r1 a1.sinks= k1 k2 a1.channels= c1 #负载平衡 a1.s ...
- Flume的Avro Sink和Avro Source研究之一: Avro Source
问题 : Avro Source提供了怎么样RPC服务,是怎么提供的? 问题 1.1 Flume Source是如何启动一个Netty Server来提供RPC服务. 由GitHub上avro-rpc ...
- 基于Flume+Kafka+ Elasticsearch+Storm的海量日志实时分析平台(转)
0背景介绍 随着机器个数的增加.各种服务.各种组件的扩容.开发人员的递增,日志的运维问题是日渐尖锐.通常,日志都是存储在服务运行的本地机器上,使用脚本来管理,一般非压缩日志保留最近三天,压缩保留最近1 ...
随机推荐
- 制作chrome插件/扩展程序,禁止谷歌浏览器访问某些网站
简单地说,浏览器插件,可以大大的扩展你的浏览器的功能.包括但不仅限于这些功能: 捕捉特定网页的内容 捕捉HTTP报文 捕捉用户浏览动作,改变浏览器地址栏/起始页/书签/Tab等界面元素的行为 与别的站 ...
- vue-cli配置多入口多出口,实现一个项目两个访问地址,区分不同上线环境
最近工作中需要把项目分割成两块,一块需要跑在微信中,通过微信jdk获取用户资料默认登录,一部分需要给原生app做webview的内嵌页面,当然这部分内容是不跑在微信中的. 所以我想到了把项目分成两部分 ...
- 机械臂——arduino、marlin固件、printrun软件【转】
最近了解到,在市面上大多数机械臂控制都采用的arduino这个开源硬件来控制的,而我发现既然会单片机,就没有必要采用arduino来控制了,arduino只是一种为了简化编程而开发一种软硬件控制平台, ...
- C++ WINDOWS下 wchar_t *和char * 相互转化总结篇
说道wchar_t和char两个类型大家都不会陌生 wchar_t:在windows下是Unicode 16编码,也就是俗称宽字节 char:当然就是指一个字节,在windows下面默认是gbk编码的 ...
- hive sql 常见异常
1.union Logging initialized using configuration in file:/home/xiaoju/hadoop/apache-hive-1.2.1-bin/co ...
- PhpStorm配置SVN的完整方法
1.安装SVN时注意选择“command line client tools"默认是不安装的 2.设置系统环境变量 3.在PhpStorm上设置如下 4.然后通过VCS就可以上传导入你的工程 ...
- RobotFrameWork接口项目分层及通用控制方式
1. 前言 上一篇文章介绍了在设计接口用例之前应遵守的设计规范,详见<RobotFramework接口设计规范>,当然读者公司的内部规范也不一定非得完全遵循笔者所提到的,适合自己公司内部的 ...
- 单片机成长之路(51基础篇) - 009 关于sdcc的多文件编译范例(一)
本文是续 单片机成长之路(51基础篇) - 006 在Linux下搭建51单片机的开发烧写环境编写的. 本范例主要由(main.c ,delay.h,delay.c,makefile)4个文件组成,s ...
- 物联网系统与CoAP之Hello,World
物联网系统与CoAP Hello,World 关于CoAP与物联网系统我们在上一篇中(ps:CoAP与物联网系统)中做一个简单的介绍,接着我们便開始试试CoAP协议的应用 CoAP应用 開始之前我们须 ...
- (原)ffmpeg过滤器开发和理解
最近学习了ffmpeg关于filter过滤器的开发,关于中间的几个相关概念,我们先放在简单介绍一下: AVFilterGraph:几乎完全等同与directShow中的fitlerGraph,代表一串 ...