二.优化
1.不丢失数据ack=-1
当Producer向Leader发送消息时,可以通过ack的值来设置可靠性级别。
1)1(默认)
意味着ISR中的Leader已成功收到消息并且Producer得到Leader收到消息的确认。如果ISR中的副本数还没有来得及拉取数据就宕机了,则会丢失数据。
2)0
意味着Producer无需等待来自Broker的确认而继续发送下一批消息,此时数据传输效率最高,但是数据可靠性最低。
3)-1(all)
Producer需要等待ISR中所有的Replicas都成功收到消息并得到它们收到消息的确认,在副本数为1的情况下,只有一个Leader,等同于ack=1,这种情况下Leader挂了,会丢数据。在副本数>1的情况下,不会丢失数据,但数据有可能会重复。
a)副本数>1的情况下,数据发送到Leader,ISR的Follower全部完成数据同步后,Leader挂掉,选举出新的Leader,数据不会丢失。
b)副本数>1的情况下,数据发送到Leader后,Follower1同步完成,Follower尚未同步,此时Leader挂掉,Producer端会返回异常,Producer端会重新发送数据,数据可能会重复。
2.分区的个数最好是消费者的整数倍
方便消费者均匀的读数据?
3.幂等(exactly once)
幂等保证Producer在一个Partition内消息精准一次。
1)最多一次(at most once):消息可能会丢失,但绝对不会重复。
2)至少一次(at least once):消息不会丢失,但有可能会重复。
3)精准一次(exactly once):消息不会丢失,也不会重复。
设置方法:props.put("enable.idempotence",true)
原理:相当于在Broker端存了一个id,当Producer发送了具有相同id值的消息后。Broker能够自动知晓这些消息已经重复了。