在Kafka架构,不管是生产者Producer还是消费者Consumer面向的都是Topic。Topic是逻辑上的概念,而Partition是物理上的概念。每个Partition逻辑上对应一个log文件,该log文件存储是Producer生产的数据。Producer生产的数据被不断追加到该log文件末端,且每条数据都有自己的offset。Kafka对于log文件是采取分片和索引机制。
启动kafka集群,集群中有三台Broker; 设置3个分区,3个副本;
bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --create --replication-factor 3 --partitions 3 --topic hy-test-topic
public static void main(String[] args) {
//1.创建kakfa生产者的配置对象
Properties prop = new Properties();
//2.给生产者配置对象添加配置信息
prop.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");
prop.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
prop.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
prop.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);
prop.put(ProducerConfig.LINGER_MS_CONFIG, 1);
prop.put(ProducerConfig.BUFFER_MEMORY_CONFIG,33554432);
//3.创建生产者对象
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(prop);
//4.调用send方法,发送消息
for (int i = 0; i < 5; i++) {
kafkaProducer.send(new ProducerRecord<String,String>("hy-test-topic",Integer.toString(i),Integer.toString(i)));
}
//5.关闭资源
kafkaProducer.close();
}
查看log.dirs
bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --describe --topic hy-test-topic
broker.id=4
中,其余都是副本 Replicas
2,3broker.id=2
中,其余都是副本 Replicas
3,4broker.id=3
中,其余都是副本 Replicas
4,2通过zookeeper查看leader
在那个broker上
[zk: localhost:2181(CONNECTED) 14] get /kafka/brokers/topics/hy-test-topic/partitions/0/state
{"controller_epoch":49,"leader":4,"version":1,"leader_epoch":0,"isr":[4,2,3]}
名称 | 描述 | 类型 | 默认 |
---|---|---|---|
log.segment.bytes | 单个日志文件的最大大小 | int | 1073741824(1G) |
继续发送消息会生成新的segment
可以看出
00000000000000000000.log
快要达到 log.segment.bytes
时,开始创建 00000000000000001187.log
.log
和.index
、.timeindex
文件是一起出现; 并且名称是以文件第一个offset命名的。使用kafka自带工具bin/kafka-run-class.sh
来读取分区下的文件内容
bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files 00000000000000000000.log
最后一行显示的是
baseOffset: 1186 position: 1072277020 CreateTime: 1695792070168
bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files 00000000000000000000.index
offset: 1186 position: 1072277020
/opt/module/kafka/bin/kafka-run-class.sh kafka.tools.DumpLogSegments --files 00000000000000000000.timeindex
借用博主@lizhitao 博客上的一张图来展示是如何查找Message的。
比如:要查找绝对offset为7的Message:
该机制是建立在offset是有序的。索引文件被映射到内存中,所以查找的速度还是很快的。
Kafka的Message存储采用了分区(partition),分段(LogSegment)和稀疏索引来达到了查找的高效性。
参考链接:https://cloud.tencent.com/developer/article/1846773