kafka 如何保证消息不丢失
Kafka 如何保证消息不丢失
Kafka 主要从 生产者(Producer)、Broker(服务器)、消费者(Consumer) 三个方面保证消息不丢失。下面是完整的代码示例,包括关键的 Kafka 配置。
组件 | 关键配置 | 作用 |
---|---|---|
生产者 | acks=all |
确保消息写入所有 ISR 副本 |
retries=Integer.MAX_VALUE |
失败时自动重试 | |
enable.idempotence=true |
避免因重试导致的重复消息 | |
Broker | replication.factor=3 |
提供多副本数据持久化 |
min.insync.replicas=2 |
确保最小同步副本数 | |
unclean.leader.election.enable=false |
避免不安全的 Leader 选举 | |
消费者 | enable.auto.commit=false |
确保消息消费后才提交 Offset |
auto.offset.reset=earliest |
确保重新读取未消费消息 | |
事务 | transactional.id |
确保 Exactly-Once |
1. 生产者端(Producer)配置与代码
✅ 关键点:
acks=all
确保消息被所有 ISR 副本写入。retries=Integer.MAX_VALUE
遇到临时故障时重试,避免丢失消息。enable.idempotence=true
生产者开启幂等性,避免因重试导致的重复消息。max.in.flight.requests.per.connection=1
确保顺序发送,避免乱序。
🔹 配置
# 生产者配置(producer.properties)
acks=all
retries=2147483647
enable.idempotence=true
max.in.flight.requests.per.connection=1
request.timeout.ms=60000
delivery.timeout.ms=120000
🔹 代码
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
public class ReliableProducer {
public static void main(String[] args) {
// 1. 配置生产者属性
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ProducerConfig.ACKS_CONFIG, "all"); // 等待所有 ISR 副本确认
props.put(ProducerConfig.RETRIES_CONFIG, Integer.MAX_VALUE); // 无限重试
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true"); // 开启幂等性
props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); // 避免乱序
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
// 2. 发送消息
for (int i = 0; i < 10; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>("reliable_topic", "key" + i, "value" + i);
producer.send(record, (metadata, exception) -> {
if (exception == null) {
System.out.println("Message sent to partition " + metadata.partition() + " at offset " + metadata.offset());
} else {
System.err.println("Message send failed: " + exception.getMessage());
}
});
}
// 3. 关闭生产者
producer.close();
}
}
2. Kafka Broker 端(服务器)配置
✅ 关键点:
- 副本机制(Replication) 确保数据不会因为单点故障丢失。
- ISR(In-Sync Replica) 控制最小同步副本数,确保消息写入安全。
- 日志持久化(Flush) 避免 Kafka 崩溃导致的数据丢失。
🔹 配置
# Broker 端配置(server.properties)
default.replication.factor=3 # 设置副本数量(必须 >= 3)
min.insync.replicas=2 # 至少 2 个副本同步,保证数据安全
log.flush.interval.messages=1 # 每条消息都 flush(影响性能,调优可调整)
log.flush.interval.ms=1000 # 每 1s 刷盘,避免数据丢失
unclean.leader.election.enable=false # 禁止非 ISR 副本选举,避免数据丢失
3. 消费者端(Consumer)配置与代码
✅ 关键点:
- 手动提交 Offset 确保消费成功后才提交,防止消息丢失。
- 关闭自动提交
enable.auto.commit=false
避免 Offset 在消费前提交。
🔹 配置
# 消费者配置(consumer.properties)
enable.auto.commit=false # 关闭自动提交,改为手动提交
auto.offset.reset=earliest # 确保消费者从头读取未消费的消息
🔹 代码
import org.apache.kafka.clients.consumer.*;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
public class ReliableConsumer {
public static void main(String[] args) {
// 1. 配置消费者属性
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "reliable_group");
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false"); // 关闭自动提交 Offset
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); // 重新消费未处理消息
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("reliable_topic"));
// 2. 轮询消息并手动提交 Offset
try {
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
System.out.println("Received message: " + record.value() + ", offset: " + record.offset());
// 3. 处理成功后手动提交 Offset
consumer.commitSync();
}
}
} finally {
consumer.close();
}
}
}
4. 事务支持(Exactly-Once 语义)
Kafka 2.0+ 提供事务 API,确保生产 + 消费的 Exactly-Once 语义。
🔹 生产者端(带事务)
props.put(ProducerConfig.TRANSACTIONAL_ID_CONFIG, "tx-id-123"); // 事务 ID
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
producer.initTransactions();
try {
producer.beginTransaction();
producer.send(new ProducerRecord<>("reliable_topic", "key", "value"));
producer.commitTransaction(); // 提交事务
} catch (Exception e) {
producer.abortTransaction(); // 回滚事务
}
🔹 消费者端(带事务)
props.put(ConsumerConfig.ISOLATION_LEVEL_CONFIG, "read_committed"); // 只消费已提交的事务数据
本文作者:MuXinu
本文链接:https://www.cnblogs.com/MuXinu/p/18711883
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器