kafka概念扫盲(2)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: kafka概念扫盲

三、kafka的生产者和消费者

3.1、kafka的生产者


Kafka的partition的分区的作用


Kafka的分区的原因主要就是提供并发提高性能,因为读写是partition为单位读写的;


那生产者发送消息是发送到哪个partition中呢?


A、在客户端中指定partition


B、轮询(推荐)消息1去p1,消息2去p2,消息3去p3,消息4去p1,消息5去p2,消息6去p3 。。。。。。。



3.2 kafka如何保证数据可靠性呢?

通过ack来保证


为保证生产者发送的数据,能可靠的发送到指定的topic,topic的每个partition收到生产者发送的数据后,都需要向生产者发送ack(确认收到),如果生产者收到ack,就会进行下一轮的发送,否则重新发送数据

网络异常,图片无法展示
|

 

网络异常,图片无法展示
|

 

那么kafka什么时候向生产者发送ack


确保follower和leader同步完成,leader在发送ack给生产者,这样才能确保leader挂掉之后,能再follower中选举出新的leader后,数据不会丢失


那多少个follower同步完成后发送ack


方案1:半数已经完成同步,就发送ack


方案2:全部完成同步,才发送ack(kafka采用这种方式)


采用第二种方案后,设想以下场景,leader收到数据,所有的follower都开始同步数据,但是有一个follower因为某种故障,一直无法完成同步,那leader就要一直等下,直到他同步完成,才能发送ack,这样就非常影响效率,这个问题怎么解决?



网络异常,图片无法展示
|



Leader维护了一个动态的ISR列表(同步副本的作用),只需要这个列表的中的follower和leader同步;当ISR中的follower完成数据的同步之后,leader就会给生产者发送ack,如果follower长时间未向leader同步数据,则该follower将被剔除ISR,这个时间阈值也是自定义的;同样leader故障后,就会从ISR中选举新的leader


怎么选择ISR的节点呢?


首先通信的时间要快,要和leader要可以很快的完成通信,这个时间默认是10s


然后就看leader数据差距,消息条数默认是10000条(后面版本被移除)


为什么移除:因为kafka发送消息是批量发送的,所以会一瞬间leader接受完成,但是follower还没有拉取,所以会频繁的踢出加入ISR,这个数据会保存到zk和内存中,所以会频繁的更新zk和内存。



但是对于某些不太重要的数据,对数据的可靠性要求不是很高,能够容忍数据的少量丢失,所以没必要等ISR中的follower全部接受成功


所以kafka为用户提供了三种可靠性级别,用户可以根据可靠性和延迟进行权衡,这个设置在kafka的生成中设置:acks参数设置


A、acks为0


生产者不等ack,只管往topic丢数据就可以了,这个丢数据的概率非常高


B、ack为1


Leader落盘后就会返回ack,会有数据丢失的现象,如果leader在同步完成后出现故障,则会出现数据丢失


C、ack为-1(all)


Leader和follower(ISR)落盘才会返回ack,会有数据重复现象,如果在leader已经写完成,且follower同步完成,但是在返回ack的出现故障,则会出现数据重复现象;极限情况下,这个也会有数据丢失的情况,比如follower和leader通信都很慢,所以ISR中只有一个leader节点,这个时候,leader完成落盘,就会返回ack,如果此时leader故障后,就会导致丢失数据



3.3 Kafka如何保证消费数据的一致性?

通过HW来保证



网络异常,图片无法展示
|




LEO:指每个follower的最大的offset


HW(高水位):指消费者能见到的最大的offset,LSR队列中最小的LEO,也就是说消费者只能看到1~6的数据,后面的数据看不到,也消费不了


避免leader挂掉后,比如当前消费者消费8这条数据后,leader挂   了,此时比如f2成为leader,f2根本就没有9这条数据,那么消费者就会报错,所以设计了HW这个参数,只暴露最少的数据给消费者,避免上面的问题



3.3.1、HW保证数据存储的一致性


A、Follower故障


Follower发生故障后会被临时提出LSR,待该follower恢复后,follower会读取本地的磁盘记录的上次的HW,并将该log文件高于HW的部分截取掉,从HW开始想leader进行同步,等该follower的LEO大于等于该Partition的hw,即follower追上leader后,就可以重新加入LSR


B、Leader故障


Leader发生故障后,会从ISR中选出一个新的leader,之后,为了保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于hw的部分截掉(新leader自己不会截掉),然后从新的leader同步数据


