Kafka的基础回顾

什么是Kafka

Kafka 是一个高吞吐量的、持久性的、分布式发布订阅消息系统

  • 高吞吐量:可以满足每秒百万级别消息的生产和消费。

为什么这么快?

难道Kafka的数据是放在内存里面的吗?

不是的,Kafka的数据还是放在磁盘里面的

主要是Kafka利用了磁盘顺序读写速度超过内存随机读写速度这个特性。

所以说它的吞吐量才这么高

  • 持久性:有一套完善的消息存储机制,确保数据高效安全的持久化。
  • 分布式:它是基于分布式的扩展、和容错机制;Kafka的数据都会复制到几台服务器上。当某一台机器故障失效时,生产者和消费者切换使用其它的机器。

Kafka组件介绍

先看中间的Kafka Cluster

这个Kafka集群内有两个节点,这些节点称之为Broker

Broker:消息的代理,Kafka集群中的一个节点称为一个broker

在Kafka中有Topic的概念

Topic:称为主题,Kafka处理的消息的不同分类(是一个逻辑概念)。

如果把Kafka认为是一个数据库的话,那么Kafka中的Topic就可以认为是一张表

不同的topic中存储不同业务类型的数据,方便使用

在Topic内部有partition的概念

Partition:是Topic物理上的分组,一个Topic会被分为1个或者多个partition(分区),分区个数是在创建topic的时候指定。每个topic都是有分区的,至少1个。

注意:这里面针对partition其实还有副本的概念,主要是为了提供数据的容错性,我们可以在创建Topic的时候指定partition的副本因子是几个。

在这里面副本因子其实就是2了,其中一个是Leader,另一个是真正的副本

Leader中的这个partition负责接收用户的读写请求,副本partition负责从Leader里面的partiton中同步数据,这样的话,如果后期leader对应的节点宕机了,副本可以切换为leader顶上来。

在partition内部还有一个message的概念

Message:称之为消息,代表的就是一条数据,它是通信的基本单位,每个消息都属于一个partition。

小结:Broker>Topic>Partition>Message

接下来还有两个组件,看图中的最左边和最右边

Producer:消息和数据的生产者,向Kafka的topic生产数据。

Consumer:消息和数据的消费者,从kafka的topic中消费数据。

这里的消费者可以有多个,每个消费者可以消费到相同的数据

最后还有一个Zookeeper服务,Kafka的运行是需要依赖于Zookeeper的,Zookeeper负责协调Kafka集群的正常运行。

 

Kafka中的生产者和消费者

Producer:Producer默认是将数据随机发送到指定Topic的分区中的,也可以根据用户设置的算法来根据消息的key来计算输入到哪个partition里面

针对producer的数据通讯方式:同步发送和异步发送

同步是指:生产者发出数据后,等接收方发回响应以后再发送下个数据的通讯方式。

异步是指:生产者发出数据后,不等接收方发回响应,接着发送下个数据的通讯方式。具体的数据通讯策略是由 acks 参数控制的

acks默认为 1 ,表示需要Leader节点回复收到消息,这样生产者才会发送下一条数据

acks:all ,表示需要所有Leader+副本节点回复收到消息(acks=-1),这样生产者才会发送下一条数据

acks:0 ,表示不需要任何节点回复,生产者会继续发送下一条数据

针对这块在面试的时候会有一个面试题:Kafka如何保证数据不丢?

其实就是通过acks机制保证的,如果设置acks为all,则可以保证数据不丢,因为此时把数据发送给kafka之后,会等待对应partition所在的所有leader和副本节点都确认收到消息之后才会认为数据发送成功了,

所以在这种策略下,只要把数据发送给kafka之后就不会丢了。

如果acks设置为1,则当我们把数据发送给partition之后,partition的leader节点也确认收到了,但是leader回复完确认消息之后,leader对应的节点就宕机了,副本partition还没来得及将数据同步过去,所以会存在丢失的可能性。

不过如果宕机的是副本partition所在的节点,则数据是不会丢的。

如果acks设置为0的话就表示是顺其自然了,只管发送,不管kafka有没有收到,这种情况表示对数据丢不丢都无所谓了。

Consumer

在消费者中还有一个消费者组的概念

每个consumer属于一个消费者组,通过group.id指定消费者组

那组内消费和组间消费有什么区别吗?

  • 组内:消费者组内的所有消费者消费同一份数据;

注意:在同一个消费者组中,一个partition同时只能有一个消费者消费数据

如果消费者的个数小于分区的个数,一个消费者会消费多个分区的数据。

如果消费者的个数大于分区的个数,则多余的消费者不消费数据

所以,对于一个topic,同一个消费者组中推荐不能有多于分区个数的消费者,否则将意味着某些消费者将无法获得消息。

  • 组间:多个消费者组消费相同的数据,互不影响。

看下面的图,加深一下理解

 

Kafka存储机制和容错机制

Message

每条Message包含了以下三个属性:

  1. offset 对应类型:long 表示此消息在一个partition中的起始的位置。可以认为offset是partition中Message的id,自增的
  2. MessageSize 对应类型:int32 此消息的字节大小。
  3. data 是message的具体内容。

存储策略

kafak中数据的存储方式是这样的:

  1. 每个partition由多个segment【片段】组成,每个segment中存储多条消息,
  2. 每个partition在内存中对应一个index,记录每个segment中的第一条消息偏移量。

Kafka中数据的存储流程是这样的:

生产者生产的消息会被发送到topic的多个partition上,topic收到消息后往对应partition的最后一个

segment上添加该消息,segment达到一定的大小后会创建新的segment。

来看这个图,可以认为是针对topic中某个partition的描述

图中左侧就是索引,右边是segment文件,左边的索引里面会存储每一个segment文件中第一条消息的偏移量,由于消息的偏移量都是递增

的,这样后期查找起来就方便了,先到索引中判断数据在哪个segment文件中,然后就可以直接定位到具体的segment文件了,这样再找具

体的那一条数据就很快了,因为都是有序的。

 

容错机制

当Kafka集群中的一个Broker节点宕机,会出现什么现象?

在Kafka服务器集群先kill干掉一个broker进程

然后通过zookeeper查看Kafka节点状态

此时发现zookeeper的/brokers/ids下面只有2个节点信息

可以通过get命令查看节点信息,这里面会显示对应的主机名和端口号

然后再使用describe查询topic的详细信息,会发现此时的分区的leader全部变成了目前存活的另外两个节点

此时可以发现Isr(In-Sync Replica)中的内容和Replicas中的不一样了,因为Isr中显示的是目前正常运行的节点

所以当Kafka集群中的一个Broker节点宕机之后,对整个集群而言没有什么特别的大影响,此时集群会给partition重新选出来一些新的Leader节点

当Kafka集群中新增一个Broker节点,会出现什么现象?

新加入一个broker节点,zookeeper会自动识别并在适当的机会选择此节点提供服务

但是启动后有个问题:发现新启动的这个节点不会是任何分区的leader?怎么重新均匀分配呢?

1、Broker中的自动均衡策略(默认已经有)

auto.leader.rebalance.enable 默认值true
leader.imbalance.check.interval.seconds 默认值:300

2、手动执行:

bin/kafka-leader-election.sh --bootstrap-server localhost:9092 --election-type preferred

关于作者

不羁的风
一起哈皮YQHP
获得点赞
文章被阅读