Kafka简单介绍
1.定义
Kafka是个分布式的基于发布/订阅模式的消息队列
消息队列的好处:解耦、可恢复性、缓冲、灵活性&峰值处理、异步通信
发布/订阅模式:消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。消费者消费数据之后不会清除消息,会在kafka本地磁盘默认保存7天,保存时间可以设置。
2.Kafka数据可靠性保证
(1)ack应答机制
为保证producer发送的数据,能可靠的发送到指定的topic,topic的每个partition收到producer发送的数据后,都需要向producer发送ack(acknowledgement确认收到),如果producer收到ack,就会进行下一轮的发送,否则重新发送数据。其实整个ack应答都是由leader发送给producer
ISR副本同步队列:Leader维护了一个动态的in-syncreplica set (ISR),意为和leader保持同步的follower集合。当ISR中的follower完成数据的同步之后,leader就会给follower发送ack。如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定。Leader发生故障之后,就会从ISR中选举新的leader。
acks=0:broker一接收到数据还没有写入磁盘就向producer返回应答,即我这边收到数据了,你可以进行下一轮数据发送。如果broker故障,则数据也没有被写入磁盘,但是producer那边认为数据已经被写入了,就会导致数据丢失
acks=1:leader落盘成功后即向producer返回应答,但是这个时候follower可能还没有同步成功,此时如果leader挂掉了,则follower无法正常同步数据,但是producer那边却认为数据已经落盘成功。在ISR副本同步队列中选取的新Leader(之前未同步成功的follower)数据是不完整的,即最后会导致数据丢失
acks=-1:lead和follower全部落盘成功broker才向producer返回应答。但是,如果在follower同步完成之后,leader向producer发送ack之前,leader挂掉了,这就导致producer以为没有发送成功,就会重新发送数据,但其实新leader(即已经完成同步的follower)已经存在该数据了,则会造成数据重复
(2)数据不丢失问题
At Least Once语义:将服务器的ACK级别设置为-1,可以保证Producer到Server之间不会丢失数据(可以保证数据不丢失,但不能保证数据不重复)
幂等性:指Producer不论向Server发送多少次重复数据,Server端都只会持久化一条。开启幂等性enable.idempotence=true(无法保证开分区跨会话)
Exactly Once=At Least Once + 幂等性
(3)Kafka事务
事务可以保证Kafka在Exactly Once语义的基础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。
个人理解:由上可知,kafka处理后的数据已经不存在丢失问题了,但是可能存在数据重复的问题,解决方法:在下一级(SparkStreaming,redis,hive等)对数据进行去重。
对于Kafka下游数据的处理:主要是下游消费者的配置
Consumer消费数据时的可靠性是很容易保证的,因为数据在Kafka中是持久化的,故不用担心数据丢失问题。
由于consumer在消费过程中可能会出现断电宕机等故障,consumer恢复后,需要从故障前的位置的继续消费,所以consumer需要实时记录自己消费到了哪个offset,以便故障恢复后继续消费
(1)kafka自动提交offset,kafka提供了自动提交offset的功能
(2)手动提交offset,虽然自动提交offset十分简介便利,但由于其是基于时间提交的,开发人员难以把握offset提交的时机。
Kafka下游数据出错两种:数据丢失,数据重复
数据丢失问题:手动维护偏移量,即处理完业务数据后,再进行偏移量的提交操作,如存入Mysql等数据库中方便维护管理
数据重复问题:极端情况下,如在提交偏移量时机器故障会造成再消费问题,所以在涉及到金额或精确性非常高的场景会使用事务保证精准一次性消费(说实话,不知道怎么做)。自己想法:进行一个数据去重,会影响效率,但可以保证数据Exactly Once
网友评论