注意:这个是为了保证多个副本间的数据存储的一致性,并不能保证数据不丢失或者不重复



3.3.2精准一次(幂等性),保证数据不重复



Ack设置为-1,则可以保证数据不丢失,但是会出现数据重复(at least once)


Ack设置为0,则可以保证数据不重复,但是不能保证数据不丢失(at most once)


但是如果鱼和熊掌兼得,该怎么办?这个时候就就引入了Exactl once(精准一次)



在0.11版本后,引入幂等性解决kakfa集群内部的数据重复,在0.11版本之前,在消费者处自己做处理


如果启用了幂等性,则ack默认就是-1,kafka就会为每个生产者分配一个pid,并未每条消息分配seqnumber,如果pid、partition、seqnumber三者一样,则kafka认为是重复数据,就不会落盘保存;但是如果生产者挂掉后,也会出现有数据重复的现象;所以幂等性解决在单次会话的单个分区的数据重复,但是在分区间或者跨会话的是数据重复的是无法解决的


3.4 kafka的消费者


3.4.1 消费方式


消息队列有两种消费消息的方式,push(微信公众号)、pull(kafka),push模式很难适应消费速率不同的消费者,因为消费发送速率是由broker决定的,他的目标是尽可能以最快的的速度传递消息,但是这样很容易造成消费者来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。而pull的方式可以消费者的消费能力以适当的速率消费消息


Pull的模式不足之处是如果kafka没有数据,消费者可能会陷入死循环,一直返回空数据,针对这一点,kafka的消费者在消费数据时候回传递一个timeout参数,如果当时没有数据可供消费,消费者会等待一段时间在返回


3.4.2 分区分配策略


一个消费者组有多个消费者,一个topic有多个partition。所以必然会涉及到partition的分配问题,即确定哪个partition由哪个消费者来消费


Kafka提供两种方式,一种是轮询(RountRobin)对于topic组生效,一种是(Range)对于单个topic生效



轮训:前置条件是需要一个消费者里的消费者订阅的是相同的topic。不然就会出现问题;非默认的的方式



同一个消费者组里的消费者不能同时消费同一个分区


比如三个消费者消费一个topic的9个分区


网络异常,图片无法展示
|



网络异常,图片无法展示
|





如果一个消费者组里有2个消费者,这个消费者组里同时消费2个topic,每个topic又有三个partition


首先会把2个topic当做一个主题,然后根据topic和partition做hash,然后在按照hash排序。然后轮训分配给一个消费者组中的2个消费者



如果是下面这样的方式订阅的呢?


比如有3个topic,每个topic有3个partition,一个消费者组中有2个消费者。消费者1订阅topic1和topic2,消费者2订阅topic2和topic3,那么这样的场景,使用轮训的方式订阅topic就会有问题



如果是下面这种方式订阅呢


比如有2个topic,每个topic有3个partition,一个消费者组 有2个消费者,消费者1订阅topic1,消费者2订阅topic2,这样使用轮训的方式订阅topic也会有问题



所以我们一直强调,使用轮训的方式订阅topic的前提是一个消费者组中的所有消费者订阅的主题是一样的;


所以轮训的方式不是kafka默认的方式


Range:是按照单个topic来划分的,默认的分配方式


网络异常,图片无法展示
|


网络异常,图片无法展示
|







Range的问题会出现消费者数据不均衡的问题


比如下面的例子,一个消费者组订阅了2个topic,就会出现消费者1消费4个partition,而另外一个消费者只消费2个partition


网络异常,图片无法展示
|




分区策略什么时候会触发呢?当消费者组里的消费者个数变化的时候,会触发分区策略调整,比如消费者里增加消费者,或者减少消费者


3.4.3 offset的维护


由于消费者在消费过程中可能会出现断电宕机等故障,消费者恢复后,需要从故障前的位置继续消费,所以消费者需要实施记录自己消费哪个offset,以便故障恢复后继续消费


Offset保存的位置有2个,一个zk,一个是kafka


首先看下offset保存到zk


由消费者组、topic、partition三个元素确定唯一的offset



所以消费者组中的某个消费者挂掉之后,或者的消费者还是可以拿到这个offset的


网络异常,图片无法展示
|




Controller这个节点和zk通信,同步数据,这个节点就是谁先起来,谁就先注册controller,谁就是controller。其他节点和controller信息保持同步



3.4.5、消费者组的案例


修改消费者组id

网络异常,图片无法展示
|





启动一个消费者发送3条数据



