为制止上面类似情况的发作,除了做好抵偿办法,更应该在系设想的时候充实考虑各类异常,设想一个不变、高可用的动静系统。
认识Kafka看一下维基百科的定义
Kafka是散布式发布-订阅动静系统。它最后由LinkedIn公司开发,之后成为Apache项目标一部门。
Kafka是一个散布式的,可划分的,冗余备份的耐久性的日记办事。它次要用于处置活泼的流式数据。
kafka架构
Kafka的整体架构十分简单,是显式散布式架构,次要由producer、broker(kafka)和consumer构成。
Kafka架构(精简版)Producer(消费者)能够将数据发布到所选择的topic(主题)中。消费者负责将记录分配到topic的哪一个 partition(分区)中。能够利用轮回的体例来简单地实现负载平衡,也能够按照某些语义分区函数(如记录中的key)来完成。
Consumer(消费者)利用一个consumer group(消费组)名称来停止标识,发布到topic中的每笔记录被分配给订阅消费组中的一个消费者实例。消费者实例能够散布在多个历程中或者多个机器上。
Kafka到底会不会丧失动静?在讨论kafka能否丢动静前先来领会一下什么是动静传递语义。
动静传递语义message delivery semantic 也就是动静传递语义,简单说就是动静传递过程中动静传递的包管性。次要分为三种:
at most once:最多一次。动静可能丧失也可能被处置,但最多只会被处置一次。at least once:至少一次。动静不会丧失,但可能被处置屡次。可能反复,不会丧失。exactly once:切确传递一次。动静被处置且只会被处置一次。不丧失不反复就一次。抱负情况下必定是希望系统的动静传递是严酷exactly once,也就是包管不丧失、只会被处置一次,但是很难做到。
回到配角Kafka,Kafka有三次动静传递的过程:
消费者发动静给Kafka Broker。Kafka Broker 动静同步和耐久化Kafka Broker 将动静传递给消费者。在那三步中每一步都有可能会丧失动静,下面详细阐发为什么会丢动静,若何更大限度制止丧失动静。
消费者丧失动静先介绍一下消费者发送动静的一般流程(部门流程与详细设置装备摆设项强相关,那里先忽略):
消费者是与leader间接交互,所以先从集群获取topic对应分区的leader元数据;获取到leader分区元数据后间接将动静发给过去;Kafka Broker对应的leader分区收到动静后写入文件耐久化;Follower拉取Leader动静与Leader的数据连结一致;Follower动静拉取完毕需要给Leader回复ACK确认动静;Kafka Leader和Follower分区同步完,Leader分区会给消费者回复ACK确认动静。
消费者发送数据流程消费者接纳push形式将数据发布到broker,每条动静逃加到分区中,挨次写入磁盘。动静写入Leader后,Follower是主动与Leader停止同步。
Kafka动静发送有两种体例:同步(sync)和异步(async),默认是同步体例,可通过producer.type属性停止设置装备摆设。
Kafka通过设置装备摆设request.required.acks属性来确认动静的消费:
0暗示不停止动静领受能否胜利确实认;不克不及包管动静能否发送胜利,生成情况根本不会用。1暗示当Leader领受胜利时确认;只要Leader存活就能够包管不丧失,包管了吞吐量。-1或者all暗示Leader和Follower都领受胜利时确认;能够更大限度包管动静不丧失,但是吞吐量低。kafka producer 的参数acks 的默认值为1,所以默认的producer级别是at least once,其实不能exactly once。
敲黑板了,那里可能会丢动静的!
若是acks设置装备摆设为0,发作收集颤动动静丢了,消费者不校验ACK天然就不晓得丢了。若是acks设置装备摆设为1包管leader不丢,但是若是leader挂了,刚好选了一个没有ACK的follower,那也丢了。all:包管leader和follower不丢,但是若是收集拥塞,没有收到ACK,会有反复发的问题。Kafka Broker丧失动静Kafka Broker 领受到数据后会将数据停止耐久化存储,你认为是下面如许的:
动静耐久化,无cache没想到是如许的:
动静耐久化,有cache操做系统自己有一层缓存,叫做 Page Cache,当往磁盘文件写入的时候,系统会先将数据流写入缓存中,至于什么时候将缓存的数据写入文件中是由操做系统自行决定。
Kafka供给了一个参数 producer.type 来控造是不是主动flush,若是Kafka写入到mmap之后就立即 flush 然后再返回 Producer 叫同步 (sync);写入mmap之后立即返回 Producer 不挪用 flush 叫异步 (async)。
敲黑板了,那里可能会丢动静的!
Kafka通过多分区多副本机造中已经能更大限度包管数据不会丧失,若是数据已经写入系统 cache 中但是还没来得及刷入磁盘,此时突然机器宕机或者掉电那就丢了,当然那种情况很极端。
消费者丧失动静消费者通过pull形式主动的去 kafka 集群拉打消息,与producer不异的是,消费者在拉打消息的时候也是找leader分区去拉取。
多个消费者能够构成一个消费者组(consumer group),每个消费者组都有一个组id。统一个消费组者的消费者能够消费统一topic下差别分区的数据,但是不会呈现多个消费者消费统一分区的数据。
消费者群组消费动静消费者消费的进度通过offset保留在kafka集群的__consumer_offsets那个topic中。
消费动静的时候次要分为两个阶段:
1、标识动静已被消费,commit offset坐标;
2、处置动静。
敲黑板了,那里可能会丢动静的!
场景一:先commit再处置动静。若是在处置动静的时候异常了,但是offset 已经提交了,那条动静关于该消费者来说就是丧失了,再也不会消费到了。
场景二:先处置动静再commit。若是在commit之前发作异常,下次还会消费到该动静,反复消费的问题能够通过营业包管动静幂等性来处理。
总结那么问题来了,kafka到底会不会丢动静?谜底是:会!
Kafka可能会在三个阶段丧失动静:
(1)消费者发送数据;
(2)Kafka Broker 存储数据;
(3)消费者消费数据;
在消费情况中严酷做到exactly once其实是难的,同时也会牺牲效率和吞吐量,更佳理论是营业侧做好抵偿机造,万一呈现动静丧失能够兜底。








还没有评论,来说两句吧...