kafka的消费顺序_Kafka基础知识大补

本文深入探讨了Kafka的基础知识,包括其作为集群的工作原理、主题与日志、偏移量管理、分布式特性以及消费者模型。Kafka不仅支持消息系统的功能,还适用于日志收集、用户活动跟踪等多种场景。通过Kafka的核心API,如生产者、消费者和流处理,文章展示了如何在实际应用中使用Kafka。此外,还介绍了Kafka与其他消息中间件如ActiveMQ、RabbitMQ的对比。
摘要由CSDN通过智能技术生成

01 kafka基础

Kafka概念

  • Kafka作为一个集群,运行在一台或者多台服务器上。
  • Kafka 通过 topic 对存储的流数据进行分类。
  • 每条记录中包含一个key,一个value和一个timestamp(时间戳)。

Kafka特性

  • 可以让你发布和订阅流式的记录。这一方面与消息队列或者企业消息系统类似。
  • 可以储存流式的记录,并且有较好的容错性。
  • 可以在流式记录产生时就进行处理。

Kafka适用场景

  • 构造实时流数据管道,它可以在系统或应用之间可靠地获取数据。 (mq)
  • 构建实时流式应用程序,对这些流数据进行转换或者影响。 (就是流处理,通过kafka stream topic和topic之间内部进行变化)

Kafka使用场景

1.日志收集

一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。

2.消息系统

解耦和生产者和消费者、缓存消息等。

3.用户活动跟踪

Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。

4.运营指标

Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。

5.流式处理

比如spark streaming和storm

Kafka核心API

  • Producer 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。
  • Consumer 允许一个应用程序订阅一个或多个 topic ,并且对发布给他们的流式数据进行处理。
  • Streams 允许一个应用程序作为一个流处理器,消费一个或者多个topic产生的输入流,然后生产一个输出流到一个或多个topic中去,在输入输出流中进行有效的转换。
  • Connector 允许构建并运行可重用的生产者或者消费者,将Kafka topics连接到已存在的应用程序或者数据系统。比如,连接到一个关系型数据库,捕捉表(table)的所有变更内容。

Topics 与日志

Topic 就是数据主题,是数据记录发布的地方,可以用来区分业务系统。Kafka中的Topics总是多订阅者模式,一个topic可以拥有一个或者多个消费者来订阅它的数据。

对于每一个topic, Kafka集群都会维持一个分区日志。

每个分区都是有序且顺序不可变的记录集,并且不断地追加到结构化的commit log文件。分区中的每一个记录都会分配一个id号来表示顺序,称之为offset,offset用来唯一的标识分区中每一条记录。

日志中的 partition(分区)有以下几个用途。

第一,当日志大小超过了单台服务器的限制,允许日志进行扩展。每个单独的分区都必须受限于主机的文件限制,不过一个主题可能有多个分区,因此可以处理无限量的数据。

第二,可以作为并行的单元集—关于这一点。

a01ba069ffbab2b209fb9965e05780fc.png

Offset

每一个分区都是一个顺序的、不可变的消息队列,并且可以持续的添加。分区中的消息都被分配了一个序列号,称之为偏移量(offset),在每个分区中此偏移量都是唯一的。

一个分区在文件系统里存储为一个文件夹。文件夹里包含日志文件和索引文件。其文件名是其包含的offset的最小的条目的offset。

b44f51547c29fdf4bfeff5b06f850e71.png
99c94c5f37f44ace499e57fd190aea6c.png

offset

要查找offset为7的Message:首先是用二分查找确定它是在哪个LogSegment中,自然是在第一个Segment中。

打开这个Segment的index文件,也是用二分查找找到offset小于或者等于指定offset的索引条目中最大的那个offset。自然offset为6的那个索引是我们要找的,通过索引文件我们知道offset为6的Message在数据文件中的位置为9807。

打开数据文件,从位置为9807的那个地方开始顺序扫描直到找到offset为7的那条Message。

这套机制是建立在offset是有序的。索引文件被映射到内存中,所以查找的速度还是很快的。

一句话,Kafka的Message存储采用了分区(partition),分段(LogSegment)和稀疏索引这几个手段来达到了高效性。

分布式

日志的分区partition (分布)在Kafka集群的服务器上。每个服务器在处理数据和请求时,共享这些分区。每一个分区都会在已配置的服务器上进行备份,确保容错性.

每个分区都有一台 server 作为 “leader”,零台或者多台server作为 follwers 。leader server 处理一切对 partition (分区)的读写请求,而follwers只需被动的同步leader上的数据。当leader宕机了,followers 中的一台服务器会自动成为新的 leader。每台 server 都会成为某些分区的 leader 和某些分区的 follower,因此集群的负载是平衡的。

