进击的Kafka(四):生产者-生产实践

107 阅读3分钟

一.生产者如何提高吞吐量

  • batch.size:批次大小,默认16。增加到32k
  • linger.ms: 等待时间,默认0(无延迟)。 修改为5-100ms
  • compression.type:压缩方式(gZip、snappy、Lz4、Zstd)。修改为snappy
  • buffer.memory:RecordAccumulator缓冲区大小,默认32m。修改为64m

二.数据可靠性

通过配置acks来实现不同的数据可靠性

(1)、acks(0)

生产者发送数据,不需要等到数据落盘应答。 数据可靠性:数据丢失

(2)、acks(1)

生产者发送数据,等待leader收到数据并落盘应答。 数据可靠性:比0可靠,但还是会丢数(leader接收到数据,落盘并响应,但是follower还没有同步数据并落盘,如果leader挂掉后,重新选出一个leader,但新leader没有对应数据)

(3)、acks(-1/all)

生产者发送数据,等待leader和follower全都收到数据并落盘应答 数据可靠性:需要有一定的条件(分区副本数 ≥ 2 + isr队列应答最小副本数 ≥ 2)

  • isr队列(in-sync replicas set):和leader保持同步的follower+leader集合(leader:0,isr:0,1,2)
  • ISR队列应答最小副本数:min.insync.replicas

解决(ack设置为-1/all时,某一个follower挂了,导致迟迟没有它的应答) 设置replica.log.time.max.ms参数,默认30ms。达到设置值,将follower踢出isr队列

(4)、总结

akc=0,很少使用 ack=1,一般用于传输日志,允许丢个别数据 ack=-1/all,用于可靠性要求高的场景:钱

akc设置数据可靠性传输效率
0
1中等中等
-1/all

三.数据重复

ack设置为(-1/all)时,follower同步完后,leader准备应答时,忽然挂了。follower成为leader后,重新接收数据,导致数据重复

(1)、至少一次(at least one)

akc=-1/allmin.insync.replice ≥ 2。保证数据不丢失,不保证数据不重复

(2)、最多一次(at most one)

ack = 0。保证数据不重复,不保证不丢失

(3)、精确一次(exactly ont)

幂等性(不管producer发多少次,broker都只有持久化一份数据)+事务+至少一次 幂等性参数:enable.idempotence=true(默认开启)

(4)、幂等判重标准

<PID,partition,SeqNumber>:幂等只能在单分区单会话内不重复
PID:kafka每次重启,都会分配一个新的PID
partition:分区号
Sequence Number:单调自增

(5)、完善幂等的PID问题

在使用事务功能时,自定义一个唯一的transactionalId。这样即使重启后,也可以根据transactionalId继续处理

四.事务原理

  • 开启事务,必须开启幂等性
  • 确认事务信息存储主体的分区(默认50个):transactionalId的hashCode值%50

五、数据有序

(1)、多分区有序

如果想要多分区有序,可以把所有数据都拉倒消费者中,然后排序

(2)、单分区有序

  • 1.x版本之前,通过设置max.in.flight.requests.per.connection = 1,不需要考虑是否开启幂等
  • 1.x版本之后,如果没有开启幂等,同1.x配置。 如果开启幂等,设置max.in.flight.requests.per.connection ≤ 5