我们知道过去对于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类 此连接器的类的全名或别名。这里我们选择FileStreamSink

  • tasks.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:

SourceTaskSinkTask

Task形成输入输出流,开发Task要注意偏移量的问题。

每个流应该是一系列键值记录。还需要定期提交已处理的数据的偏移量,以便在发生故障时,处理可以从上次提交的偏移量恢复。Connector还需要是动态的,实现还负责监视外部系统是否存在任何更改。

开发一个简单的连接器

开发连接器只需要实现两个接口,即ConnectorTask

这里我们简单开发一个FileStreamConnector。

此连接器是为在独立模式下使用,SourceConnectorSourceTask读取文件的每一行,SinkConnectorSinkTask每个记录写入一个文件。

连接器示例:

继承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;
}
接收任务

不像SourceConnectorSinkConnectorSourceTaskSinkTask有非常不同的接口,因为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简介的更多相关文章

  1. Kafka Connect简介

    Kafka Connect简介 http://colobu.com/2016/02/24/kafka-connect/#more Kafka 0.9+增加了一个新的特性Kafka Connect,可以 ...

  2. kafka connect简介以及部署

    https://blog.csdn.net/u011687037/article/details/57411790 1.什么是kafka connect? 根据官方介绍,Kafka Connect是一 ...

  3. 最简单流处理引擎——Kafka Streaming简介

    Kafka在0.10.0.0版本以前的定位是分布式,分区化的,带备份机制的日志提交服务.而kafka在这之前也没有提供数据处理的顾服务.大家的流处理计算主要是还是依赖于Storm,Spark Stre ...

  4. Kafka: Connect

    转自:http://www.cnblogs.com/f1194361820/p/6108025.html Kafka Connect 简介 Kafka Connect 是一个可以在Kafka与其他系统 ...

  5. 简单测试flume+kafka+storm的集成

    集成 Flume/kafka/storm 是为了收集日志文件而引入的方法,最终将日志转到storm中进行分析.storm的分析方法见后面文章,这里只讨论集成方法. 以下为具体步骤及测试方法: 1.分别 ...

  6. 【转】flume+kafka+zookeeper 日志收集平台的搭建

    from:https://my.oschina.net/jastme/blog/600573 flume+kafka+zookeeper 日志收集平台的搭建 收藏 jastme 发表于 10个月前 阅 ...

  7. hadoop 之 kafka 安装与 flume -> kafka 整合

    62-kafka 安装 : flume 整合 kafka 一.kafka 安装 1.下载 http://kafka.apache.org/downloads.html 2. 解压 tar -zxvf ...

  8. Flume+Kafka+Strom基于伪分布式环境的结合使用

    目录: 一.Flume.Kafka.Storm是什么,如何安装? 二.Flume.Kafka.Storm如何结合使用? 1) 原理是什么? 2) Flume和Kafka的整合  3) Kafka和St ...

  9. Kafka connect快速构建数据ETL通道

    摘要: 作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 业余时间调研了一下Kafka connect的配置和使用,记录一些自己的理解和心得,欢迎 ...

随机推荐

  1. Android系列教程之前言

    内容转载自我自己的博客 目前安卓的主流开发语言是Java,在正式开始Android系列的教程之前,需要知道一些基本内容 Android介绍 Android['ændrɔid] 是一个基于Linux 内 ...

  2. 《HelloGitHub》第 40 期

    <HelloGitHub>第 40 期 兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程. ...

  3. Hadoop自学系列集(二) ---- CentOS下安装JDK

    上篇我们讲述了如何使用VMware安装CentOS系统,接下来就看如何安装我们最为熟悉的jdk吧!安装前先看看系统上有没有安装过jdk,输入java -version,如果查询出了其他版本的jdk版本 ...

  4. 走近OPENCV // opencv 2.4.9+vs2013配置

    一直很懒去配opencv,这几周忍不了终于抽空来配了一下环境... 用的是旧版opencv2.4系列,最新到3.0了,之后再看看教程不知道有什么特别大的区别. (FF14国服没有4.0 // 8.19 ...

  5. 搭建PowerDNS+LAP+NFS+MySQL主从半节点同步实现LAMP架构

    实验环境:(共7台机器) PowerDNS: 192.168.99.110    两台LAP: 192.168.99.120 和 192.168.99.130 NFS服务器:192.168.99.14 ...

  6. 第三章、Go-内建容器

    3.1.数组 (1)数组的定义 package main import ( "fmt" ) func main() { //用var定义数组可以不用赋初值 var arr1 [5] ...

  7. win10家庭版打开组策略

    新建记事本,输入: @echo off pushd "%~dp0" dir /b C:\Windows\servicing\Packages\Microsoft-Windows-G ...

  8. 自定义SWT控件五之自定义穿梭框

    5.自定义穿梭框 package com.view.control.shuttlebox; import java.util.ArrayList; import java.util.HashMap; ...

  9. MongoDB之数据库备份与恢复

    MongoDB之数据备份与恢复 一,需求 一段时间备份数据库数据,以防意外导致数据丢失 二,备份与恢复 2.1,数据库备份 1,常用命令格式 mongodump -h IP --port 端口 -u ...

  10. RocketMq中网络通信之服务端

    一,Broker服务端入口(NettyServer端) 首先RocketMq网络通信采用的Netty通信.服务端主要集中在Broker中.我们先看一下Broker的启动类BrokerStartup 显 ...