一、数据传递语义
- 至少一次(At Least Once):ACK级别设置为-1+分区副本大于等于2+ISR里应答的最小副本数量大于等于2
- 最多一次(At Most Once):ACK级别设置为0
- 精确一次(Exactly Once):对于一些非常重要的信息,比如和钱相关的数据,要求数据既不能重复也不丢失。幂等性+至少一次
- 总结:
- At Least Once可以保证数据不丢失,但是不能保证数据不重复
- At Most Once可以保证数据不重复,但是不能保证数据不丢失
二、幂等性
一、介绍
幂等性就是指Producer不论向Broker发送多少次重复数据,Broker端都只会持久化一条,保证数据不重复
二、重复数据的判断标准:
具有<PID,Partition,SeqNumber>相同主键的消息提交时,Broker只会持久化一条。其中PID是Kafka每次重启都会分配一个新的;Partition表示分区号;Sequence Number是单调自增的。所以幂等性只能保证是在单分区单会话内不重复
三、参数
enable.idempotence,默认为true,false关闭
三、Kafka事务
一、原理
二、相关API
// 1 初始化事务
void initTransactions();
// 2 开启事务
void beginTransaction() throws ProducerFencedException;
// 3 在事务内提交已经消费的偏移量(主要用于消费者)
void sendOffsetsToTransaction(Map<TopicPartition, OffsetAndMetadata> offsets,
String consumerGroupId) throws
ProducerFencedException;
// 4 提交事务
void commitTransaction() throws ProducerFencedException;
// 5 放弃事务(类似于回滚事务的操作)
void abortTransaction() throws ProducerFencedException;
三、单个Producer使用事务保证消息的仅一次发送
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.Properties;
public class CustomProducerAck {
public static void main(String[] args) {
// 1.创建kafka配置对象
Properties properties = new Properties();
// 2.配置对应参数
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"node1:9092");
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());
// 设置ack
properties.put(ProducerConfig.ACKS_CONFIG,"all");
// 重试次数retries,默认是int最大值2147483647
properties.put(ProducerConfig.RETRIES_CONFIG,3);
// 3.创建kafka生产者对象
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);
// 4.调用send方法,发送消息
for(int i=0;i<5;i++){
kafkaProducer.send(new ProducerRecord<>("first","testMessage"+1));
}
// 5.关闭资源
kafkaProducer.close();
}
}