生产者

生产者可以将数据发布到所选择的topic(主题)中。生产者负责将记录分配到topic的哪一个 partition(分区)中。可以使用循环的方式来简单地实现负载均衡,也可以根据某些语义分区函数(例如:记录中的key)来完成。

消费者

消费者使用一个 消费组 名称来进行标识,发布到topic中的每条记录被分配给订阅消费组中的一个消费者实例.消费者实例可以分布在多个进程中或者多个机器上。

如果所有的消费者实例在同一消费组中,消息记录会负载平衡到每一个消费者实例.

如果所有的消费者实例在不同的消费组中,每条消息记录会广播到所有的消费者进程。

af64632dfac72df975db57882133ba4d.png

如上图所示, Kafka 集群有两台 server 的,四个分区(p0-p3)和两个消费者组。消费组A有两个消费者,消费组B有四个消费者。

通常情况下,每个 topic 都会有一些消费组,一个消费组对应一个"逻辑订阅者"。一个消费组由许多消费者实例组成,便于扩展和容错。这就是发布和订阅的概念,只不过订阅者是一组消费者而不是单个的进程。

在Kafka中实现消费的方式是将日志中的分区划分到每一个消费者实例上,以便在任何时间,每个实例都是分区唯一的消费者。维护消费组中的消费关系由Kafka协议动态处理。如果新的实例加入组,他们将从组中其他成员处接管一些 partition 分区;如果一个实例消失,拥有的分区将被分发到剩余的实例。

Kafka 只保证分区内的记录是有序的,而不保证主题中不同分区的顺序。每个 partition 分区按照key值排序足以满足大多数应用程序的需求。但如果你需要总记录在所有记录的上面,可使用仅有一个分区的主题来实现,这意味着每个消费者组只有一个消费者进程。

Kafka作为消息系统

消费组在Kafka有两层概念。在队列中,消费组允许你将处理过程分发给一系列进程(消费组中的成员)。 在发布订阅中,Kafka允许你将消息广播给多个消费组。

Kafka的优势在于每个topic都有以下特性—可以扩展处理并且允许多订阅者模式—不需要只选择其中一个。

Kafka 设计的更好。topic中的partition是一个并行的概念。 Kafka能够为一个消费者池提供顺序保证和负载平衡,是通过将topic中的partition分配给消费者组中的消费者来实现的, 以便每个分区由消费组中的一个消费者消耗。通过这样,我们能够确保消费者是该分区的唯一读者,并按顺序消费数据。 众多分区保证了多个消费者实例间的负载均衡。但请注意,消费者组中的消费者实例个数不能超过分区的数量。

Kafka 作存储系统

数据写入Kafka后被写到磁盘,并且进行备份以便容错。直到完全备份,Kafka才让生产者认为完成写入,即使写入失败Kafka也会确保继续写入。

Kafka用做流处理

Kafka流处理器不断地从输入的topic获取流数据,处理数据后,再不断生产流数据到输出的topic中去。

批处理

将消息、存储和流处理结合起来,使得Kafka看上去不一般,但这是它作为流平台所备的。

Kafka 配置介绍

Broker 核心配置

  • broker.id

用于服务的broker id。如果没设置,将生存一个唯一broker id。为了避免ZooKeeper生成的id和用户配置的broker id相冲突,生成的id将在reserved.broker.max.id的值基础上加1。

  • log.dirs

保存日志数据的目录,如果未设置将使用log.dir的配置。

  • zookeeper.connect

Zookeeper主机地址

Topic级别配置

与Topic相关的配置既包含服务器默认值,也包含可选的每个Topic覆盖值。 如果没有给出每个Topic的配置,那么服务器默认值就会被使用。 通过提供一个或多个 --config 选项,可以在创建Topic时设置覆盖值。

  • 使用自定义的最大消息大小和刷新率创建了一个名为 my-topic 的topic:

> bin/kafka-topics.sh

--zookeeper localhost:2181

--create --topic my-topic --partitions 1

--replication-factor 1

--config max.message.bytes=64000

--config flush.messages=1

  • 可以在使用alter configs命令稍后更改或设置覆盖值. 本示例重置my-topic的最大消息的大小:

> bin/kafka-configs.sh

--zookeeper localhost:2181

--entity-type topics

--entity-name my-topic

--alter

--add-config max.message.bytes=128000

......

Producer 配置

比较核心的配置:metadata.broker.list、request.required.acks、producer.type、serializer.class

## 消费者获取消息元信息(topics, partitions and replicas)的地址,配置格式是:host1:port1,host2:port2,也可以在外面设置一个vip

metadata.broker.list

##消息的确认模式

