Kafka:分布式消息队列

1. 简介

介绍 Kafka 的概述、优势和劣势,以及应用场景。

2. 基本概念

2.1 架构

一个典型的 Kafka 体系架构包括若干 Producer、若干Broker、若干 Consumer,以及一个ZooKeeper集群。

  • ZooKeeper是Kafka用来负责集群元数据的管理、控制器的选举等操作的。Kafka通过ZooKeeper来实施对元数据信息的管理,包括集群、broker、主题、分区等内容。
  • Producer将消息发送到Broker,Broker负责将收到的消息存储到磁盘中。
  • 而Consumer负责从Broker订阅并消费消息。
  • Broker:服务代理节点。对于Kafka而言,Broker可以简单地看作一个独立的Kafka服务节点或Kafka服务实例。大多数情况下也可以将Broker看作一台Kafka服务器,前提是这台服务器上只部署了一个Kafka实例。一个或多个Broker组成了一个Kafka集群。

2.2 Topic和Partition

Kafka中的消息以Topic为单位进行归类,生产者负责将消息发送到特定的Topic(发送到Kafka集群中的每一条消息都要指定一个主题),而消费者负责订阅主题并进行消费。

Topic是一个逻辑上的概念,它还可以细分为多个分区,一个分区只属于单个Topic,很多时候也会把分区称为主题分区(Topic-Partition)。同一Topic下的不同分区包含的消息是不同的,分区在存储层面可以看作一个可追加的日志(Log)文件,消息在被追加到分区日志文件的时候都会分配一个特定的偏移量(offset)。offset是消息在分区中的唯一标识,Kafka通过它来保证消息在分区内的顺序性,不过offset并不跨越分区,也就是说,Kafka保证的是分区有序而不是主题有序

从Kafka的底层实现来说,主题和分区都是逻辑上的概念,分区可以有一至多个副本,每个副本对应一个日志文件,每个日志文件对应一至多个日志分段(LogSegment),每个日志分段还可以细分为索引文件、日志存储文件和快照文件等。

2.3 AR、ISR、OSR

分区中的所有副本统称为AR(Assigned Replicas)。所有与leader副本保持一定程度同步的副本(包括leader副本在内)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。消息会先发送到leader副本,然后follower副本才能从leader副本中拉取消息进行同步,同步期间内follower副本相对于leader副本而言会有一定程度的滞后。前面所说的“一定程度的同步”是指可忍受的滞后范围,这个范围可以通过参数进行配置。与leader副本同步滞后过多的副本(不包括leader副本)组成OSR(Out-of-Sync Replicas),由此可见,AR=ISR+OSR。在正常情况下,所有的 follower 副本都应该与leader 副本保持一定程度的同步,即 AR=ISR,OSR集合为空。

2.4 HW、LEO

HW是High Watermark的缩写,俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。

LEO是Log End Offset的缩写,它标识当前日志文件中下一条待写入消息的offset,LEO的大小相当于当前日志分区中最后一条消息的offset值加1。分区ISR集合中的每个副本都会维护自身的LEO,而ISR集合中最小的LEO即为分区的HW,对消费者而言只能消费HW之前的消息。

2.5 Producer

2.5.1 架构

整个生产者客户端由两个线程协调运行,这两个线程分别为主线程和Sender线程(发送线程)。在主线程中由KafkaProducer创建消息,然后通过可能的拦截器、序列化器和分区器的作用之后缓存到消息累加器(RecordAccumulator,也称为消息收集器)中。Sender 线程负责从RecordAccumulator中获取消息并将其发送到Kafka中。

RecordAccumulator 主要用来缓存消息以便 Sender 线程可以批量发送,进而减少网络传输的资源消耗以提升性能。RecordAccumulator 缓存的大小可以通过生产者客户端参数buffer.memory 配置,默认值为 33554432B,即 32MB。

2.6 Consumer与Group

消费者(Consumer)负责订阅Kafka中的主题(Topic),并且从订阅的主题上拉取消息。与其他一些消息中间件不同的是:在Kafka的消费理念中还有一层消费组(Consumer Group)的概念,每个消费者都有一个对应的消费组。当消息发布到主题后,只会被投递给订阅它的每个消费组中的一个消费者。如果所有的消费者都隶属于不同的消费组,那么所有的消息都会被广播给所有的消费者,即每条消息会被所有的消费者处理,这就相当于发布/订阅模式的应用。

3. 实践应用

3.1 普通消息

3.1.1 创建Topic

如果broker端配置参数auto.create.topics.enable设置为true(默认值就是true),那么当生产者向一个尚未创建的主题发送消息时,会自动创建一个分区数为num.partitions (默认值为1)、副本因子为default.replication.factor(默认值为1)的主题。

3.1.2 修改Topic

目前Kafka只支持增加分区数而不支持减少分区数。按照Kafka现有的代码逻辑,此功能完全可以实现,不过也会使代码的复杂度急剧增大。

3.2 顺序消息

3.3 延迟消息

