平台人生
作者平台人生·2018-11-23 15:43
软件开发工程师·平台人生

发布-订阅消息系统——Kafka

字数 3457阅读 5602评论 1赞 5

今天给大家介绍一个强大的开源流处理平台——Kafka


Kafka是什么?

Apache Kafka是一个分布式发布-订阅(Pub-Sub)消息系统和一个强大的队列,可以处理大量的数据,能够将消息从一个端点传递到另一个端点。它的消息保留在磁盘上,并会在群集内复制以防止数据丢失。
此外,Kafka需要构建在ZooKeeper的同步服务之上,因为Kafka通过Zookeeper管理集群配置,进行选举leader等活动。

Kafka有什么特性?

可靠性:Kafka的数据分布在整个系统里,具备数据的故障保护能力。
可扩展性:Kafka消息传递系统可以轻松缩放,无需停机。
持久性:Kafka的数据是按照一定顺序持久化保存的,可以按需读取。
高性能: Kafka具有高吞吐量、低延迟的特性,可轻松处理巨大的消息流,同时保证亚秒级的消息延迟。
高并发:支持数千个客户端同时读写。

这些特性使得Kafka的应用场景极为广泛,不仅限于传递消息,还有跟踪用户活动、收集度量指标和日志记录、流处理等诸多场景。

Kafka基本概念

9ldwolx3jtag

9ldwolx3jtag

在了解Kafka的架构之前,需要知道一些基本的概念。相信大家对生产者-消费者模型都有所了解,在Kafka中,生产者(Producer)是指向Kafka服务器发布消息的应用程序,这里的每个Kafka服务器节点称为一个Broker,它主要用来接收生产者发送的消息并将这些消息路由给服务器中的队列。而与相对应的消费者(Consumer)就是从消息队列中请求消息的客户端应用程序。
00s1b8hpjwszjf
00s1b8hpjwszjf

Kafka集群中的消息,是通过主题(Topic)来进行组织的,所谓主题可以理解为一类消息的标签,就像新闻中的体育、娱乐、教育等分类概念。而一个主题中的消息数据可以被分为若干个分区(Partition),消息以追加的方式写入分区,并以先进先出的顺序读取。此外,为了保证分布式可靠性,Kafka会在不同的Broker上对每个分区的数据进行备份(Replication),防止其中一个Broker宕机造成分区上的数据不可用。
i6p1h5gfpawm
i6p1h5gfpawm

我们需要知道,Kafka分区是提高Kafka性能的关键所在,当发现集群性能不高时,常用手段就是增加Topic的分区,分区数越多,吞吐量也越大,当然,需要的资源也越多。


接下来,我们分别细说一下Kafka生产者和消费者是怎么具体运作的。

Kafka生产者

Kafka在接收到生产者发送的消息之后,会根据一定的策略将消息存储到不同的分区中。
wtbz3b44vevp

wtbz3b44vevp

从创建一个包含目标主题和要发送的内容的ProducerRecord对象开始,可以同时指定键或分区。在发送之前,生产者要先把键和值对象序列化成字节数组以便在网络上传输。
接下来,数据被传给分区器,如果在ProducerRecord中指定了分区,那么分区器不会再做任何事情,直接向指定主题与分区写入。若没有指定分区,分区器会根据键Key来选择一个分区。或者二者都没指定,则根据默认的均衡策略向Partition循环写入。当Producer发送消息时,它可以选择一次发送一条数据(同步),也可以选择将一定量的数据按主题和分区放在不同批次中缓存,然后再批量发送(异步)。
服务器在收到这些消息时会返回一个响应,如果成功就返回一个元数据对象,包含了主题、分区和偏移量等信息。如果写入失败,则会返回一个错误并尝试重发,如果超过设定尝试次数,就返回错误信息。

Kafka消费者

在实际应用中,Kafka消费者经常会做一些高延迟的操作,此时生产者的写入速度往往会大于消费者读取处理的速度,如果只使用单个消费者处理信息,应用程序将永远跟不上消息生成的速度。这时就很有必要对消费者进行横向伸缩,以提高消费者读取能力和处理能力。
vgj4267v0f1a

