kafka基础之核心概念

来源:互联网 发布:java public class读法 编辑:程序博客网 时间:2024/06/05 13:28

一 Broker(代理)

一台kafka服务器就可以称之为broker.一个集群由多个broker组成,一个broker可以有多个topic

 

二 Topic(主题)

每一条发送到kafka集群的消息都可以有一个类别,这个类别叫做topic,不同的消息会进行分开存储,如果topic很大,可以分布到多个broker上

也可以这样理解:topic被认为是一个队列,每一条消息都必须指定它的topic,可以说我们需要明确把消息放入哪一个队列。

对于传统的message queue而言,一般会删除已经被消费的消息,而Kafka集群会保留所有的消息,无论其被消费与否。当然,因为磁盘限制,不可能永久保留所有数据(实际上也没必要),因此Kafka提供两种策略删除旧数据。一是基于时间,二是基于Partition文件大小。例如可以通过配置$KAFKA_HOME/config/server.properties,让Kafka删除一周前的数据,也可在Partition文件超过1GB时删除旧数据,配置如下所示。

# The minimum age of a log file to be eligible fordeletion

log.retention.hours=168

# The maximum size of a log segment file. When thissize is reached a new log segment will be created.

log.segment.bytes=1073741824

# The interval at which log segments are checked tosee if they can be deleted according to the retention policies

log.retention.check.interval.ms=300000

# If log.cleaner.enable=true is set the cleanerwill be enabled and individual logs can then be marked for log compaction.

log.cleaner.enable=false

三 Partition(分区)

为了使得kafka吞吐量线性提高,物理上把topic分成一个或者多个分区,每一个分区是一个有序的队列。且每一个分区在物理上都对应着一个文件夹,该文件夹下存储这个分区所有消息和索引文件。

分区的表示: topic名字-分区的id

每个日志文件都是一个Log Entry序列,每个Log Entry包含一个4字节整型数值(值为M+5),1个字节的"magic value",4个字节的CRC校验码,然后跟M个字节的消息

 

这个log entries并非由一个文件构成,而是分成多个segment,每个segment以该segment第一条消息的offset命名并以“.kafka”为后缀。另外会有一个索引文件,它标明了每个segment下包含的log entry的offset范围,如下图所示:


分区中每条消息都有一个当前Partition下唯一的64字节的offset,它指明了这条消息的起始位置

Kafka只保证一个分区的数据顺序发送给消费者,而不保证整个topic里多个分区之间的顺序

 

四 Replicas(副本)

试想:一旦某一个Broker宕机,则其上所有的Partition数据都不可被消费,所以需要对分区备份。其中一个宕机后其它Replica必须要能继续服务并且即不能造成数据重复也不能造成数据丢失。

 

如果没有一个Leader,所有Replica都可同时读/写数据,那就需要保证多个Replica之间互相(N×N条通路)同步数据,数据的一致性和有序性非常难保证,大大增加了Replication实现的复杂性,同时也增加了出现异常的几率。而引入Leader后,只有Leader负责数据读写,Follower只向Leader顺序Fetch数据(N条通路),系统更加简单且高效。

 

每一个分区,根据复制因子N,会有N个副本,比如在broker1上有一个topic,分区为topic-1, 复制因子为2,那么在两个broker的数据目录里,就都有一个topic-1,其中一个是leader,一个replicas

 

同一个Partition可能会有多个Replica,而这时需要在这些Replication之间选出一个Leader,Producer和Consumer只与这个Leader交互,其它Replica作为Follower从Leader中复制数据

 

五 AR PR ISR OSR

AR: 就是assigned replicas,指的是根据复制因子所产生的副本数,如果没有设置,默认就一个,也就是说AR是全部的副本数集合或者队列

 

PR: Preferred Replica,即AR中第一个副本,创建一个新的Topic或者给已有Topic增加Partition时,Kafka保证Preferred Replica被均匀分布到集群中的所有Broker上。理想情况下,Preferred Replica会被选为Leader。以上两点保证了所有Partition的Leader被均匀分布到了集群当中,这一点非常重要,因为所有的读写操作都由Leader完成,若Leader分布过于集中,会造成集群负载不均衡

 

ISR:就是in-sync replicas,同步副本队列,我们知道broker上的副本是需要通过zookeeper来实现同步的,它是AR的一个子集,可以等于AR,也可以是AR的一部分,因为AR完全有可能有些副本不存在同步副本队列里。

另外我们需要知道的是leader也是属于ISR的。

而且leader失效,新leader的选举必须是通过ISR里的副本选举出来的。

OSR: 就是out of-sync replicas,leader 会维护一个ISR列表,follower从leader同步数据,同步的时候可能存在延迟,比如:

延迟时间:replica.lag.time.max.ms

如果超过阀值,则会把follower剔除ISR,然后放入到OSR中,而且新加入的follower也会先放在OSR中

 

六 高水位线(HW)&日志结尾位置(LEO)

HW: highwatermark缩写,是指消费者能够看到的这个partition的位置,它是指partition的ISR中所对应的log的LEO(LogEndOffset)中最小的那个值,比如topic-1这个分区,在broker1,broker2,broker3,

其中broker1所对应副本为leader,其余是follower,那么他们都在ISR列表,这三个都有自己对应的日志文件,那么每一个文件都有一个LEO,HW就是指最小的那个LEO

消费者最多只能消费到高水位这个位置的消息;另外,每一个replica都有高水位,leader和follower各自负责更新的高水位状态;对于leader新写入的消息,消费者不能立刻消费,leader会等到该消息被所有ISR中的replicas同步后更新高水位,此消息才能被消费者消费。

 

LEO: LogEnfOffset缩写,表示每一个partition的log最后一条message的offset(偏移量)

灰色代表leader:

蓝色和绿色代表follower:


s



七  broker, topic, partition都会向zookeeper注册,他们在zookeeper的结构表现为:

/brokers/ids:broker的id,我们可以在server.properties配置,每一台机器的这个id必须唯一

/brokers/topics: broker下有哪些topic

[samples, __consumer_offsets]

/brokers/topics/samples/partitions:samples这个主题下有哪些分区

[0, 1, 2]

/brokers/topics/__consumer_offsets/partitions: 新版kafka将消费者的位置信息(offset)保存在kafka内部的topic中,就是这里的__consumer_

Offsets topic,并且提供了kafka-consumer-groups.sh供用户查看消费者信息。那么这个__consumer_offsets保存到底是什么呢?

是默认的50个分区,如果消费者组比50还多的话,可能还会增加

[44, 45, 46, 47, 48, 49, 10, 11, 12, 13, 14, 15,16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 26, 27,28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]

 

计算指定consumer group在__consumer_offsets topic中分区信息

Math.abs(groupID.hashCode()) % numPartitions

查看消费者组:

./kafka-consumer-groups.sh --bootstrap-server192.168.3.101:29092 --list SampleConsumer

SampleConsumer49

SampleConsumer67

Math.abs("SampleConsumer67".hashCode()) %50就得到你这个组的位置信息该属于哪一个分区

 

八  Producer(生产者)

负责发布消息到broker

九 Consumer(消费者) 和Consumer Group消费者组

消费者:负责从broker取数据

消费者组:

同一个topic的消息,可以并行被不同的消费者组消费,但是每一个消费者组内只能有一个消费者来消费这个消息


原创粉丝点击