Kafka 是互联网行业内常用的一个消息中间,和RabbitMQ、RocketMQ的作用都是解耦生产端和消费端,缓存消息。
优点:
- 高吞吐,低延迟(零拷贝)
- 可扩展性
- 持久性,可靠性(磁盘持久化)
- 容错性(副本)
- 高并发
Kafka是怎么保证端到端之间的消息一致性的呢?
每一个环节都会可能导致数据丢失或者重复。
生产者的职责就是,确保生产的消息能到达Kafka,这里一般可以通过ack机制(kafka中的参数)来确定消息是否到达kafka中。
1.1 ack该参数表示有多少个分区副本收到消息,才认为本次发送是成功的。
- acks=0,只要发送消息就认为成功,生产端不等待服务器节点的响应(生产上一般不采用这种,很容易导致数据丢失)
- acks=1,表示生产者收到 leader 分区的响应就认为发送成功
- acks=-1,只有当 ISR 中的副本全部收到消息时,生产端才会认为是成功的。这种配置是最安全的,但由于同步的节点较多,吞吐量会降低。
ISR:in-sync Replica,是有分区leader维护的一个与leader消息基本保持同步的副本集合,称之为ISR,否则称之为OSR(out-sync Replica)
在发送消息的时候可以设计参数 retries 和 retry.backoff.m
retries 表示生产端的重试次数,如果重试次数用完后,还是失败,会将消息临时存储在本地磁盘,待服务恢复后再重新发送。
retry.backoff.m 表示重试的间隔时间。
这里要特别注意一种特殊情况,如果Kafka没有正常响应,不一定代表消息发送失败,也有可能是响应时正好赶上网络抖动,响应超时。如果再次发送就会导致数据重复。
如下图所示:
服务端作为消息的存储介质,也有可能会丢失消息。比如:某个分区leader挂掉,为了保证这个分区的数据不丢失并且能够继续对外提供服务,我们会引入副本概念,通过备份来解决这个问题。类似于hdfs中的副本机制。
具体可设置哪些参数?
2.1 参数 replication.factor表示分区副本的个数,replication.factor >1 当leader 副本挂了,follower副本会被选举为leader继续提供服务。
2.2 参数 min.insync.replicas表示 ISR 最少的副本数量,通常设置 min.insync.replicas >1,这样才有可用的follower副本执行替换,保证消息不丢失
2.3 参数 unclean.leader.election.enable是否可以把非 ISR (即OSR:follow消息滞后于leader分区很多)集合中的副本选举为 leader 副本。
如果设置为true,而follower副本的同步消息进度落后较多,此时被选举为leader,会导致消息丢失,一般不采用。
如图:
follow-C副本处于OSR模式,消息滞后于leader很多。
消费者就是消费kafka服务端存储的数据。消费了之后会提交一个offset(记作消费偏移量)给到服务端。
提交offset的时刻
- 拉取消息-业务处理-提交offset(推荐)
- 拉取消息-提交offset-业务处理(不推荐,会导致可能提交了offset,但是并没有进行业务处理,因此会导致数据丢失。)
如果生产者在接受ack的时候和消费者提交offset的时候遇到网络故障的话,该怎么解决呢?
如图:
手动提交offset
设置 enable.auto.commit=false;
提交offset失败之后就会导致下次还会重复消费已经消费过的消息(重复消费)
针对这个现象,可以采用幂等性的方式解决,
kafka 在 0.11.0 版本后,每条消息都有唯一的message id, MQ服务采用空间换时间方式,自动对重复消息过滤处理,保证接口的幂等性。



