Kafka入门

目录

1. 什么是Kafka

2. Kafka使用场景

2.1. 用作消息队列

2.2. 作为ELK日志的数据源

3. 核心概念

3.1. Broker

3.2. partition

3.3. offset

3.4. Consumer Group

4. 消息积压

5. 消息重试

5.1. 生产者重试策略

5.2. 消费者重试策略

6. Rebalance

6.1. 概念

6.2. 分区分配策略

6.3. 影响

7. 分区分配策略

7.1. 生产者分区分配策略

7.2. 消费者分区分配策略

8. 消息消费顺序

9. 消息可靠性

9.1. 发送方可靠性

9.2. 消费者可靠性

9.3. broker导致的丢失

10. 延迟队列

11. Zookeeper的作用

11.1. Broker 注册

11.2.  Topic 注册

11.3. 负载均衡


1. 什么是Kafka

Kafka是LinkedIn自研的消息传递系统,起初是用于解决其内部数据管道问题,后来因为高吞吐、可扩展、社区成熟度高等特点成为业内主流的分布式消息队列。

2. Kafka使用场景

Kafka可用于消息队列、日志收集与传输、流数据处理等。下面列举自己工作中使用过的2种场景:用作消息队列和日志收集。

2.1. 用作消息队列

业务场景:业务服务和大数据服务通过Kafka解耦,大数据服务将数据投递到Kafka,业务服务订阅消费。

2.2. 作为ELK日志的数据源

业务场景:为缓解ElasticSearch服务端的压力,用Kafka做数据分流,将采集的业务应用日志存储到kafka,然后LogStash消费Kafka中存储的消息数据,并将消费后的数据写入到ElasticSearch进行存储,最后我们就可以通过Kibana来查询、分析日志了。

3. 核心概念

3.1. Broker

即Kafka的服务器

3.2. partition

每个partition是1个log文件,发布到此partition的消息都会被直接追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量)。

log文件根据broker中的配置要求,保留一定时间后(默认7天)删除来释放磁盘空间。

Partition索引:每隔一定字节的数据建立一条索引。

3.3. offset

即消费者偏移量,kafka会自行创建_consumer_offsets的topic用于保存consumer提交的位移。

3.4. Consumer Group

 即消费者分组,一个partition中的消息只会被同一group中的一个consumer消费,但可以被不同组的consumer消费。每个group中consumer消息消费互相独立。

4. 消息积压

常见原因

解决方法

consumer挂掉、消费者"消费能力"不足

扩容consumer,增加消费能力,从而处理积压数据

分区数设置太少

如果当前partition<consumer可以合理的增加分区

消息发到partition不均匀,导致发生数据倾斜

配置合适的消费者分区分配策略,比如roundrobin,让消息分配均匀

5. 消息重试

5.1. 生产者重试策略

在Spring中默认重试策略为:重试次数为0,重试间隔为100ms。可以在yml中配置,支持的属性可以查看ProducerConfig类。

5.2. 消费者重试策略

在Spring中默认重试策略为:消费逻辑抛出异常时,会快速重试10次,重试间隔100ms,如果重试完成后依旧消费失败会commit这条记录。有2种方案配置重试策略:

方案一:

全局配置重试策略RetryTopicConfiguration对所有消费者生效,或者单独在方法上使用@RetryableTopic对单个消费者生效。自动生成retry topic和dlt topic。

方案二(推荐,比较简单):

全局配置SeekToCurrentErrorHandler。

6. Rebalance

6.1. 概念

消费组里的消费者数量有变化或消费的分区数有变化,kafka会重新分配消费者消费分区的关系。

6.2. 分区分配策略

就是将topic的partition分配给consumer的方式,包含:range(范围分配,默认策略)、round-robin(轮询)、sticky(粘性)。

6.3. 影响

在重平衡过程中,所有的消费者实例均不能消费任何消息。

7. 分区分配策略

7.1. 生产者分区分配策略

》如果指定了分区则发到指定分区

》如果没指定分区且消息key不为空,则基于key的哈希值来选择一个分区

》如果没指定分区且消息key为空,则用轮询的方式选择一个分区

源码实现:org.apache.kafka.clients.producer.internals.DefaultPartitioner

7.2. 消费者分区分配策略

》range(默认):实现类org.apache.kafka.clients.consumer.RangeAssignor,先看分区能不能均分,能均分就1人1个,不能的话,字典顺序排序前面的消费者多负责1个分区,比如consumer1,consumer2,partition0,partition1,partition2,不能均分,则consumer1负责p0,p1,consumer2负责p2。

》roundrobin:实现类org.apache.kafka.clients.consumer.RoundRobinAssignor将partition轮着分给consumer。

 

8. 消息消费顺序

保证消息消费顺序的方式:

方式1:发送消息的时候指定partition

方式2:业务自己写逻辑保证

比如根据消息的updateTime判断消息先后顺序

9. 消息可靠性

9.1. 发送方可靠性

发送时由于网络原因消息没有发送出去,可设置Producer的重试次数和重试间隔尽可能保证消息发送可靠性。

9.2. 消费者可靠性

默认是自动提交offset,如果消费者刚拿到这个消息还未开始处理业务逻辑机器挂了,此时offset已被自动提交,就会导致消息没消费到。可开启手动提交,注意消费逻辑做好幂等。使用自动还是手动要根据业务场景决定。

9.3. broker导致的丢失

一般情况下,kafka多副本机制保证了可靠性,但某些极端情况下仍可能出现消息丢失,比如:leader 所在的 broker 突然挂掉,就要从 follower 副本重新选出一个 leader ,但是 leader 的数据还有一些没有被 follower 副本的同步的话,就会造成消息丢失。可通过设置参数尽可能降低了消息丢失的可能性,比如:设置副本数replication.factor >= 3和min.insync.replicas > 1(代表消息至少要被写入到 2 个副本才算是被成功发送)

10. 延迟队列

Kafka本身并没有提供原生的延迟队列功能,需要自己设计方案处理。

方案一(实现复杂而且时间不准):利用Kafka的时间戳

生产者发送消息时,设置消息的时间戳为当前时间加上延迟时间:

在消费者的消息处理逻辑中,判断消息的时间戳是否已经超过当前时间,如果超过则进行正常的消费处理,否则将消息重新发送到延迟主题,并设置新的延迟时间:

11. Zookeeper的作用

为 Kafka 提供元数据的管理的功能,主要做了以下几点:

11.1. Broker 注册

Broker启动时会将自己的ip、端口等信息注册到zk

11.2.  Topic 注册

Topic和partition信息也会注册到zk

11.3. 负载均衡

当 Consumer 消费的时候,Zookeeper 可以根据当前的 Partition 数量以及 Consumer 数量来实现动态负载均衡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值