一个典型的 Kafka 体系架构包括若干 Producer、若干 Broker、若干 Consumer,以及一个ZooKeeper集群。其中ZooKeeper是Kafka用来负责集群元数据的管理、控制器的选举等操作的。Producer将消息发送到Broker,Broker负责将收到的消息存储到磁盘中,而Consumer负责从Broker订阅并消费消息。
1、Producer:生产者,发送消息的一方,发送消息到主题的分区中。
2、Consumer:消费者,接收消息的一方,通过订阅主题来消费消息。
3、Broker:服务代理节点。对于Kafka而言,Broker可以简单地看作一个独立的Kafka服务节点或Kafka服务实例。大多数情况下也可以将Broker看作一台Kafka服务器,前提是这台服务器上只部署了一个Kafka实例。
4、Topic:主题,Kafka中的消息以主题为单位进行归类,生产者负责将消息发送到特定的主题(发送到Kafka集群中的每一条消息都要指定一个主题),而消费者负责订阅主题并进行消费。
5、Partition:分区,一个主题可以分为多个分区,而一个分区只属于单个主题。同一主题下不同分区包含的消息是不同的,分区在存储层面(磁盘)可以看做是一个log文件(.log后缀),并且消息是以追加的方式顺序写入log文件,在此过程会给消息分配一个分区内唯一标识偏移量offset,保证消息在分区内的顺序性。但是offset并不跨分区,也就是说只能保证分区内顺序,不能保证主题内顺序。Kafka中的分区可以分布在不同的服务器(broker)上。
kafka为分区引入了多副本(Replica)机制,同一分区的不同副本中保存的是相同的消息(在同一时刻,副本之间并非完全一样),副本之间是“一主多从”的关系,其中leader副本负责处理读写请求,follower副本只负责与leader副本的消息同步。副本处于不同的broker中,避免某个broker挂掉后导致数据丢失(Zookeeper负责leader副本的选举)。
生产者和消费者只与leader副本进行交互,而follower副本只负责消息的同步,很多时候follower副本中的消息相对leader副本而言会有一定的滞后。
分区中的所有副本统称为AR(Assigned Replicas)。所有与leader副本保持一定程度同步的副本(包括leader副本在内)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。消息会先发送到leader副本,然后follower副本才能从leader副本中拉取消息进行同步(follower副本如何知道有新消息?leader副本发通知?),同步期间内follower副本相对于leader副本而言会有一定程度的滞后。前面所说的“一定程度的同步”是指可忍受的滞后范围,这个范围可以通过参数进行配置。与leader副本同步滞后过多的副本(不包括leader副本)组成OSR(Out-of-Sync Replicas),由此可见,AR=ISR+OSR。在正常情况下,所有的 follower 副本都应该与 leader 副本保持一定程度的同步,即 AR=ISR,OSR集合为空。默认情况下,当leader副本发生故障时,只有在ISR集合中的副本才有资格被选举为新的leader。
ISR与HW和LEO也有紧密的关系。HW是High Watermark的缩写,俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。LEO是Log End Offset的缩写,它标识当前日志文件中下一条待写入消息的offset。其中leader副本的LEO变化后,follower副本开始同步,而HW的值是取所有副本的最小值,这样来保证消费者拉取的数据肯定在所有副本中。对于生产者发送一条消息,只有等这条消息在所有副本中同步完成才算是成功,消费者才可以消费到。(对于生产者来说收到消息推送成功的响应时机可以通过acks配置,这个参数用来指定分区中必须要有多少个副本收到这条消息,之后生产者才会认为这条消息是成功写入的)