kafka 从分区任意位置、分区开头、分区末尾开始消费数据

本文探讨了Kafka消费者在消费数据时如何从分区的任意位置、开头或末尾开始。与Redis相比,Kafka提供订阅消息的存储功能,并允许在磁盘上存储订阅消息。消费者在加入消费者分组后,通过subscribe函数订阅topic,同一分片只能被一个分组内的消费者消费。此外,通过配置auto.offset.reset属性,可以选择从分区的开头或末尾开始消费。文中以kafka0.10.0.0版本为例,提供了相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近就kafka消费者消费数据时,消费者提交的offset与同事们有一些分歧和讨论,这里记录一下自己的研究。

我们知道redis和kafka都可以作为消息队列使用,都可以完成发布订阅功能,但是kafka相较于redis可以实现订阅消息的存储,可以实现订阅消息的任意位置消费,更重要的时kafka订阅消息是可以存储到磁盘上的,而redis订阅消息是无法存储磁盘的。

(1)消费者消费数据时加入一个消费者分组之后,可以通过 subscribe函数订阅某个topic,这时这个消费者进入brokers的group management管理机制,同一个分片只能被一个分组中的消费者消费,如果同一个分片希望被多个消费者消费,需要将多个消费者放入到不同的消费者分组中。

 //订阅指定的topic
consumer.subscribe(Arrays.asList(topic));
(2)还有一种消费数据的方式是可以通过assign函数指定要消费的分区数据,这种方式可以指定从分区的任意位置开始消费数据,当然这种
//消费者指定要消费的分区,指定分区之后消费者崩溃之后 不会引发分区reblance
consumer.assign(list);
消费数据的方式,如果消费者奔溃之后,不会引发分区reblance,也就是说assign的consumer不会拥有kafka的group management机制。

我们上面说过,同一个分片只能由消费者分组中的同一个消费者进行消费,假设当消费者A使用assign指定分区进行消费时,如果这时消费者A使用的分组group B,是通过subscribe订阅了这个主题的分片时,由于消费者A不加入group management,它相当于一个独立的临时消费者,这时消费者A也是可以正常消费的,看起来就是一个分片被一个消费者组中的多个消费者消费一样。


(3)我们还可以配置如下属性auto.offset.reset来,设置消费者从分区的开头或者末尾进行消费数据。当然这也是有条件的。

 //一般配置earliest 或者latest 值
props.put("auto.offset.reset", "latest");

我把上述三种情况的消费者不同使用方式下,消费者提交offset的情况进行了归总和说明:


早在kafka0.8.2.2版本的时候,kafka已经支持消息offset存在brokers中,只不过默认是将offset存储到zookeeper中。kafka现在最新发布的版本都是默认将数据存储到brokers中。我的代码示例是使用了kafka0.10.0.0版本,当我们这里通过assign函数分配指定的分区时


下面是我的测试代码,有兴趣的同学可以查看和验证上述结论:


 

/**
 * 
 * @author yujie.wang
 * kafka生产者示例代码
 */
