kafka基本知识
基本概念
消息以主题(Topic)来分类,每一个主题都对应一个「消息队列」
面相消费者和生产者,物理上存储的其实是 Partition,每一个 Partition 最终对应一个目录,里面存储所有的消息和索引文件。
默认情况下,每一个 Topic 在创建时如果不指定 Partition 数量时只会创建 1 个 Partition。比如,我创建了一个 Topic 名字为 test ,没有指定 Partition 的数量,那么会默认创建一个 test-0 的文件夹,这里的命名规则是:
<topic_name>-<partition_id>。任何发布到 Partition 的消息都会被追加到 Partition 数据文件的尾部,这样的顺序写磁盘操作让 Kafka 的效率非常高
具体结构
每个 Partition 都为一个目录,而每一个目录又被平均分配成多个大小相等的 Segment File 中,Segment File 又由 index file 和 data file 组成,他们总是成对出现,后缀 “.index” 和 “.log” 分表表示 Segment 索引文件和数据文件。
1 | |
Segment 是 Kafka 文件存储的最小单位。Segment 文件命名规则:Partition 全局的第一个 Segment 从 0 开始,后续每个 Segment 文件名为上一个 Segment 文件最后一条消息的 offset 值。
Kafka 是如何准确的知道 message 的偏移的呢?这是因为在 Kafka 定义了标准的数据存储结构,在 Partition 中的每一条 message 都包含了以下三个属性:
- offset:表示 message 在当前 Partition 中的偏移量,是一个逻辑上的值,唯一确定了 Partition 中的一条 message,可以简单的认为是一个 id;
- MessageSize:表示 message 内容 data 的大小;
- data:message 的具体内容
消费组
消费组
消费组的概念:在Kafka中,消费组是一组消费者的集合,这些消费者共同订阅一个或多个主题,共享消息的消费。Kafka保证一个分区内的消息只被消费组中的一个消费者处理,这样可以在消费者间实现负载均衡。分区与消费者的关系:每个消费者负责读取指定主题的一个或多个分区中的消息。如果消费者的数量等于分区的数量,那么每个消费者负责读取一个分区的消息。如果消费者数量少于分区数量,某些消费者将负责多个分区。如果消费者数量多于分区数量,将会有一些空闲的消费者。
支持多应用消费
全量消息读取:Kafka允许多个消费组独立地订阅同一个主题。这意味着每个消费组都可以从头到尾读取主题中的所有消息,而不会影响到其他消费组。这个特性对于需要处理相同数据集的不同应用非常重要。消费组与应用的关系:通常,每个独立的应用会有自己的消费组。这样,即使多个应用需要读取并处理同一主题的消息,它们也能保证获取到全量的消息数据。每个消费组的消费进度是独立管理的。
消费顺序
Kafka 中一个 topic 中的消息是被打散分配在多个 Partition(分区) 中存储的, Consumer Group 在消费时需要从不同的 Partition 获取消息,那最终如何重建出 Topic 中消息的顺序呢?
答案是:没有办法。Kafka 只会保证在 Partition 内消息是有序的,而不管全局的情况。
可以指定消息的key,确保相同的key发布到同一个分区
可靠性
- 对于一个分区来说,它的消息是有序的。如果一个生产者向一个分区先写入消息A,然后写入消息B,那么消费者会先读取消息A再读取消息B。
- 当消息写入所有in-sync状态的副本后,消息才会认为已提交(committed)。这里的写入有可能只是写入到文件系统的缓存,不一定刷新到磁盘。生产者可以等待不同时机的确认,比如等待分区主副本写入即返回,后者等待所有in-sync状态副本写入才返回。
- 一旦消息已提交,那么只要有一个副本存活,数据不会丢失。
- 消费者只能读取到已提交的消息
主题的分区数目
当你创建一个Kafka主题时,可以指定分区的数量。分区数量不是随机的,而是由你在创建主题时设置的。分区使得Kafka可以在多个服务器上分布数据和负载,提高吞吐量。
1 | |
Kafka配置文件修改与参数
Kafka的配置主要在其配置文件中设置,例如server.properties。有许多配置参数,比如:
broker.id:唯一标识每个Kafka节点。log.dirs:存储日志文件的位置。zookeeper.connect:Zookeeper的连接信息,Kafka用它来存储集群的状态。
更改配置文件通常是直接编辑文件,然后重启Kafka服务。
消费者读取启动之前的数据
消费者可以读取到启动之前的数据。这取决于消费者的auto.offset.reset配置:
- 设置为
earliest时,消费者将从有效负载的最开始读取数据。 - 设置为
latest时,消费者将从新产生的数据开始读取。
使用Go语言的Sarama库,这可以在消费者配置中设置:
1 | |
事务的默认隔离级别
默认为读未提交
Kafka的事务隔离级别通过isolation.level配置控制,有两个值:
read_uncommitted(默认):消费者可以读取到未提交的消息。read_committed:消费者只能读取到已提交的消息。
在Go语言中,使用Sarama库设置消费者的隔离级别时,需要使用Kafka版本0.11.0或更高,并配置消费者如下:
1 | |