替代Flume——Kafka Connect简介

我们知道过去对于Kafka的定义是分布式,分区化的,带备份机制的日志提交服务。也就是一个分布式的消息队列,这也是他最常见的用法。但是Kafka不止于此,打开最新的官网。

我们看到Kafka最新的定义是:Apache Kafka® is a distributed streaming platform
分布式流处理平台。

这里也清晰的描述了Kafka的特点:Kafka用于构建实时数据管道和流式应用程序。它具有水平可扩展性、容错性、速度极快,并在数千家公司投入生产。
所以现在的Kafka已经不仅是一个分布式的消息队列,更是一个流处理平台。这源于它于0.9.0.0和0.10.0.0引入的两个全新的组件Kafka Connect与Kafka Streaming。
Kafka Connect简介
我们知道消息队列必须存在上下游的系统,对消息进行搬入搬出。比如经典的日志分析系统,通过flume读取日志写入kafka,下游由storm进行实时的数据处理。

Kafka Connect的作用就是替代Flume,让数据传输这部分工作可以由Kafka Connect来完成。Kafka Connect是一个用于在Apache Kafka和其他系统之间可靠且可靠地传输数据的工具。它可以快速地将大量数据集合移入和移出Kafka。
Kafka Connect的导入作业可以将数据库或从应用程序服务器收集的数据传入到Kafka,导出作业可以将Kafka中的数据传递到查询系统,也可以传输到批处理系统以进行离线分析。
Kafka Connect功能包括:
- 一个通用的Kafka连接的框架 - Kafka Connect规范化了其他数据系统与Kafka的集成,简化了连接器开发,部署和管理
- 分布式和独立模式 - 支持大型分布式的管理服务,也支持小型生产环境的部署
- REST界面 - 通过易用的REST API提交和管理Kafka Connect
- 自动偏移管理 - 只需从连接器获取一些信息,Kafka Connect就可以自动管理偏移量提交过程,因此连接器开发人员无需担心连接器开发中偏移量提交这部分的开发
- 默认情况下是分布式和可扩展的 - Kafka Connect构建在现有的组管理协议之上。可以添加扩展集群
- 流媒体/批处理集成 - 利用Kafka现有的功能,Kafka Connect是桥接流媒体和批处理数据系统的理想解决方案

