持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
kafka生产模式下生产者经验
提高吞吐量
可以通过修改以下这四个参数来提高消费者的吞吐量。
• batch.size:批次大小,默认16k
• linger.ms:等待时间
• compression.type:压缩snappy
• RecordAccumulator:缓冲区大小,修改为64m
相关设置解释
1、适当增加 缓冲区一批数据最大值 (batch.size)可以提高吞吐量,但是太大之后可能会造成数据传输的延时增加。
2、数据达不到batch.size的值时候,在达到等待时候之后也会发送消息。
数据可靠性
生产者发送消息到broker之后的应答策列,Ack的设置
• 0:生产者发送过来的数据,不需要等数据落盘应答。效率快,但是可靠性不高。
• 1:生产者发送过来的数据,Leader收到数据后应答。 效率和可靠性适中
• -1(all):生产者发送过来的数据,Leader+和isr队列 里面的所有节点收齐数据后应答。-1和all等价。 效率慢,可靠性高(kafka默认的应答策列)
当红色的follow挂了之后,一直不能和Leader进行同步,这种情况会认为机器故障,但是避免这种情况在Leader中维护了一个ISR队列,它包含Follow和Leader的集合,如果一个Follow长时间没有和Leader进行通信(发送数据交互或者同步数据)就会从ISR集合中移除这个Follow。 该时间阈值由replica.lag.time.max.ms参 数设定,默认30s。例如2超时,(leader:0, isr:0,1)。 所以数据的可靠性:(分区副本包含Leader和Follow,kafka副本默认一个,生成环境设置2个)
完成可靠性分析:ACK级别设置为-1 + 分区副本大于等于2 + ISR里应答的最小副本数量大于等于2
数据重复问题
数据保证不重复:第一:生产者至少发送一次数据到kafka集群(数据不丢),第二:生产者最多也只发送一个次数到kafka集群。(数据不重复)
幂等性
生产者无论向kafka集群发送多少次数据,broker中都只会持久化一次。
重复数据判断条件:通过以下这三个条件判断该数据是否重复。
- 生产者Id:PID kafka每次重启都会生成一个新的Id(所以只能在单次会话中保证不重复)
- 分区号 Partition :分区号
- 序列号SeqNumber:单调递增
生产者事务
幂等性只能保证在单次会话中保证数据不重复,当kafka集群重启后仍然可能会有重复数据产生。
开启事务,必须要先开启幂等性。
事务协调器选择
事务协调器 ( Transaction Coordinator )每一个broke节点都有事务协调器,那么是如何选择的呢?
- 根据存储事务信息的特殊主题(该主题默认有50个分区)
- 用事务id(需要配置)除以50取摸,得到事务属于哪一个分区。
- 该分区的Leader副本所在的broker就是这个事务id对应的Transaction Coordinator 节点。
生产者使用事务示例
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);
kafkaProducer.initTransactions();
kafkaProducer.beginTransaction();
try {
// 2 发送数据
for (int i = 0; i < 5; i++) {
kafkaProducer.send(new ProducerRecord<>("first", "atguigu" + i));
}
int i = 1 / 0;
kafkaProducer.commitTransaction();
} catch (Exception e) {
kafkaProducer.abortTransaction();
} finally {
// 3 关闭资源
kafkaProducer.close();
}
数据有序
由于分区的原因导致发送的消息可能在不同的分区。所以我们需要数据在多分区下有序。生产者发送的数据有先后关系,在消费者消费数据同时,我们需要消费的数据也是原来发送的顺序的。
多分区的情况下可采用一个消费者拉去所有分区的数据再进行排序,然后再进行消费。效率还不如单分区,保证单分区内数据有序。
数据乱序
产生的原因:数据1发送过去,发送成功,数据2发送失败导致重试,但是数据3可能已经发送过去了,最后又发送数据2,导致数据为1,3,2乱序了。
解决办法:
1)kafka在1.x版本之前保证数据单分区有序,条件如下: max.in.flight.requests.per.connection=1(不需要考虑是否开启幂等性)。
2)kafka在1.x及以后版本保证数据单分区有序,条件如下:
(1)未开启幂等性 max.in.flight.requests.per.connection需要设置为1。
(2)开启幂等性 max.in.flight.requests.per.connection需要设置小于等于5。
原因说明:因为在kafka1.x以后,启用幂等后,kafka服务端会缓存producer发来的最近5个request的元数据, 故无论如何,都可以保证最近5个request的数据都是有序的。