Kafka 来源

Kafka的前身是由LinkedIn开源的一款产品,2011年初开始开源,加入了 Apache 基金会,2012年从 Apache Incubator 毕业变成了 Apache 顶级开源项目。同时LinkedIn还有许多著名的开源产品。如:

  • 分布式数据同步系统Databus
  • 高性能计算引擎Cubert
  • Java异步处理框架ParSeq
  • Kafka流处理平台

Kafka 介绍

Kafka 用于构建实时数据管道和流应用程序。它具有水平可扩展性,容错性,快速性,并在数千家公司的生产环境中运行。

从官方我们可以知道ApacheKafka一个分布式流媒体平台。这到底是什么意思呢?

流媒体平台有三个关键功能:

  • 发布和订阅记录数据流,类似于消息队列或企业消息传递系统。
  • 有容错能力的可以持久化的存储数据流。
  • 记录发生时可以进行流处理。

Kafka 通常用于两大类应用:

  • 构建可在系统或应用程序之间可靠获取数据的实时流数据管道
  • 构建转换或响应数据流的实时流处理

Kafka 基本概念

  • Producer - 消息和数据的生产者,向 Kafka 的一个 Topic 发布消息的进程/代码/服务。
  • **Consumer **- 消息和数据的消费者,订阅数据(Topic)并且处理其发布的消息的进程/代码/服务。
  • Consumer Group - 逻辑概念,对于同一个 Topic,会广播不同的 Group,一个Group中,只有一个consumer 可以消费该消息。
  • Broker - 物理概念,Kafka 集群中的每个 Kafka 节点。
  • Topic - 逻辑概念,Kafka消息的类别,对数据进行区分,隔离。
  • Partition - 物理概念,分片,Kafka 下数据存储的基本单元,一个 Topic 数据,会被分散存储到多个Partition,每一个Partition是有序的。
  • **Replication **- 副本,同一个 Partition 可能会有多个 Replica ,多个 Replica 之间数据是一样的。
  • Replication Leader - 一个 Partition 的多个 Replica 上,需要一个 Leade r负责该 Partition 上与 Produce 和 Consumer 交互
  • ReplicaManager - 负责管理当前的 broker 所有分区和副本的信息,处理 KafkaController 发起的一些请求,副本状态的切换,添加/读取消息等。

概念的延伸

Partition

  • 每一个Topic被切分为多个Partitions
  • 消费者数据要小于等于Partition的数量
  • Broker Group中的每一个Broker保存Topic的一个或多个Partitions
  • Consumer Group中的仅有一个Consumer读取Topic的一个或多个Partions,并且是唯一的Consumer。

Replication

  • 当集群中有Broker挂掉的时候,系统可以主动的使用Replicas提供服务。
  • 系统默认设置每一个Topic的Replication的系数为1,可以在创建Topic的时候单独设置。

Replication特点

  • Replication的基本单位是Topic的Partition。
  • 所有的读和写都从Leader进,Followers只是作为备份。
  • Follower必须能够及时的复制Leader的数据
  • 增加容错性与可扩展性。

Kafka 消息结构

在 Kafka2.0 中的消息结构如下(整理自官网)。

baseOffset: int64 - 用于记录Kafka这个消息所处的偏移位置

batchLength: int32 - 用于记录整个消息的长度

partitionLeaderEpoch: int32

magic: int8 (current magic value is 2) - 一个固定值,用于快速判断是否是Kafka消息

crc: int32 - 用于校验信息的完整性

attributes: int16 - 当前消息的一些属性

bit 0~2:

0: no compression

1: gzip

2: snappy

3: lz4

bit 3: timestampType

​ bit 4: isTransactional (0 means not transactional)

​ bit 5: isControlBatch (0 means not a control batch)

​ bit 6~15: unused

lastOffsetDelta: int32

firstTimestamp : int64

maxTimestamp: int64

producerId: int64

producerEpoch: int16

baseSequence: int32

records:

length: varint

attributes: int8

bit 0~7: unused

timestampDelta: varint

offsetDelta: varint

keyLength: varint

key: byte[]

valueLen: varint

value: byte[]

Headers => [Header]

headerKeyLength: varint

headerKey: String

headerValueLength: varint

Value: byte[]

关于消息结构的一些释义。

  • Offset -用于记录Kafka这个消息所处的偏移位置
  • Length - 用于记录整个消息的长度
  • CRC32 - 用于校验信息的完整性
  • Magic - 一个固定值,用于快速判断是否是Kafka消息
  • Attributes - 当前消息的一些属性
  • Timestamp - 消息的时间戳
  • Key Length - key的长度
  • Key - Key的具体值
  • Value Length - 值的长度
  • Value - 具体的消息值