网络异常,图片无法展示
|



指定消费者组启动消费者,启动三个消费者,可以看到每个消费者消费了一条数据


网络异常,图片无法展示
|

 

 

网络异常,图片无法展示
|

 

 

网络异常,图片无法展示
|



在演示下不同组可以消费同一个topic的,我们看到2个消费者的消费者都消费到同一条数据


再次启动一个消费者,这个消费者属于另外一个消费者组




网络异常,图片无法展示
|

 

 

网络异常,图片无法展示
|


四、Kafka的高效读写机制

4.1、分布式部署


多节点并行操作



4.2、顺序写磁盘


Kafka的producer生产数据,要写入到log文件中,写的过程中一直追加到文件末尾,为顺序写,官网有数据表明。同样的磁盘,顺序写能到600M/S,而随机写只有100K/S。这与磁盘的机械结构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间


4.3、零复制技术


正常情况下,先把数据读到内核空间,在从内核空间把数据读到用户空间,然后在调操作系统的io接口写到内核空间,最终在写到硬盘中



网络异常,图片无法展示
|



Kafka是这样做的,直接在内核空间流转io流,所以kafka的性能非常高


网络异常,图片无法展示
|






五、 zookeeper在kafka中的作用

Kafka集群中有一个broker会被选举为controller,负责管理集群broker的上下线,所有的topic的分区副本分配和leader选举等工作


相关文章
|
2月前
|
消息中间件 存储 缓存
Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
【2月更文挑战第20天】Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
167 2
|
14天前
|
消息中间件 存储 Java
全网把Kafka概念讲的最透彻的文章,别无二家
消息队列老大哥Kafka在官网的介绍是这么说的,真是霸气:全球财富前100强公司有超过80%信任并使用Kafka。Kafka目前在GitHub目前也已经有star数27.6k、fork数13.6k。大家好,我是南哥。一个对Java程序员进阶成长颇有研究的人,今天我们开启新的一篇Java进阶指南,本期的对象是Kafka。Kafka历史Star趋势图本文收录在我开源的《Java学习面试指南》中,一份涵盖Java程序员所需掌握核心知识、面试重点的Java指南。希望收到大家的 ⭐ Star ⭐支持。
全网把Kafka概念讲的最透彻的文章,别无二家
|
26天前
|
消息中间件 大数据 Kafka
高效处理大数据:Kafka的13个核心概念详解
大家好,我是小米!今天我将为大家深入解析Kafka的核心概念,包括消息、批次、主题、分区、副本、生产者、消费者、消费组等内容。通过这篇文章,你将全面了解Kafka的工作机制和应用场景,为你的大数据处理提供有力支持。准备好了吗?让我们开始吧!
45 4
|
2月前
|
消息中间件 运维 负载均衡
【Kakfa】Kafka 中 AR、ISR、OSR 三者的概念
【4月更文挑战第11天】【Kakfa】Kafka 中 AR、ISR、OSR 三者的概念
|
2月前
|
消息中间件 存储 Kafka
【Kafka】Replica、Leader 和 Follower 三者的概念分析
【4月更文挑战第11天】【Kafka】Replica、Leader 和 Follower 三者的概念分析
|
11月前
|
消息中间件 存储 Kafka
Kafka架构及基本概念
刚开始了解Kafka时对其中多个名词表示懵逼,broker是啥?咋还有分区?有没有跟和我一样有很多???本文就我对Kafka的理解梳理各个角色以及功能,欢迎大家一起来沟通交流
101 0
|
2月前
|
消息中间件 存储 Java
Kafka基本概念与应用场景
Apache Kafka是一种分布式的、基于发布/订阅的消息系统,由Scala语言编写而成。它具备快速、可扩展、可持久化的特点。Kafka最初由LinkedIn开发,并于2011年初开源, 2012年10月从Apache孵化器毕业,成为Apache基金会的顶级项目。
|
2月前
|
消息中间件 Kafka
Kafka - 深入了解Kafka基础架构:Kafka的基本概念
Kafka - 深入了解Kafka基础架构:Kafka的基本概念
45 0
|
11月前
|
消息中间件 存储 监控
深入浅出:理解Kafka的核心概念与架构
深入浅出:理解Kafka的核心概念与架构
418 0
|
12月前
|
消息中间件 存储 Kafka
Kafka 实战开篇-讲解架构模型、基础概念以及集群搭建(下)
Kafka 实战开篇-讲解架构模型、基础概念以及集群搭建(下)
161 0