秃头系列-kafka基础概念

116 阅读5分钟

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战

前言

  • 关于作者:励志不秃头的一个CURD的Java农民工
  • 关于文章:本篇文章说说kafka的一些基础概念,对kafka形成一定的认识

基本概念

Kafka是一个分布式流处理平台,使用的是拉模式,由客户端主动拉取消息特性:

  • 提供发布订阅及Topic支持
  • 吞吐量高但不保证消息有序
名称解释
Broker消息中间件处理节点,一个Kafka节点就是一个broker,一个或者多个Broker可以组成一个Kafka集群
TopicKafka根据topic对消息进行归类,发布到Kafka集群的每条消息都需要指定一个topic
Partition物理上的概念,一个topic可以分为多个partition(topic分区),每个partition内部消息是有序的
Producer消息生产者,向Broker发送消息的客户端
Consumer消息消费者,从Broker读取消息的客户端
ConsumerGroup每个Consumer属于一个特定的ConsumerGroup,一条消息可以被多个不同的Consumer Group消费,但是一个Consumer Group中只能有一个Consumer能够消费该消息

服务端(brokers)和客户端(producer、consumer)之间通信通过TCP协议来完成。

消息发送

当Producer发布一个消息到某个指定的topic,这个topic不存在,则自动创建

  • num.partitions:创建topic默认分区数,默认为1
  • default.replication.factor:默认副本数量,默认为1,建议设置为大于等于2

Kafka对于消息的发送,是支持同步和异步的;同步阻塞等待,异步不需要等待阻塞。
从本质上来说,kafka都是采用异步的方式来发送消息到broker,但是kafka并不是每次发送消息都会直接发送到broker上,而是把消息放到了一个发送队列中,然后通过一个后台线程不断从队列取出消息进行发送,发送成功后会触发callback。kafka客户端会积累一定量的消息统一组装成一个批量消息发送出去,触发条件是batch.size和linger.ms

而同步发送的方法,无非就是通过future.get()来等待消息的发送返回结果,但是这种方法会严重影响消息发送的性能。

//同步发送(异步阻塞发送)
Future<RecoreMetadata> send = producer.send(record);
RecoreMetadata recordMetadata = send.get();

batch.size

生产者发送多个消息到broker上的同一个分区时,为了减少网络请求带来的性能开销,通过批量的方式来提交消息,可以通过这个参数来控制批量提交的字节数大小,默认大小是16384byte,也就是16kb,意味着当一批消息大小达到指定的batch.size的时候会统一发送

linger.ms

Producer默认会把两次发送时间间隔内收集到的所有Requests进行一次聚合然后再发送,以此提高吞吐量,而linger.ms就是为每次发送到broker的请求增加一些delay,以此来聚合更多的Message请求

batch.size和linger.ms这两个参数是kafka性能优化的关键参数,很多同学会发现batch.size和linger.ms这两者的作用是一样的,如果两个都配置了,那么怎么工作的呢?实际上,当二者都配置的时候,只要满足其中一个要求,就会发送请求到broker上

Metadata

kafka集群的metadata包括:

  • 所有broker的信息: ip和port;
  • 所有topic的信息: topic name, partition数量, 每个partition的leader, isr, replica集合等

kafka集群的每一台broker都缓存了整个集群的metadata, 当broker或某一个topic的metadata信息发生变化时, 集群的Controller都会感知到作相应的状态转换, 同时把发生变化的新的metadata信息广播到所有的broker;

基本上就是metadata的获取,定时刷新以及引用的操作, 比如说partition leader的迁移, partition个数的变化, broker的上下线等等;

消息消费

关键参数

  • group.id
    • 消费组的公共UD
  • enable.auto.commit
    • 消费者消费消息以后自动提交,只有当消息提交以后,该消息才不会被再次接收到,还可以配合auto.commit.interval.ms控制自动提交的频率。
    • 也可以通过consumer.commitSync()的方式实现手动提交
  • auto.offset.reset
    • 针对新的groupid中的消费者而言的,当有新groupid的消费者来消费指定的topic时,对于该参数的配置,会有不同的语义:
      • auto.offset.reset=latest情况下,新的消费者将会从其他消费者最后消费的offset处开始消费Topic下的消息
      • auto.offset.reset= earliest情况下,新的消费者会从该topic最早的消息开始消费
      • auto.offset.reset=none情况下,新的消费者加入以后,由于之前不存在offset,则会直接抛出异常
  • max.poll.records 此设置限制每次调用poll返回的消息数,这样可以更容易的预测每次poll间隔要处理的最大值。通过调整此值,可以减少poll间隔

单播消费

一条消息只能被某一个消费者消费的模式,类似queue模式,只需让所有消费者在同一个消费组里即可分别在两个客户端执行如下消费命令,然后往主题里发送消息,结果只有一个客户端能收到消息

多播消费

一条消息能被多个消费者消费的模式,类似publish-subscribe模式费,针对Kafka同一条消息只能被同一个消费组下的某一个消费者消费的特性,要实现多播只要保证这些消费者属于不同的消费组即可

好了,以上就是Kafka的基础概念,下一篇文章讲讲kafka的核心概念,这样,就对kafka有一个系统的认识了。我是新生代农民工L_Denny,我们下篇文章见。未待续。。。。。。