Kafka 优点

  1. 分布式 - Kafka是分布式的,多分区,多副本的和多订阅者的,基于Zookeeper调度。
  2. 持久性和扩展性 - Kafka使用分布式提交日志,这意味着消息会尽可能快地保留在磁盘上,因此它是持久的。同时具有一定的容错性,Kafka支持在线的水平扩展,消息的自平衡。
  3. 高性能 - Kafka对于发布和订阅消息都具有高吞吐量。 即使存储了许多TB的消息,它也保持稳定的性能。且延迟低,适用高并发。时间复杂的为o(1)。

Kafka 应用

  1. 用于聚合分布式应用程序中的消息。进行操作监控。
  2. 用于跨组织的从多个服务收集日志,然后提供给多个服务器,解决日志聚合问题。
  3. 用于流处理,如Storm和Spark Streaming,从kafka中读取数据,然后处理在写入kafka供应用使用。

Kafka 安装

安装 Jdk

具体步骤此处不说。

安装 Kafka

直接官方网站下载对应系统的版本解压即可。

由于Kafka对于windows和Unix平台的控制脚本是不同的,因此如果是windows平台,要使用bin\windows\而不是bin/,并将脚本扩展名更改为.bat。以下命令是基于Unix平台的使用。

# 解压
tar -xzf kafka_2.11-2.0.0.tgz
# 启动Zookeeper
bin/zookeeper-server-start.sh config/zookeeper.properties
# 启动Kafka
bin/kafka-server-start.sh config/server.properties
# 或者后台启动
bin/kafka-server-start.sh config/server.properties &

让我们创建一个名为“test”的主题,它只包含一个分区,只有一个副本:

`> bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

如果我们运行list topic命令,我们现在可以看到该主题:

`> bin/kafka-topics.sh --list --zookeeper localhost:2181 test

或者,您也可以将代理配置为在发布不存在的主题时自动创建主题,而不是手动创建主题。

查看Topic的信息

./kafka-topics.sh --describe --zookeeper localhost:2181 --topic Hello-Kafka

运行生产者,然后在控制台中键入一些消息以发送到服务器。

> bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
This is a message
This is another message`

运行消费者,查看收到的消息

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
> This is a message
> This is another message

Kafka 工程实例

POM 依赖

<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.1.0</version>
</dependency>

生产者

编写生产者 Java 代码。关于 Properties 中的值的意思描述可以在官方文档中找到 http://kafka.apache.org/ 。下面的生产者向 Kafka 推送了10条消息。

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties; /**
* <p>
* Kafka生产者,发送10个数据
*
* @Author niujinpeng
* @Date 2018/11/16 15:45
*/
public class MyProducer { public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers", "192.168.110.132:9092");
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); Producer<String, String> producer = new KafkaProducer<>(props);
for (int i = 0; i < 10; i++) {
producer.send(new ProducerRecord<String, String>("test", Integer.toString(i), Integer.toString(i)));
}
producer.close();
} }

消费者

编写消费者 Java 代码。


import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer; import java.util.Arrays;
import java.util.Properties; /**
* <p>
* Kafka消费者
*
* @Author niujinpeng
* @Date 2018/11/19 15:01
*/
public class MyConsumer { public static void main(String[] args) { Properties props = new Properties();
props.put("bootstrap.servers", "192.168.110.132:9092");
props.put("group.id", "test");
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("test"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}
}
} }

可以在控制台看到成功运行后的输出,由 offset 可以看到已经消费了10条消息。

 INFO | Kafka version : 2.0.0
INFO | Kafka commitId : 3402a8361b734732
INFO | Cluster ID: 0Xrk5M1CSJet0m1ut3zbiw
INFO | [Consumer clientId=consumer-1, groupId=test] Discovered group coordinator 192.168.110.132:9092 (id: 2147483647 rack: null)
INFO | [Consumer clientId=consumer-1, groupId=test] Revoking previously assigned partitions []
INFO | [Consumer clientId=consumer-1, groupId=test] (Re-)joining group
INFO | [Consumer clientId=consumer-1, groupId=test] Successfully joined group with generation 4
INFO | [Consumer clientId=consumer-1, groupId=test] Setting newly assigned partitions [test-0]
offset = 38, key = 0, value = 0
offset = 39, key = 1, value = 1
offset = 40, key = 2, value = 2
offset = 41, key = 3, value = 3
offset = 42, key = 4, value = 4
offset = 43, key = 5, value = 5
offset = 44, key = 6, value = 6
offset = 45, key = 7, value = 7
offset = 46, key = 8, value = 8
offset = 47, key = 9, value = 9

问题

如果java.net.InetAddress.getCanonicalHostName 取到的是主机名。需要修改 Kafka 的配置文件。

vim server.properties
# x.x.x.x是服务器IP
advertised.listeners=PLAINTEXT://x.x.x.x:9092

<完>

本文原发于个人博客:https://www.codingme.net 转载请注明出处

消息队列中间件(三)Kafka 入门指南的更多相关文章

  1. 初试kafka消息队列中间件二(采用java代码收发消息)

    初试kafka消息队列中间件二(采用java代码收发消息) 上一篇 初试kafka消息队列中间件一 今天的案例主要是将采用命令行收发信息改成使用java代码实现,根据上一篇的接着写: 先启动Zooke ...

  2. 初试kafka消息队列中间件一 (只适合初学者哈)

    初试kafka消息队列中间件一 今天闲来有点无聊,然后就看了一下关于消息中间件的资料, 简单一点的理解哈,网上都说的太高大上档次了,字面意思都想半天: 也就是用作消息通知,比如你想告诉某某你喜欢他,或 ...

  3. ActiveMQ RabbitMQ RokcetMQ Kafka实战 消息队列中间件视频教程

    附上消息队列中间件百度网盘连接: 链接: https://pan.baidu.com/s/1FFZQ5w17e1TlLDSF7yhzmA 密码: hr63

  4. c#开源消息队列中间件EQueue 教程

    一.简介 EQueue是一个参照RocketMQ实现的开源消息队列中间件,兼容Mono,具体可以参看作者的文章<分享一个c#写的开源分布式消息队列equeue>.项目开源地址:https: ...

  5. 常用的消息队列中间件mq对比

    原文地址:https://blog.csdn.net/qq_30764991/article/details/80239076 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量 ...

  6. nodejs一个函数实现消息队列中间件

    消息队列中间件(Message Queue)相信大家不会陌生,如Kafka.RabbitMQ.RocketMQ等,已经非常成熟,在大大小小的公司和项目中也已经广泛使用. 有些项目中,如果是只使用初步的 ...

  7. Delayer 基于 Redis 的延迟消息队列中间件

    Delayer 基于 Redis 的延迟消息队列中间件,采用 Golang 开发,支持 PHP.Golang 等多种语言客户端. 参考 有赞延迟队列设计 中的部分设计,优化后实现. 项目链接:http ...

  8. 基于硬件的消息队列中间件 Solace 简介之二

    前言...... 前面简单介绍了Solace来自于哪家公司, 主要能做哪些事情. 本篇主要进一步介绍Solace作为消息传递的中间件如何工作的. 传统意义上来讲, 每当我们谈到消息中间件时, 首先想到 ...

  9. Spring Boot 之 RabbitMQ 消息队列中间件的三种模式

    开门见山(文末附有消息队列的几个基本概念) 1.直接模式( Direct)模式 直白的说就是一对一,生产者对应唯一的消费者(当然同一个消费者可以开启多个服务). 虽然使用了自带的交换器(Exchang ...

随机推荐

  1. 守护模式,互斥锁,IPC通讯,生产者消费者模型

    '''1,什么是生产者消费者模型 生产者:比喻的是程序中负责产生数据的任务 消费者:比喻的是程序中负责处理数据的任务 生产者->共享的介质(队列)<-消费者 2,为何用 实现了生产者与消费 ...

  2. python 错误记录

    class Func: d = dict() def __setitem__(self, key, value): # xxx object does not support item assignm ...

  3. 837B. Balanced Substring

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. ip锁死怎么设置ip地址

    单击电脑网络连接图标,打开网络和共享中心   点击本地连接   点击详细信息,即可看到IP地址.子网掩码.默认网关.DNS服务器信息   再点击本地连接状态下的属性   找到Internet 协议版本 ...

  5. Java spring boot 2.0连接mysql异常:The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone

    解决办法:application.yml提示信息表明数据库驱动com.mysql.jdbc.Driver'已经被弃用了.应当使用新的驱动com.mysql.cj.jdbc.Driver' com.my ...

  6. vue-router下的html5 history在iis服务器上的设置 vue去掉#

    转自:https://www.cnblogs.com/zzsdream/p/6576639.html 1.安装 url rewrite模块到IIS 下载地址 2.在web.config文件中 syst ...

  7. XLua----热更新

    一.xLua 环境配置 1).Xlua中  Plugin  Xlua复制到 需要热更新的工程中---->Assets子目录 2).开启宏HOTFIX_ENABLE File---->bui ...

  8. C++的结构体指针传参

    typedef struct node{int n;node *left;}*tnode; 传参的时候注意用** void init(node **nn);int main(){tnode nna;i ...

  9. 【RL-TCPnet网络教程】第9章 RL-TCPnet网络协议栈移植(uCOS-III)

    第9章        RL-TCPnet网络协议栈移植(uCOS-III) 本章教程为大家讲解RL-TCPnet网络协议栈的uCOS-III操作系统移植方式,学习了第6章讲解的底层驱动接口函数之后,移 ...

  10. vue父子组件及非父子组件通信

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: <parent> <child :child-msg="msg" ...