public class Producer_Sample {
	//kafka集群机器
	private static final String KAFKA_HOSTS = "10.4.30.151:9092,10.4.30.151:9093,10.4.30.151:9094";
	//topic名称
	private static final String TOPIC = "my-replicated-topic_2";
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Producer_Sample producer = new Producer_Sample();
		producer.producer_send(TOPIC);
		System.out.println("end");
	}
	
	/**
	 * 生产者生产数据
	 * 发送消息是异步进行,一旦消息被保存到
<think>首先,用户的问题是:“我想在Kafka中创建主题test并设置三个分区后,如何实现消息的生产和消费 请问Kafka 创建主题 test 三个分区 如何实现消息生产与消费”。这涉及到Kafka的基本操作:创建主题、生产消息和消费消息。 用户引用了几个参考内容,我需要参考这些内容来确保回答准确: - 引用[1]:提到Kafka消费者的分区分配策略,如range、round-robin和sticky策略。 - 引用[2]:讨论Kafka分区和副本机制,以及生产者分区写入策略。 - 引用[3]:解释Kafka消息的键值对结构,以及键如何用于确定分区。 - 引用[4]:展示Kafka实操,包括创建主题、生产者、消费者组,查看消费偏移等。 用户的问题具体是:创建主题"test"有三个分区,然后实现消息的生产和消费。 我的回答需要: - 结构清晰,逐步解决问题。 - 使用中文。 - 遵循系统级指令:行内数学表达式用$...$,独立公式用$$...$$,但Kafka主题可能不涉及数学公式,所以可能不需要。但如果有概率或统计,才用。 - 生成相关问题。 - 在回答中引用的段落末尾添加引用标识。 回答结构: 1. **创建主题**:解释如何创建主题"test"有三个分区。 2. **生产消息**:如何用生产者发送消息到这个主题。 3. **消费消息**:如何用消费消费消息。 4. 生成相关问题。 从引用中提取关键信息: - 创建主题:引用[4]提到使用kafka-topics.sh脚本来创建主题。 - 生产者:引用[3]提到消息有键值对,键可以用于分区。 - 消费者:引用[1]提到分区分配策略;引用[4]提到消费者组和消费偏移。 步骤: 1. **创建主题**: - 使用Kafka命令行工具创建主题。 - 命令示例:`kafka-topics.sh --create --bootstrap-server <broker> --topic test --partitions 3 --replication-factor 1`(假设复制因子为1)。 - 参考引用[4]。 2. **生产消息**: - 使用生产者API或命令行工具发送消息。 - 消息可以有键,键决定分区(引用[3])。 - 命令示例:`kafka-console-producer.sh --bootstrap-server <broker> --topic test`。 - 在Java中,使用ProducerRecord(引用[3])。 3. **消费消息**: - 使用消费者API或命令行工具消费消息。 - 消费者可以指定组ID(引用[4])。 - 命令示例:`kafka-console-consumer.sh --bootstrap-server <broker> --topic test --group my-group`。 - 分区分配策略如range或round-robin(引用[1])。 确保回答真实可靠:基于Kafka标准文档和实践。 生成相关问题: - 基于主题,如:如何优化Kafka的生产和消费?如何处理分区再均衡?等。 完整回答结构: - 介绍:简要说明Kafka主题、分区、生产者和消费者。 - 步骤1:创建主题。 - 步骤2:生产消息。 - 步骤3:消费消息。 - 相关问题。 添加引用: - 在相关部分末尾添加引用标识,如[^1]、[^2]等。</think>### Kafka主题创建与消息生产消费实现指南 在Kafka中创建主题、设置分区并实现消息的生产和消费是核心操作。以下我将基于Kafka标准实践(以Kafka 3.x版本为例),逐步解释如何创建主题"test"(三个分区),并实现消息的生产和消费过程。整个过程包括命令行工具操作和Java API示例(如需编程实现)。所有步骤均参考Kafka官方文档和站内引用内容,确保可靠[^1][^2][^3][^4]。 --- ### 步骤1: 创建主题"test"并设置三个分区Kafka中,主题(Topic)是消息的逻辑容器,分区(Partition)用于并行处理和负载均衡。创建主题需使用Kafka的`kafka-topics.sh`命令行工具(位于Kafka安装目录的`bin/`下)。假设Kafka集群已启动,且ZooKeeper或KRaft模式配置正确。 - **命令示例**: ```bash # 创建主题"test",指定3个分区和1个副本(replication-factor可根据集群规模调整) ./bin/kafka-topics.sh --create \ --bootstrap-server localhost:9092 \ # 替换为实际broker地址 --topic test \ --partitions 3 \ --replication-factor 1 ``` - **验证主题创建**: ```bash # 查看主题详情,确认分区数 ./bin/kafka-topics.sh --describe \ --bootstrap-server localhost:9092 \ --topic test ``` 输出应显示类似: ``` Topic: test PartitionCount: 3 ReplicationFactor: 1 Configs: Topic: test Partition: 0 Leader: 0 Replicas: 0 Isr: 0 Topic: test Partition: 1 Leader: 0 Replicas: 0 Isr: 0 Topic: test Partition: 2 Leader: 0 Replicas: 0 Isr: 0 ``` 这表示主题"test"成功创建,有三个分区(Partition 0,1,2)[^4]。 **关键点**: - 分区数决定消息的并行处理能力;三个分区允许消息分散存储,提高吞吐量。 - 如果使用旧版Kafka(依赖ZooKeeper),需替换`--bootstrap-server`为`--zookeeper localhost:2181`[^2]。 --- ### 步骤2: 实现消息生产 生产者(Producer)负责向主题发送消息。消息由键(Key)和值(Value)组成,键用于确定消息写入哪个分区(相同键的消息写入同一分区)。Kafka提供命令行工具或编程API(如Java)实现生产。 #### 方法1: 命令行生产者(快速测试) 使用`kafka-console-producer.sh`发送消息: ```bash # 启动生产者,向主题"test"发送消息 ./bin/kafka-console-producer.sh \ --bootstrap-server localhost:9092 \ --topic test \ --property "parse.key=true" \ # 启用键值对格式 --property "key.separator=:" # 定义键值分隔符(例如 key:value) ``` 输入消息示例(每条消息格式为`键:值`): ``` key1:Hello Kafka key2:This is a test key1:Another message # 相同key1的消息会写入同一分区 ``` - **分区规则**:如果指定键(如`key1`),消息根据键的哈希值分配到特定分区;未指定键时,采用轮询(round-robin)策略分发到不同分区[^3]。 #### 方法2: Java API生产者(编程实现) 使用Kafka的Java客户端(需添加依赖如`kafka-clients`): ```java import org.apache.kafka.clients.producer.*; public class SimpleProducer { public static void main(String[] args) { // 1. 配置生产者属性 Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); // Kafka broker地址 props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); // 2. 创建生产者实例 Producer<String, String> producer = new KafkaProducer<>(props); // 3. 发送消息到主题"test" for (int i = 0; i < 5; i++) { String key = "key" + (i % 3); // 键决定分区:key0,key1,key2循环 String value = "Message " + i; ProducerRecord<String, String> record = new ProducerRecord<>("test", key, value); // 异步发送(可添加回调处理) producer.send(record, (metadata, exception) -> { if (exception == null) { System.out.println("Sent to partition: " + metadata.partition()); } else { exception.printStackTrace(); } }); } // 4. 关闭生产者 producer.close(); } } ``` - **分区机制**:通过键(如`key0`)控制消息写入分区。例如,`key0`的消息总是分配到同一分区(如Partition 0),确保相关消息顺序性[^3]。 - **性能提示**:批量发送和异步机制可提升吞吐量[^2]。 --- ### 步骤3: 实现消息消费 消费者(Consumer)从主题拉取消息。Kafka消费者通常以组(Group)形式工作,组内消费者共享分区负载。默认分区分配策略是range或round-robin(新版本支持sticky策略)[^1]。 #### 方法1: 命令行消费者(快速测试) 使用`kafka-console-consumer.sh`消费消息: ```bash # 启动消费者,指定消费者组(group.id) ./bin/kafka-console-consumer.sh \ --bootstrap-server localhost:9092 \ --topic test \ --group my-test-group # 消费者组ID,用于协调分区分配 ``` - **输出示例**:消费者将按顺序显示消息(如`Hello Kafka`)。注意:多分区下消息顺序可能乱序,因为每个分区独立消费[^4]。 - **查看消费偏移**:验证消费进度: ```bash ./bin/kafka-consumer-groups.sh --describe \ --bootstrap-server localhost:9092 \ --group my-test-group ``` #### 方法2: Java API消费者(编程实现) ```java import org.apache.kafka.clients.consumer.*; import java.time.Duration; import java.util.Collections; import java.util.Properties; public class SimpleConsumer { public static void main(String[] args) { // 1. 配置消费者属性 Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("group.id", "my-test-group"); // 消费者组ID props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("auto.offset.reset", "earliest"); // 从最早偏移开始消费 // 2. 创建消费者实例 Consumer<String, String> consumer = new KafkaConsumer<>(props); // 3. 订阅主题"test" consumer.subscribe(Collections.singletonList("test")); // 4. 拉取并处理消息 try { while (true) { ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100)); for (ConsumerRecord<String, String> record : records) { System.out.printf("Partition: %d, Key: %s, Value: %s\n", record.partition(), record.key(), record.value()); } } } finally { consumer.close(); // 关闭消费者 } } } ``` - **分区分配**:消费者组内自动协调分区分配(如三个分区可能分配给组内多个消费者)。例如,一个消费者组有三个消费者时,每个消费者负责一个分区[^1]。 - **顺序性**:单个分区内消息有序,但跨分区消息可能乱序(如Partition 0的消息先于Partition 1到达)[^4]。 --- ### 关键注意事项 1. **分区与性能**:三个分区提升并行度,但过多分区可能增加管理开销。建议根据生产者/消费者数量调整[^2]。 2. **消息顺序**:使用相同键确保相关消息写入同一分区,以维护顺序性[^3]。 3. **消费者组**:组ID用于跟踪消费偏移(offset)。再均衡(rebalance)时,组内消费者自动重新分配分区[^1]。 4. **错误处理**:生产/消费时监控日志,常见问题如broker不可达或序列化错误。 通过以上步骤,您已实现Kafka主题创建、消息生产和消费的全流程。如需扩展(如安全认证或流处理),可参考Kafka官方文档。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值