3.4 广播消息

3.5 Reblance

Kafka 集群的broker 节点不可避免地会遇到宕机或崩溃的问题,当分区的leader节点发生故障时,其中一个follower节点就会成为新的leader节点,这样就会导致集群的负载不均衡,从而影响整体的健壮性和稳定性。

在 Kafka 中可以提供分区自动平衡的功能,与此对应的 broker 端参数是 auto.leader.rebalance.enable,此参数的默认值为true,即默认情况下此功能是开启的。如果开启分区自动平衡的功能,则 Kafka 的控制器会启动一个定时任务,这个定时任务会轮询所有的 broker节点,计算每个broker节点的分区不平衡率(broker中的不平衡率=非优先副本的leader个数/分区总数)是否超过leader.imbalance.per.broker.percentage参数配置的比值,默认值为 10%,如果超过设定的比值则会自动执行优先副本的选举动作以求分区平衡。执行周期由参数leader.imbalance.check.interval.seconds控制,默认值为300秒,即5分钟。

4. 性能优化

介绍如何优化 Kafka 的性能,例如主题分区配置、消息压缩等。

5. 常见问题解答

解答有关 Kafka 的常见问题。

5.1 kafka参数配置

5.1.1 生产者参数

参数详情
acks

这个参数用来指定分区中必须要有多少个副本收到这条消息,之后生产者才会认为这条消息是成功写入的。acks 是生产者客户端中一个非常重要的参数,它涉及消息的可靠性和吞吐量之间的权衡。acks参数有3种类型的值(都是字符串类型)。

  • acks=1。默认值即为1。生产者发送消息之后,只要分区的leader副本成功写入消息,那么它就会收到来自服务端的成功响应。
  • acks=0。生产者发送消息之后不需要等待任何服务端的响应。
  • acks=-1或acks=all。生产者在消息发送之后,需要等待ISR中的所有副本都成功写入消息之后才能够收到来自服务端的成功响应。
max.request.size这个参数用来限制生产者客户端能发送的消息的最大值,默认值为 1048576B,即 1MB
retries和retry.backoff.ms
  • retries参数用来配置生产者重试的次数,默认值为0,即在发生异常的时候不进行任何重试动作。
  • 重试还和另一个参数retry.backoff.ms有关,这个参数的默认值为100,它用来设定两次重试之间的时间间隔,避免无效的频繁重试。

5.1.2 消费者参数

参数详情
bootstrap.servers该参数的释义和生产者客户端KafkaProducer 中的相同,用来 指 定 连 接 Kafka 集 群 所需 的 broker 地 址 清 单,具 体 内 容 形 式 为host1:port1,host2:post,可以设置一个或多个地址,中间用逗号隔开,此参数的默认值为“”。
group.id消费者隶属的消费组的名称,默认值为“”。如果设置为空,则会报出异常
key.deserializer 和 value.deserializer与生产者客户端KafkaProducer中的key.serializer和value.serializer参数对应。消费者从broker端获取的消息格式都是字节数组(byte[])类型,所以需要执行相应的反序列化操作才能还原成原有的对象格式。这两个参数分别用来指定消息中key和value所需反序列化操作的反序列化器,这两个参数无默认值。
client.id这个参数用来设定KafkaConsumer对应的客户端id,默认值也为“”。如果客户端不设置,则KafkaConsumer会自动生成一个非空字符串。

5.1.3 broker参数

参数详情

5.2 kafka和Rocketmq比较

比较项KafkaRocketMQ
架构自己实现了name server
适用场景适合日志处理适合业务处理
性能单机写入TPS号称在百万条/秒大约在10万条/秒;
可靠性使用异步刷盘方式,异步Replication;支持异步/同步刷盘;异步/同步 Replication;RocketMQ所支持的同步方式提升了数据的可靠性。
实时性均支持pull长轮询RocketMQ消息实时性更好
支持的队列数Kafka单机超过64个队列/分区,消息发送性能降低严重;RocketMQ单机支持最高5万个队列,性能稳定;
消息顺序性Kafka某些配置下,支持消息顺序,但是一台Broker宕机后,就会产生消息乱序RocketMQ支持严格的消息顺序,在顺序消费场景下,一台Broker宕机后,发送消息会失败,但是不会乱序。
消费失败重试机制Kafka消费失败不支持重试RocketMQ消费失败支持定时重试,每次重试间隔时间顺延
定时/延时消息Kafka不支持定时消息;RocketMQ支持定时消息
分布式事务消息Kafka不支持分布式事务消息RocketMQ支持分布式事务消息
消息查询机制Kafka不支持消息查询RocketMQ支持根据Message Id查询消息,也支持根据消息内容查询消息
消息回溯Kafka理论上可以按照Offset来回溯消息RocketMQ支持按照时间来回溯消息,精度毫秒,例如从一天之前的某分某秒开始重新消费消息

6. 总结

总结 Kafka 的关键知识点,并提供学习资源和进一步研究方向。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值