KAFKA学习记录

                                               KAFKA学习记录

我学习kafka主要是通过《kafka权威指南》这本书,以及网上的一些博客,看书遇到不明白的地方就去网上找一些资料,包括以下几个博客

美团的一个技术写的:https://blog.csdn.net/lizhitao/article/details/39499283

看书的过程还是需要做一些笔记的,不然过一段时间就忘记了,先来一张思维导图,后续还会补充

概念:

    Broker:一个独立的Kafka服务器被称为broker,broker接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存,broker为消费者提供服务,对读取分区的请求做出响应,返回已经提交到磁盘的消息。

分区首领:每个集群都有一个broker同时充当了集群控制器的角色(自动从集群的活跃成员选举出来)。控制器负责管理工作,包括将分区分配给broker和监控broker,在集群中一个分区从属于一个broker,该broker被称为分区的首领,一个分区可以分配给多个broker,这个时候就会发生分区复制

保留消息:(在一定期限内)是kafka的一个重要特性,Kafka broker默认的消息保留策略:保留一段时间(比如7天)要么保留到一定大小的字节数(比如1GB)

主题默认配置:

num.partitions分区数量,默认为1

log.retention.hours:决定数据可以保留多久(作用于日志片段)

log.retention.bytes:通过保留的消息字节数判断消息是否过期,(作用于每个分区)

log.segment.bytes

 

生产者

发送消息3种方式

发送并忘记:把消息发送给生产者,并不关心是否正常到达,生产者可以自动尝试重发

同步发送:使用send发送消息,返回一个Future对象,调用get方法进行等待,就可以知道消息是否发送成功

异步发送:调用send方法,并指定一个回调函数,服务器在返回响应时调用该函数

生产者配置:

acks:指定必须要有多个分区副本收到消息,生产者才会认为消息写入是成功的

acks=0,不等待服务器响应,因为生产者不需要等待服务器的响应,所以它可以以网络能够支持的最大速度发送消息,从而达到很高的吞吐量,

acks=1只要集群的首领收到消息

acks=all,只有当所有参与复制的节点全部收到消息时,生产者才会受到一个来自服务器的成功响应

buffer.memory:该参数用来设置生产者内存缓冲区的大小,生产者用它缓冲要发送到服务器的消息,如果应用程序发送消息的速度超过发送到服务器的速度,会导致生产者空间不足,这个时候send方法要么阻塞,要么抛出异常,取决于如何设置block.on.buffer.full参数

retries消息重发次数

batch.size:该参数指定了一个批次可以使用的内存大小,按照字节数计算

linger.ms:该参数指定了生产者在发送批次之前等待更多消息加入批次的时间,kafka producer会在批次填满或者linger.ms达到上限时把批次发送出去。

生产者分区策略:

key为null的时候,记录被随机发送到主题内各个可用的分区上,分区其使用轮询算法将消息均衡的分布到各个分区上

key不为空,并且使用默认分区器,kafka会对健进行散列,然后根据散列值把消息映射到特定的分区上

 

消费者:

消费者的配置:

fetch.min.bytes:指定消费者从服务器获取记录的最小字节数

fetch.max.wait.ms:用于指定broker的等待时间

max.partition.fetch.bytes:指定了服务器从每个分区返回给消费者的最大字节数,max.partition.fetch.bytes的值必须比broker能够接收的最大消息的字节数大,否则消费者可能无法读取这些消息

session.timeout.ms

该属性指定了消费者在被认为死亡之前可以与服务器断开连接的时间,默认是3s,如果消费者没有在session.timeout.ms指定的时间内发送心跳给群组协调器,就被认为已经死亡

heartbeat.interval.ms:指定了poll()方法想协调器发送心跳的频率,heartbeat.interval.ms必须比session.timeout.ms小

auto.offset.reset:该属性指定了在读取一个没有偏移量的分区或者偏移量无效的情况下,该做如何处理,默认值是lastest意思是说在偏移量无效的情况下,消费者将从最新的记录开始读取数据,另一个值是earliest,意思是说,在偏移量无效的情况下,消费者将从起始位置读取分区的记录

enable.auto.commit:指定了消费者是否自动提交偏移量,默认true,如果设置true,可以通过配置auto.commit.interval.ms属性来控制提交的频率

partition.assignment.strategy:分区策略 Range分区策略:把主题内的若干个连续的分区分配给消费者 分区策略 RoundRobin,该策略把主题的所有分区逐个分配给消费者

max.poll.records:该属性用于控制单次调用call方法能够返回的记录数量

 

再均衡监听器:

从特定偏移量开始处理记录:

每一个消费者从属于一个消费者群组,多个消费者群组可以同时读取一个主题的数据

再均衡:分区的所有权从一个消费者转移到另一个消费者,它为消费者群组带来了高可用性和伸缩性

