一:主题Topic
主题(Topic)是kafka消息的逻辑划分,可以理解为是一个类别的名称;
kafka通过topic将消息进行分类,不同的topic会被订阅该topic的消费者消费。
当这个topic中的消息非常非常多,多到需要几T来存,因为消息是会被保存到log日志文件中的,这无疑是会出现一些问题。
为了解决这个文件过大的问题,kafka提出了Partition分区的概念
二:分区Partition
2.1 概念说明
图例说明:
- 这个是对topic进行了划分,划分了三个分区(Partition),进行分区存储
- 分区的作用是:分段存储kafka中的消息
- 优点:生产者可以并行的写;提高系统读和写(生产和消费)的吞吐量;可以分布式存储
2.2 创建分区命令
./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 2 --topic 主题名称
2.3 查看分区信息
./kafka-topics.sh --describe --zookeeper localhost:2181 --topic 主题名称
2.4 实践
# 创建
[root@localhost bin]# ./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 2 --topic test1
Created topic test1.
# 查看
[root@localhost bin]# ./kafka-topics.sh --describe --zookeeper localhost:2181 --topic test1
Topic: test1 PartitionCount: 2 ReplicationFactor: 1 Configs:
Topic: test1 Partition: 0 Leader: 0 Replicas: 0 Isr: 0
Topic: test1 Partition: 1 Leader: 0 Replicas: 0 Isr: 0
[root@localhost bin]#
2.5 查看日志文件
[root@localhost bin]# cd /root/kafka/data/kafka-logs/
[root@localhost kafka-logs]# ll
总用量 16
...
drwxr-xr-x. 2 root root 141 1月 21 15:34 test1-0
drwxr-xr-x. 2 root root 141 1月 21 15:34 test1-1
drwxr-xr-x. 2 root root 141 1月 20 20:11 userlog-0
[root@localhost kafka-logs]#
[root@localhost kafka-logs]# cd test1-0
[root@localhost test1-0]# ll
总用量 4
-rw-r--r--. 1 root root 10485760 1月 21 15:34 00000000000000000000.index
-rw-r--r--. 1 root root 0 1月 21 15:34 00000000000000000000.log
-rw-r--r--. 1 root root 10485756 1月 21 15:34 00000000000000000000.timeindex
-rw-r--r--. 1 root root 8 1月 21 15:34 leader-epoch-checkpoint
[root@localhost test1-0]# ll ../test1-1
总用量 4
-rw-r--r--. 1 root root 10485760 1月 21 15:34 00000000000000000000.index
-rw-r--r--. 1 root root 0 1月 21 15:34 00000000000000000000.log
-rw-r--r--. 1 root root 10485756 1月 21 15:34 00000000000000000000.timeindex
-rw-r--r--. 1 root root 8 1月 21 15:34 leader-epoch-checkpoint
[root@localhost test1-0]#
在上面的文件中,有index和log两个文件,这两个文件的作用如下:
比如:文件里有一千万条数据,我需要去找到最近24小时的发的消息
- 后缀index文件里面保存的是:如第一条的消息的位置是哪一个索引,第1000条的消息的位置是哪一个索引。。。。通过这种区间索引创建出一个稀疏索引的效果,可以快速的定位到消息的位置
- 后缀timeindex文件是带时间的:例如24小时某个时间点上的索引位置是在那一条
2.6 日志保存的内容细节说明
数据实际上是存储在data/kafka-logs/test-0和test-1中的000…000.log文件中
- 000…000.log:保存消息
- consumerGroupld-topict分区号:
kafka内部自己创建了_consumer_offsets主题包含了50个分区。这个主题用来存放消费者消费某个主题的偏移量。
- 提交到哪个分区︰通过hash函数: hash(consumerGroupld) %_consumer_offsets主题的分区数
- 提交到该主题中的内容是: key是consumerGroupld+topic+分区号,value就是当前offset的值
- 文件中保存的消息,默认保存7天。七天到后消息会被删除。
定期将自己消费分区的offset提交给kafka内部topic:__consumer_offsets,提交过去的时候,key是consumerGroupld-topict分区号,value就是当前offset的值,kafka会定期清理topic里的消息,最后就保留最新的那条数据
当一个消费者挂掉后,该消费者消费的信息会存放到__consumer_offsets-分区号中,在另一个同样的消费者组中的消费者会再去消费这个生产者生产的消息,此时便会从这个分区中获取挂掉的消费者消费的位置
因为_consumer_offsets可能会接收高并发的请求,kafka默认给其分配50个分区(可以通过offsets.topic.num.partitions设置),这样可以通过加机器的方式抗大并发。
通过如下公式可以选出consumer消费的offset要提交到_consumer_offsets的哪个分区公式: hash(consumerGroupld) % ** _consumer_offsets主题的分区数**