运行Kafka Connect
Kafka Connect目前支持两种运行模式:独立和集群。
独立模式
在独立模式下,只有一个进程,这种更容易设置和使用。但是没有容错功能。
启动:
> bin/connect-standalone.sh config/connect-standalone.properties connector1.properties [connector2.properties ...]
独立模式配置
第一个参数config/connect-standalone.properties是一些基本的配置:
这几个在独立和集群模式下都需要设置:
#bootstrap.servers kafka集群列表
bootstrap.servers=localhost:9092
#key.converter key的序列化转换器 比如json的 key.converter=org.apache.kafka.connect.json.JsonConverter
#value.converter value的序列化转换器
value.converter=org.apache.kafka.connect.json.JsonConverter
#独立模式特有的配置:
#offset.storage.file.filename 用于存储偏移量的文件
offset.storage.file.filename =/home/kafka/connect.offsets
独立模式连接器配置(配置文件)
后面的参数connector1.properties [connector2.properties ...] 可以多个,是连接器配置内容
这里我们配置一个从文件读取数据并存入kafka的配置:
connect-file-sink.properties
name- 连接器的唯一名称。尝试再次使用相同名称注册将失败。connector.class- 连接器的Java类 此连接器的类的全名或别名。这里我们选择FileStreamSinktasks.max- 应为此连接器创建的最大任务数。如果连接器无法达到此级别的并行性,则可能会创建更少的任务。key.converter- (可选)覆盖worker设置的默认密钥转换器。value.converter- (可选)覆盖worker设置的默认值转换器。下面两个必须设置一个:
topics- 以逗号分隔的主题列表,用作此连接器的输入topics.regex- 用作此连接器输入的主题的Java正则表达式
name=local-file-sink
connector.class=FileStreamSink
tasks.max=1
file=test.sink.txt
topics=connect-test
可以在连接器中配置转换器
需要指定参数:
transforms- 转换的别名列表,指定将应用转换的顺序。transforms.$alias.type- 转换的完全限定类名。transforms.$alias.$transformationSpecificConfig转换的配置属性
例如,我们把刚才的文件转换器的内容添加字段
首先设置connect-standalone.properties
key.converter.schemas.enable = false
value.converter.schemas.enable = false
设置connect-file-source.properties
name=local-file-source
connector.class=FileStreamSource
tasks.max=1
file=test.txt
topic=connect-test
transforms=MakeMap, InsertSource
transforms.MakeMap.type=org.apache.kafka.connect.transforms.HoistField$Value
transforms.MakeMap.field=line
transforms.InsertSource.type=org.apache.kafka.connect.transforms.InsertField$Value
transforms.InsertSource.static.field=data_source
transforms.InsertSource.static.value=test-file-source
没有转换前的结果:
"foo"
"bar"
"hello world"
转换后:
{"line":"foo","data_source":"test-file-source"}
{"line":"bar","data_source":"test-file-source"}
{"line":"hello world","data_source":"test-file-source"}
常用转换类型:
- InsertField - 使用静态数据或记录元数据添加字段
- ReplaceField - 过滤或重命名字段
- MaskField - 用类型的有效空值替换字段(0,空字符串等)
- ValueToKey Value转换为Key
- HoistField - 将整个事件作为单个字段包装在Struct或Map中
- ExtractField - 从Struct和Map中提取特定字段,并在结果中仅包含此字段
- SetSchemaMetadata - 修改架构名称或版本
- TimestampRouter - 根据原始主题和时间戳修改记录主题
- RegexRouter - 根据原始主题,替换字符串和正则表达式修改记录主题
集群模式
集群模式下,可以扩展,容错。
启动:
> bin/connect-distributed.sh config/connect-distributed.properties
在集群模式下,Kafka Connect在Kafka主题中存储偏移量,配置和任务状态。
集群模式配置
connect-distributed.properties
#也需要基本的配置
bootstrap.servers=localhost:9092
key.converter=org.apache.kafka.connect.json.JsonConverter
value.converter=org.apache.kafka.connect.json.JsonConverter
#还有一些配置要注意
#group.id(默认connect-cluster) - Connect的组id 请注意,这不得与使用者的组id 冲突
group.id=connect-cluster
#用于存储偏移的主题; 此主题应具有许多分区
offset.storage.topic=connect-offsets
offset.storage.replication.factor=1
#用于存储连接器和任务配置的主题 只能一个分区
config.storage.topic=connect-configs
config.storage.replication.factor=1
#用于存储状态的主题; 此主题可以有多个分区
status.storage.topic=connect-status
status.storage.replication.factor=1
在集群模式下,配置并不会在命令行传进去,而是需要REST API来创建,修改和销毁连接器。
集群模式连接器配置(REST API)
可以配置REST API服务器,支持http与https
listeners=http://localhost:8080,https://localhost:8443
默认情况下,如果未listeners指定,则REST服务器使用HTTP协议在端口8083上运行。
以下是当前支持的REST API:
GET /connectors- 返回活动连接器列表POST /connectors- 创建一个新的连接器; 请求主体应该是包含字符串name字段的JSON对象和包含config连接器配置参数的对象字段GET /connectors/{name}- 获取有关特定连接器的信息GET /connectors/{name}/config- 获取特定连接器的配置参数PUT /connectors/{name}/config- 更新特定连接器的配置参数GET /connectors/{name}/status- 获取连接器的当前状态,包括它是否正在运行,失败,暂停等,分配给哪个工作人员,错误信息(如果失败)以及所有任务的状态GET /connectors/{name}/tasks- 获取当前为连接器运行的任务列表GET /connectors/{name}/tasks/{taskid}/status- 获取任务的当前状态,包括它是否正在运行,失败,暂停等,分配给哪个工作人员,以及错误信息是否失败PUT /connectors/{name}/pause- 暂停连接器及其任务,这将停止消息处理,直到恢复连接器PUT /connectors/{name}/resume- 恢复暂停的连接器(如果连接器未暂停,则不执行任何操作)POST /connectors/{name}/restart- 重新启动连接器(通常是因为它已经失败)POST /connectors/{name}/tasks/{taskId}/restart- 重启个别任务(通常因为失败)DELETE /connectors/{name}- 删除连接器,暂停所有任务并删除其配置
连接器开发指南
kakfa允许开发人员自己去开发一个连接器。
核心概念
要在Kafka和其他系统之间复制数据,用户需要创建一个Connector
Connector有两种形式:
SourceConnectors从另一个系统导入数据,例如,JDBCSourceConnector将关系数据库导入Kafka
SinkConnectors导出数据,例如,HDFSSinkConnector将Kafka主题的内容导出到HDFS文件
和对应的Task:
SourceTask和SinkTask
Task形成输入输出流,开发Task要注意偏移量的问题。
每个流应该是一系列键值记录。还需要定期提交已处理的数据的偏移量,以便在发生故障时,处理可以从上次提交的偏移量恢复。Connector还需要是动态的,实现还负责监视外部系统是否存在任何更改。
开发一个简单的连接器
开发连接器只需要实现两个接口,即Connector和Task。
这里我们简单开发一个FileStreamConnector。
此连接器是为在独立模式下使用,SourceConnector/ SourceTask读取文件的每一行,SinkConnector/ SinkTask每个记录写入一个文件。
连接器示例:
继承SourceConnector,添加字段(要读取的文件名和要将数据发送到的主题)
public class FileStreamSourceConnector extends SourceConnector {
private String filename;
private String topic;
定义实际读取数据的类
@Override
public Class<? extends Task> taskClass() {
return FileStreamSourceTask.class;
}
在FileStreamSourceTask下面定义该类。接下来,我们添加一些标准的生命周期方法,start()和stop()
@Override
public void start(Map<String, String> props) {
// The complete version includes error handling as well.
filename = props.get(FILE_CONFIG);
topic = props.get(TOPIC_CONFIG);
}
@Override
public void stop() {
// Nothing to do since no background monitoring is required.
}
最后,实施的真正核心在于taskConfigs()
@Override
public List<Map<String, String>> taskConfigs(int maxTasks) {
ArrayList<Map<String, String>> configs = new ArrayList<>();
// Only one input stream makes sense.
Map<String, String> config = new HashMap<>();
if (filename != null)
config.put(FILE_CONFIG, filename);
config.put(TOPIC_CONFIG, topic);
configs.add(config);
return configs;
}
任务示例:
源任务
实现SourceTask 创建FileStreamSourceTask继承SourceTask
public class FileStreamSourceTask extends SourceTask {
String filename;
InputStream stream;
String topic;
@Override
public void start(Map<String, String> props) {
filename = props.get(FileStreamSourceConnector.FILE_CONFIG);
stream = openOrThrowError(filename);
topic = props.get(FileStreamSourceConnector.TOPIC_CONFIG);
}
@Override
public synchronized void stop() {
stream.close();
}
接下来,我们实现任务的主要功能,即poll()从输入系统获取事件并返回以下内容的方法List:
@Override
public List<SourceRecord> poll() throws InterruptedException {
try {
ArrayList<SourceRecord> records = new ArrayList<>();
while (streamValid(stream) && records.isEmpty()) {
LineAndOffset line = readToNextLine(stream);
if (line != null) {
Map<String, Object> sourcePartition = Collections.singletonMap("filename", filename);
Map<String, Object> sourceOffset = Collections.singletonMap("position", streamOffset);
records.add(new SourceRecord(sourcePartition, sourceOffset, topic, Schema.STRING_SCHEMA, line));
} else {
Thread.sleep(1);
}
}
return records;
} catch (IOException e) {
// Underlying stream was killed, probably as a result of calling stop. Allow to return
// null, and driving thread will handle any shutdown if necessary.
}
return null;
}
接收任务
不像SourceConnector和SinkConnector,SourceTask并SinkTask有非常不同的接口,因为SourceTask采用的是拉接口,并SinkTask使用推接口。两者共享公共生命周期方法,但SinkTask完全不同:
public abstract class SinkTask implements Task {
public void initialize(SinkTaskContext context) {
this.context = context;
}
public abstract void put(Collection<SinkRecord> records);
public void flush(Map<TopicPartition, OffsetAndMetadata> currentOffsets) {
}
这是一个简单的例子,它们有简单的结构化数据 - 每一行只是一个字符串。几乎所有实用的连接器都需要具有更复杂数据格式的模式。要创建更复杂的数据,您需要使用Kafka Connect dataAPI。
Schema schema = SchemaBuilder.struct().name(NAME)
.field("name", Schema.STRING_SCHEMA)
.field("age", Schema.INT_SCHEMA)
.field("admin", new SchemaBuilder.boolean().defaultValue(false).build())
.build();
Struct struct = new Struct(schema)
.put("name", "Barbara Liskov")
.put("age", 75);
更多Kafka相关技术文章:
什么是Kafka?
Kafka监控工具汇总
Kafka快速入门
Kafka核心之Consumer
Kafka核心之Producer
更多实时计算,Flink,Kafka等相关技术博文,欢迎关注实时流式计算

替代Flume——Kafka Connect简介的更多相关文章
- Kafka Connect简介
Kafka Connect简介 http://colobu.com/2016/02/24/kafka-connect/#more Kafka 0.9+增加了一个新的特性Kafka Connect,可以 ...
- kafka connect简介以及部署
https://blog.csdn.net/u011687037/article/details/57411790 1.什么是kafka connect? 根据官方介绍,Kafka Connect是一 ...
- 最简单流处理引擎——Kafka Streaming简介
Kafka在0.10.0.0版本以前的定位是分布式,分区化的,带备份机制的日志提交服务.而kafka在这之前也没有提供数据处理的顾服务.大家的流处理计算主要是还是依赖于Storm,Spark Stre ...
- Kafka: Connect
转自:http://www.cnblogs.com/f1194361820/p/6108025.html Kafka Connect 简介 Kafka Connect 是一个可以在Kafka与其他系统 ...
- 简单测试flume+kafka+storm的集成
集成 Flume/kafka/storm 是为了收集日志文件而引入的方法,最终将日志转到storm中进行分析.storm的分析方法见后面文章,这里只讨论集成方法. 以下为具体步骤及测试方法: 1.分别 ...
- 【转】flume+kafka+zookeeper 日志收集平台的搭建
from:https://my.oschina.net/jastme/blog/600573 flume+kafka+zookeeper 日志收集平台的搭建 收藏 jastme 发表于 10个月前 阅 ...
- hadoop 之 kafka 安装与 flume -> kafka 整合
62-kafka 安装 : flume 整合 kafka 一.kafka 安装 1.下载 http://kafka.apache.org/downloads.html 2. 解压 tar -zxvf ...
- Flume+Kafka+Strom基于伪分布式环境的结合使用
目录: 一.Flume.Kafka.Storm是什么,如何安装? 二.Flume.Kafka.Storm如何结合使用? 1) 原理是什么? 2) Flume和Kafka的整合 3) Kafka和St ...
- Kafka connect快速构建数据ETL通道
摘要: 作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 业余时间调研了一下Kafka connect的配置和使用,记录一些自己的理解和心得,欢迎 ...
随机推荐
- 【MySQL】(五)索引与算法
本篇文章的主旨是对InnoDB存储引擎支持的索引做一个概述,并对索引内部的机制做一个深入的解析,通过了解索引内部构造来了解哪里可以使用索引. 1.InnoDB存储引擎支持以下几种常见的索引: B+树索 ...
- spark 源码分析之十九 -- Stage的提交
引言 上篇 spark 源码分析之十九 -- DAG的生成和Stage的划分 中,主要介绍了下图中的前两个阶段DAG的构建和Stage的划分. 本篇文章主要剖析,Stage是如何提交的. rdd的依赖 ...
- windos10专业版激活(可用)
电脑提示Windows许可证即将到期,于是自己就在网上找了一些教程,但是并没有激活成功,反而由即将到期变为了通知状态,尝试了各种密钥都不行,也下载了激活工具如暴风激活工具,KMS都不管用,尝试了好多方 ...
- sqlserver清除日志
在一次处理数据库日志已满的过程中,发现有的时候数据库日志不能清除,经实验,可以通过以下方式来完成. 使用exec sp_cycle_errorlog 来清除sql系统本身的临时日志. dump tra ...
- 15款好用超赞的chrome插件, 开发者们的必备~
今天推荐一波Chrome插件干货.这些插件带给我开发效率上的提升.所以在这里整理一下,分享给朋友们. 作为一名程序开发者,推荐一波常用的chrome插件,用了就舍不得丢,包括免费FQ工具,github ...
- Java中内部类的骚操作
10.1 如何定义内部类 如代码10.1-1 所示 public class Parcel1 { public class Contents{ private int value = 0; pu ...
- Python实现淘宝秒杀聚划算自动提醒源码
快来加入群[python爬虫交流群](群号570070796),发现精彩内容. 本实例能够监控聚划算的抢购按钮,在聚划算整点聚的时间到达时发出提醒(音频文件自己定义位置)并自动弹开页面(URL自己定义 ...
- HttpsUtils
package io.renren.modules.jqr.util; import java.io.BufferedReader; import java.io.InputStream; impor ...
- 对JAVA Bean使用PropertyDescriptor反射调用JAVA方法低耦合
对于符合JAVA Bean规范的bean,调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性. public void g ...
- 关于程序null值的见解
今天遇到了一个问题,查询一条数据,返回用list接,发现少了2个值(ssh框架).执行SQL少的这两个字段的值为null.上图说明一下: 可以看到第一次查询没有角标38.39的值. 是同一条SQL,第 ...