消息中间件-Kafka

来源:互联网 发布:扫描ssh端口 弱口令 编辑:程序博客网 时间:2024/06/06 17:45

消息发布

Producer在发布消息到某个Partition时,先通过ZooKeeper找到该Partition的Leader,然后无论该Topic的ReplicationFactor为多少(也即该Partition有多少个Replica),Producer只将该消息发送到该Partition的Leader,Leader会将该消息写入其本地Log。每个Follower都从Leaderpull数据。这种方式上,Follower存储的数据顺序与Leader保持一致。Follower在收到该消息并写入其Log后,向Leader发送 ACK。一旦Leader收到了ISR中的所有Replica的ACK,该消息就被认为已经commit了,Leader将增加HW(高水位:表示最近一次提交消息的偏移位置)并且向 Producer发送ACK。
为了提高性能,每个Follower在接收到数据后就立马向Leader发送ACK,而非等到数据写入Log中。因此,对于已经commit的消息,Kafka只能保证它被存于多个Replica的内存中,而不能保证它们被持久化到磁盘中,也就不能完全保证异常发生后该条消息一定能被 Consumer消费。但考虑到这种场景非常少见,可以认为这种方式是在性能和数据持久化上做了一个比较好的平衡。Consumer读消息也是从Leader读取,只有被commit过的消息(offset低于HW的消息)才会暴露给Consumer。

消息订阅

High level api是consumer读的partition的offsite是存在zookeeper上。High level api 会启动另外一个线程去每隔一段时间,offsite自动同步到zookeeper上。换句话说,如果使用了High level api, 每个message只能被读一次,一旦读了这条message之后,无论我consumer的处理是否ok。High level api的另外一个线程会自动的把offiste+1同步到zookeeper上。如果consumer读取数据出了问题,offsite也会在zookeeper上同步。因此,如果consumer处理失败了,会继续执行下一条。这往往是不对的行为。因此,Best Practice是一旦consumer处理失败,直接让整个conusmer group抛Exception终止,但是最后读的这一条数据是丢失了,因为在zookeeper里面的offsite已经+1了。等再次启动conusmer group的时候,已经从下一条开始读取处理了。

Low level api是consumer读的partition的offsite在consumer自己的程序中维护。不会同步到zookeeper上。但是为了kafka manager能够方便的监控,一般也会手动的同步到zookeeper上。这样的好处是一旦读取某个message的consumer失败了,这条message的offsite我们自己维护,我们不会+1。下次再启动的时候,还会从这个offsite开始读。这样可以做到exactly once对于数据的准确性有保证。

Spring Cloud Stream

如果是使用Spring Cloud Stream,我们就不用单独处理offset了,Spring Cloud Stream为我们处理了;我们可以通过如下的四个参数,来配置消费者消费的次数,配置回退算法的参数;
maxAttempts
If processing fails, the number of attempts to process the message (including the first). Set to 1 to disable retry.

Default: 3.

backOffInitialInterval
The backoff initial interval on retry.

Default: 1000.

backOffMaxInterval
The maximum backoff interval.

Default: 10000.

backOffMultiplier
The backoff multiplier.

Default: 2.0.

参考

Kafka设计和原理详解
小白也能看懂的简单明了kafka原理解析
Kafka史上最详细原理总结
mafka平台架构
Kafka副本同步机制理解
Kafka数据可靠性与一致性解析
kafka consumer防止数据丢失
Kafka的分布式架构设计与High Availability机制
微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务
基于Kafka消息驱动最终一致事务(一)
基于Kafka消息驱动最终一致事务(二)
Kafka delivery保证(kafka消息投递保证)
kafka使用high api如何确保不丢失消息,不重复发送,消息只读取一次?
Kafka消息投递语义-消息不丢失,不重复,不丢不重

原创粉丝点击