Kafka介绍
Kafka 比较重要的几个概念:
- Producer(生产者) : 产生消息的一方。
- Consumer(消费者) : 消费消息的一方。
- Broker(代理) : 可以看作是一个独立的 Kafka 实例。多个 Kafka Broker 组成一个 Kafka Cluster。每个 Broker 中又包含了 Topic 以及 Partition
- Topic(主题) : Producer 将消息发送到特定的主题,Consumer 通过订阅特定的 Topic(主题) 来消费消息。
- Partition(分区) : Partition 属于 Topic 的一部分。一个 Topic 可以有多个 Partition ,并且同一 Topic 下的 Partition 可以分布在不同的 Broker 上,这也就表明一个 Topic 可以横跨多个 Broker
Kafka 如何保证消息不丢失
生产者丢失消息的情况
生产者(Producer) 调用send方法发送消息之后,消息可能因为网络问题并没有发送过去
最佳实践
- 使用 producer.send(msg, callback)。带有回调通知的 send 方法可以针对发送失败的消息进行重试处理
- 设置 acks = all,如果设置成 all,则表明所有副本 Broker 都要接收到消息,该消息才算是“已提交”
- 设置 retries = 3,当出现网络的瞬时抖动时,消息发送可能会失败,此时配置了 retries > 0 的 Producer 能够自动重试消息发送,避免消息丢失
- 设置 retry.backoff.ms = 300,合理估算重试的时间间隔,可以避免无效的频繁重试
消费者丢失消息的情况
- 处理消息异常导致失败,并且提交了偏移量
最佳实践
- 确保消息消费完成再提交,设置成 enable.auto.commit = false,并采用手动提交位移的方式
Kafka 如何保证消息不重复消费
kafka出现消息重复消费的原因
- 服务端侧已经消费的数据没有成功提交 offset
- Kafka 侧 由于服务端处理业务时间长或者网络链接等等原因让 Kafka 认为服务假死,触发了分区 rebalance
最佳实践
- 消费消息服务做幂等校验
Kafka消费组
为了提升Kafka消费者服务的性能,需要为Topic多分几个分区,然后使用消费者组(Consumer Group)去消费者topic
如何合理设置消费者数量
- 消费者数量太少,会导致一个消费者需要消费多个分区的数据,造成某一个消费者消费压力提升;
- 消费者数量太多,会导致有的消费者并不会消费任何数据,浪费部署资源
- 消费者组里的消费者数量与topic的分片数一致,这样可以保证每个消费者消费1个分区,达到最大效率协调
如何保证分区写入顺序
由于业务明确要求确保顺序消费,而kafka只是保证分片内的消费顺序是固定的,但是不同分片之间的消费顺序是无法保证的。
生产者写入消息到kafka的topic时,kafka将依据不同的策略将数据分配到不同的分区中:
- 轮询分区策略
- 随机分区策略
- 按key分区分配策略
- 自定义分区策略
业务场景:消费论坛帖子评论
采用自定义分区策略,因为每个评论操作请求中都携带有一个原始帖子ID字段,所以分发策略也很简单,直接帖子ID % 分片数将消息进行分发,这样同一个帖子ID的评论操作就都可以到同一个分片中,这样顺序的问题就解决了。