##0:不保证消息的到达确认,只管发送,低延迟但是会出现消息的丢失,在某个server失败的情况下,有点像TCP

##1:发送消息,并会等待leader 收到确认后,一定的可靠性

## -1:发送消息,等待leader收到确认,并进行复制操作后,才返回,最高的可靠性

request.required.acks =0

## 消息发送的最长等待时间

request.timeout.ms =10000

## socket的缓存大小

send.buffer.bytes=100*1024

## key的序列化方式,若是没有设置,同serializer.class

key.serializer.class

## 分区的策略,默认是取模

partitioner.class=kafka.producer.DefaultPartitioner

## 消息的压缩模式,默认是none,可以有gzip和snappy

compression.codec = none

## 可以针对默写特定的topic进行压缩

compressed.topics=null

## 消息发送失败后的重试次数

message.send.max.retries =3

## 每次失败后的间隔时间

retry.backoff.ms =100

## 生产者定时更新topic元信息的时间间隔 ,若是设置为0,那么会在每个消息发送后都去更新数据

topic.metadata.refresh.interval.ms =600*1000

## 用户随意指定,但是不能重复,主要用于跟踪记录消息

client.id=""

消息模式 相关

## 生产者的类型 async:异步执行消息的发送 sync:同步执行消息的发送

producer.type=sync

## 异步模式下,那么就会在设置的时间缓存消息,并一次性发送

queue.buffering.max.ms =5000

## 异步的模式下 最长等待的消息数

queue.buffering.max.messages =10000

## 异步模式下,进入队列的等待时间 若是设置为0,那么要么进入队列,要么直接抛弃

queue.enqueue.timeout.ms = -1

## 异步模式下,每次发送的最大消息数,前提是触发了queue.buffering.max.messages或是queue.buffering.max.ms的限制

batch.num.messages=200

## 消息体的系列化处理类 ,转化为字节流进行传输

serializer.class= kafka.serializer.DefaultEncoder

Consumer 配置

最为核心的配置是group.id、zookeeper.connect

## Consumer归属的组ID,broker是根据group.id来判断是队列模式还是发布订阅模式,非常重要

group.id

## 消费者的ID,若是没有设置的话,会自增

consumer.id

## 一个用于跟踪调查的ID ,最好同group.id相同

client.id = group id value

## 对于zookeeper集群的指定,可以是多个 hostname1:port1,hostname2:port2,hostname3:port3 必须和broker使用同样的zk配置

zookeeper.connect=localhost:2182

## zookeeper的心跳超时时间,查过这个时间就认为是dead消费者

zookeeper.session.timeout.ms =6000

## zookeeper的等待连接时间

zookeeper.connection.timeout.ms =6000

## zookeeper的follower同leader的同步时间

zookeeper.sync.time.ms =2000

## 当zookeeper中没有初始的offset时候的处理方式 。smallest :重置为最小值 largest:重置为最大值 anythingelse:抛出异常

auto.offset.reset = largest

## socket的超时时间,实际的超时时间是:max.fetch.wait + socket.timeout.ms.

socket.timeout.ms=30*1000

## socket的接受缓存空间大小

socket.receive.buffer.bytes=64*1024

##从每个分区获取的消息大小限制

fetch.message.max.bytes =1024*1024

## 是否在消费消息后将offset同步到zookeeper,当Consumer失败后就能从zookeeper获取最新的offset

auto.commit.enable =true

## 自动提交的时间间隔

auto.commit.interval.ms =60*1000

## 用来处理消费消息的块,每个块可以等同于fetch.message.max.bytes中数值

queued.max.message.chunks =10

## 当有新的consumer加入到group时,将会reblance,此后将会有partitions的消费端迁移到新

## 的consumer上,如果一个consumer获得了某个partition的消费权限,那么它将会向zk注册

##"Partition Owner registry"节点信息,但是有可能此时旧的consumer尚没有释放此节点,

## 此值用于控制,注册节点的重试次数.

rebalance.max.retries =4

## 每次再平衡的时间间隔

rebalance.backoff.ms =2000

## 每次重新选举leader的时间

refresh.leader.backoff.ms

## server发送到消费端的最小数据,若是不满足这个数值则会等待,知道满足数值要求

fetch.min.bytes =1

## 若是不满足最小大小(fetch.min.bytes)的话,等待消费端请求的最长等待时间

fetch.wait.max.ms =100

## 指定时间内没有消息到达就抛出异常,一般不需要改

consumer.timeout.ms = -1

Kafka Connect 配置

Kafka Streams 配置

AdminClient 配置


02 Kafka架构

