Kafka中所有消息是通过Topic为单位进行管理,每个Kafka中的Topic通常会有多个订阅者,负责订阅发送到改Topic中的数据。Kafka负责管理集群中每个Topic的一组日志分区数据。
生产者将数据发布到相应的Topic。负责选择将哪个记录分发送到Topic中的哪个Partition。例如可以round-robin方式完成此操作,然而这种仅是为了平衡负载。也可以根据某些语义分区功能(例如基于记录中的Key)进行此操作。
每组日志分区是一个有序的不可变的的日志序列,分区中的每一个Record都被分配了唯一的序列编号称为是offset,Kafka 集群会持久化所有发布到Topic中的Record信息,改Record的持久化时间是通过配置文件指定,默认是168小时。
log.retention.hours=168
Kafka底层会定期的检查日志文件,然后将过期的数据从log中移除,由于Kafka使用硬盘存储日志文件,因此使用Kafka长时间缓存一些日志文件是不存在问题的
record是以一种方式(轮询或者hash)进入topic的 无法保证分区与分区之间的顺序的,只能保证分区内部的写入顺序是按照先后顺序
若想保证分区是按照先进先出的顺序,就可以设置topic不分区,就可以保证顺序分
数据在topic 分区partion中唯一的标识offiset 表示在分区中partion 先后顺序,offiset越小,进入kafka越早,但是无法得知分区之间的顺序的
分区内有序
那么为什么要设置分区呢?
带有分区存储可以打破单机数据存储的容量
可以存储海量的数据
分区数越大,单个topic存储能力越强,因为每一个kafka的分区,都会有一个服务器负责去存储该分区里的数据,每个服务器都会有一个leader担当这个分区的读和写,
因此,分区数越大,kafka所能够处理的写入越大,对于kafka而言,分区数可以从某种程度上提升kafka消息队列的写入性能。
多个消费者可以订阅同一个主题内的partion,recorde数据可以被多个消费之消费,他们之间彼此独立,互不影响,消费者消费完record后,会向kafka提交自己的偏移量offset,
kafka提交的偏移量是下一次读取的偏移量,
在消费者消费Topic中数据的时候,每个消费者会维护本次消费对应分区的偏移量,消费者会在消费完一个批次的数据之后,会将本次消费的偏移量提交给Kafka集群,
因此对于每个消费者而言可以随意的控制改消费者的偏移量。因此在Kafka中,消费者可以从一个topic分区中的任意位置读取队列数据,
由于每个消费者控制了自己的消费的偏移量,因此多个消费者之间彼此相互独立。
Kafka中对Topic实现日志分区的有以下目的:
- 首先,它们允许日志扩展到超出单个服务器所能容纳的大小。每个单独的分区都必须适合托管它的服务器,但是一个Topic可能有很多分区,因此它可以处理任意数量的数据。
- 其次每个服务器充当其某些分区的Leader,也可能充当其他分区的Follwer,因此群集中的负载得到了很好的平衡。