消费者通过向被指派为群组协调器的broker发送心跳来维持它们和群组的从属关系以及他们对分区的所有权关系,只要消费者以正常的时间时间间隔发送心跳,就被认为是活跃的。

提交和偏移量:

提交:更新分区当前位置的操作

如何提交偏移量:消费者往一个叫做_consumer_offser的特殊主题发送消息,消息里包含每个分区的偏移量,当触发在均衡的时候,每个消费者可能分配到新的分区,而不是之前处理的那个,为了能继续之前的工作,消费者需要读取每个分区最后一次提交的偏移量,然后从偏移量指定的地方继续处理

提交偏移量的方式:

自动提交:消费者自动提交偏移量,设置enable.auto.commit为tue,那么每过5s,消费者会自动把从poll()方法接收到的最大偏移量提交上去,提交时间间隔由auto.commit.interval.ms控制,默认值是5s

自动提交会导致重复消费问题,在使用自动提交时,每次调用轮询方法都会把上一次调用返回的偏移量提交上去

提交当前偏移量:开发者在必要的时候提交当前偏移量,而不是基于时间间隔,设置auto.commit.offset设为false,使用commitSync()提交偏移量,这个api会提交由poll()方法返回的最新偏移量,提交成功后马上返回(在broker对提交请求作出回应之前,应用程序会一直阻塞,这样会限制程序的吞吐量,可以通过降低提交频率来提升吞吐量,但如果发生了再均衡,会增加重复i消息的数量)

异步提交:使用commitAsync()异步提交偏移量,只管发送请求,无须等待broker的响应,不会进行重试, 对于异步提交,由于不会进行失败重试,当消费者异常关闭或者触发了再均衡前,如果偏移量还未提交就会造成偏移量丢失。commitAsync()提交也支持回调,在broker作出反应时会执行回调

重试异步提交:可以使用一个单调递增的序列号来维持异步提交的顺序,在每次提交偏移量之后或者在回调里提交偏移量时递增序列号,在进行重试时,先检查回调的序列号和即将提交的偏移量是否相等,如果相等,说明没有新的提交,那么可以安全的重试,如果序列号比较大,说明一个新的提交已经发送出去了,应该停止重试

异步+同步 组合的方式提交偏移量: 针对异步提交偏移量丢失的问题,通过对消费者进行异步批次提交并且在关闭时同步提交的方式,这样即使上一次的异步提交失败,通过同步提交还能够进行补救,同步会一直重试,直到提交成功。

提交特定的偏移量:可以提交指定分区和偏移量

深入kafka

kafka如何进行复制?

kafka如何处理来自生产者和消费者的请求?

kafka的存储细节,比如文件格式和索引?

 

复制:kafka的分区副本分为leader副本和follower副本,由leader 副本处理所有来自生产者的请求和消费者的请求,首领以外的副本都是follower副本,他们唯一的任务就是从首领那里复制消息,保持与首领一致的状态,如果首领发生奔溃,其中一个跟随者会被提升为新首领。

 

存储细节:https://www.cnblogs.com/wuzhenzhao/p/10143946.html    消息的文件存储机制

https://mp.weixin.qq.com/s/kZcHe6FSgd5fKidGlX9i3Q 美团的

集群的成员关系:

kafka使用zookeeper来维护集群成员的信息,每个broker都有一个唯一的标识符,在broker启动的时候,通过创建临时节点把自己的id注册到Zookeeper,Kafka组件订阅Zookeeper的/broker/ids路径,当有broker加入集群或者退出集群时,这些组件就可以获得通知,

 

控制器:控制器其实就是一个broker,它除了具有一般broker的功能以外,还负责分区首领的选举,集群里第一个启动的broker通过在Zookeeper里创建一个临时节点/controller让自己成为控制器。其他broker在启动时也会尝试创建这个节点,不过会收到一个“节点已存在”的异常,也就是说集群已经有一个controller,其他节点在控制器节点上创建zookeeper watch对象,这样就可以收到这个节点的变更通知,这种方式可以确保这个集群里只有一个控制器存在

Kafka使用Zookeeper的临时节点来选举控制器,并在节点加入集群或者退出集群时通知控制器,控制器负责在节点加入或离开集群时进行分区首领选举,控制器使用epoch来避免脑裂。

复制:kafka使用主题来组织数据,每个主题被分为若干分区,每个分区有多个副本,那些副本被保存在broker上,每个broker可以保存成百上千个属于不同主题和分区的副本。

首领副本:每个分区都有一个首领副本,为了保证一致性,所有生产者请求和消费者请求都会经过这个副本

跟随者副本:首领以外的副本都是跟随者副本,跟随者副本不处理来自客户端的请求,它们唯一的任务就是从首领那里复制信息,保持与首领一致的状态,如果首领发生奔溃,其中的一个副本就会被提升为新首领

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章