一个典型的 Kafka 体系架构包括若干 Producer(消息生产者),若干 broker(作为 Kafka 节点的服务器),若干 Consumer(Group),以及一个 ZooKeeper 集群。Kafka通过 ZooKeeper 管理集群配置、选举 Leader 以及在 consumer group 发生变化时进行 Rebalance(即消费者负载均衡,在下一课介绍)。Producer 使用 push(推)模式将消息发布到 broker,Consumer 使用 pull(拉)模式从 broker 订阅并消费消息。

下图:一个总体架构,并没有对作为 Kafka 节点的 broker 进行深入刻画,事实上,它的内部细节相当复杂,如下图所示,Kafka 节点涉及 Topic、Partition 两个重要概念。

b2e28f8f0c439d4456196e9eff28200c.png

kafka总体架构

6823a7aabedbdf620c32ffbdacb50826.png

Broker:Kafka的broker是无状态的,broker使用Zookeeper维护集群的状态。Leader的选举也由Zookeeper负责。

Zookeeper:Zookeeper负责维护和协调broker。当Kafka系统中新增了broker或者某个broker发生故障失效时,由ZooKeeper通知生产者和消费者。生产者和消费者依据Zookeeper的broker状态信息与broker协调数据的发布和订阅任务。

Producer:生产者将数据推送到broker上,当集群中出现新的broker时,所有的生产者将会搜寻到这个新的broker,并自动将数据发送到这个broker上。

Consumer:因为Kafka的broker是无状态的,所以consumer必须使用partition offset来记录消费了多少数据。如果一个consumer指定了一个topic的offset,意味着该consumer已经消费了该offset之前的所有数据。consumer可以通过指定offset,从topic的指定位置开始消费数据。consumer的offset存储在Zookeeper中。

e39d461089a33ecb5f0ec8b32a346b35.png

Kafka 基础架构

03 Kafka环境搭建及相关命令

  • 安装zookeeper
  • 下载代码并解压

> tar -xzf kafka_2.11-1.0.0.tgz

> cd kafka_2.11-1.0.0

  • 启动服务器zk和kafka

>bin/zookeeper-server-start.sh config/zookeeper.properties

>bin/kafka-server-start.sh config/server.properties

  • 创建一个 topic 名为“test”的topic

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

  • 发送一些消息

Kafka自带一个命令行客户端,运行 producer,然后在控制台输入一些消息以发送到服务器。

> bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test

这是一条kafka测试消息

  • 启动一个 consumer

命令行consumer(消费者),将消息转储到标准输出。

>bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test

这是一条kafka测试消息

  • 列出所有Topic

bin/kafka-topics.sh --list --zookeeper 10.0.178.247:2181/kafka_test

  • 查看topic详情

bin/kafka-topics.sh --describe --zookeeper 10.0.178.247:2181/kafka_test --topic test_lyb

04 Java kafka实例

java客户端使用

生产者创建

Properties kafkaProperties = new Properties();

kafkaProperties.put("bootstrap.servers", "host1:9092,host2:9092,host3:9093");

kafkaProperties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");

kafkaProperties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

KafkaProducer kafkaProducer = new KafkaProducer<>(kafkaProperties);

消息发送 发送消息一共分为三种模式

  • 发送即忘记
  • 同步发送
  • 异步发送

同步即忘记

/**

* 发送消息并忘记,虽然会进行重试,但是还是会丢失数据而客户端并不知道

*/

@Test

public void sendMessageAndForget() {

ProducerRecord producerRecord = new ProducerRecord<>(TOPIC_TEST, "test_message", "this test message");

kafkaProducer.send(producerRecord);

}

同步发送

/**

* 同步发送消息,通过send方法获取到future,当发送失败后,get()方法会返回异常

* @throws ExecutionException

* @throws InterruptedException

*/

@Test

public void sendMessageWithSync() throws ExecutionException, InterruptedException {

ProducerRecord producerRecord = new ProducerRecord<>(TOPIC_TEST, "test_message", "this test message");

Future future = kafkaProducer.send(producerRecord);

RecordMetadata recordMetadata = future.get();

System.out.println("record offset:" + recordMetadata.offset());

}

异步发送

/**

* 异步发送消息,通过在send方法中,增加一个回调函数,能够知道发送结果

* @throws InterruptedException

*/

@Test

public void sendMessageWithAsync() throws InterruptedException {

ProducerRecord producerRecord = new ProducerRecord<>(TOPIC_TEST, "test_message", "this test message");

kafkaProducer.send(producerRecord, new Callback() {

@Overridepublic void onCompletion(RecordMetadata metadata, Exception exception) {

System.out.println(metadata.offset());

}

});

TimeUnit.SECONDS.sleep(3);

}

05 几种信息系统比较(ActiveMQ、Kafka、RabbitMQ)

e4b434eb7c1bbd5397620f5d70085b2f.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值