vgj4267v0f1a

eg6y606nakt1
eg6y606nakt1

Kafka消费者从属于消费者群组,一个群组里的消费者订阅的是同一主题,每个消费者接收主题一部分分区的消息,且群组之间互不影响。往群组里增加消费者是横向伸缩消费能力的主要方式。从图中可以看出,可以通过增加消费者来分担负载,而每个应用程序(消费者群组)都可以获取到订阅主题的全部消息。

Kafka整体架构

fwonajihx956

fwonajihx956

最后来看一张Kafka整体工作架构图,从生产者push消息,到Broker存储传递,最后生产者从中pull自己订阅的消息,再结合上Zookeeper的同步协调服务。通过上面的介绍,应该很容易就能看懂Kafka是怎么工作了吧?


下面介绍Kafka分区管理中的两个重要功能,leader 平衡以及分区副本重分配。

Kafka分区副本与leader平衡

首先在一个3节点的Kafka集群中创建一个分区数为3,副本数为3的Topic,查看集群中topic信息如下:
njalzdlylzdi

njalzdlylzdi

集群中使用多个分区副本可以提高可靠性,而多个副本中会有主从之分,称为主副本/跟随者副本(leader/follower)。其中leader负责处理消息读写请求,而follower只负责从leader备份消息。此外,leader同时负责维护Isr(In-sync replica) 列表,当发生leader选举时,只有Isr中副本能参与选举。
Isr(In-sync replica): leader中记录的与其保持同步的副本(Replicas)列表。当follower副本消息落后太多,或超过一定时间未发起备份请求,则leader会将其从Isr中移除。
zy55dvln5mjb
zy55dvln5mjb

创建topic时,Kafka将副本清单里的第一个同步副本选为leader,也就是上图Replicas中的第一列。各分区副本中的leader会以默认的均衡策略进行分配,但在集群或分区状态改变的时候,很有可能会导致集群leader分配不均衡。这时就需要通过触发leader选举,使leader平衡。

Kafka集群分区副本重分配(迁移)

在某些时候,可能要调整分区的副本。如新加入的broker需要获得负载,broker离线造成分区不同步,都会使得主题分区在整个集群里分布不均,造成集群负载的不均衡。
这时候需要使用到kafka-reassign-partitions.sh工具来对分区副本进行重分配并执行迁移。具体步骤如下:
由broker和topic清单生成一组重分配计划
1.在bin/topics-to-move.json中写JSON文件(要重分配的topic列表)
kamynteeoo7u

kamynteeoo7u

2.使用-generate生成重分配计划(将topic:test5重分配到broker0,1,2,3)
bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --topics-to-move-json-file topics-to-move.json --broker-list“0,1,2,3” --generate
3.标准控制台上会输出两个JSON对象,分别描述当前分区分配情况以及建议的分区分配方案。将其中的Proposed partition reassignment configuration内容写到bin/expand-cluster-reassignment.json文件中。
r1ep86i4znzq
r1ep86i4znzq

根据计划执行重新分配分区
4.使用-execute执行计划
bin/kafka-reassign-partitions.sh--zookeeper localhost:2181 –reassignment-json-file expand-cluster-reassignment.json --execute
验证分区重分配的进度和完成情况
5.使用-verify验证是否完成
bin/kafka-reassign-partitions.sh--zookeeper localhost:2181 –reassignment-json-file expand-cluster-reassignment.json --verify
y2ufo0jyixx7
y2ufo0jyixx7

最后,我们来看一下重分配的迁移结果:
meh2a74t7w0u
meh2a74t7w0u

可以看到,Broker从3个扩容为4个后的分区副本重分配结果,分区0和1已经迁移完成,而分区2还正在执行中。当然,我们也可以不使用Kafka提供的重分配计划,而根据实际情况以自己写JSON文件进行分配。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

5

添加新评论1 条评论

wuwenpinwuwenpin软件开发工程师南京
2018-11-24 20:32
不错,值得学习!!
Ctrl+Enter 发表

本文隶属于专栏

作者其他文章

相关文章

相关问题

相关资料

X社区推广