深入kafka

(一)kafka集群

1、集群成员关系

(1)broker如何将自己注册到zookeeper上:broker启动的时候通过在zookeeper上创建临时节点的方式将自己的brokerid(唯一)注册到zookeeper上

(2)zookeeper用于注册broker的路径:/brokers/ids

(3)broker取消注册:kafka组件订阅以上路径,当某个broker和zookeeper断开连接导致临时节点被删除时,其他broker可以收到通知。

2、控制器

(1)什么是控制器:一个特殊的broker

(2)控制器的作用:负责分区首领(如果一个分区在一个broker上,那么这个broker称为这个分区的首领)的选举。

(3)控制器是怎么产生的:集群里第一个启动的broker在对应zookeeper上创建一个临时节点/controller让自己成为控制器,其他broker再去创建的时候,收到节点已存在的反馈,保证集群中只有一个broker是控制器。

(4)控制器宕机怎么办:控制器被关闭后,对应的临时节点删除。其他broker收到通知后尝试创建临时节点,成功创建的节点成为控制器

(5)控制器是如何进行分区选举的呢:kafka会在zk上针对每个topic维护一个ISR集合(in-sync-replica同步副本集)。

a、某个分区的leader不可用,控制器从isr集合中选择一个新的副本作为新的leader。再通知leader及其他相关broker,告知其读取数据或者从何处进行进行数据同步

(6)某一个topic分区的分配:控制器从所有broker中随机选择一个作为起点,然后顺位分配。新增partition也是控制器利用这种算法进行重新分配

(二)kafka如何进行复制

1、副本分类:

(1)首领副本:处理生产者和消费者请求的副本,为保证一致性,所有请求都会经过这个副本

    a、当前首领:当前的首领

    b、首选首领:创建主题时选定的首领

(2)跟随者副本:首领副本以外的副本成为跟随者副本。跟随者副本不关心请求来源,只是为保证自己和首领副本的一致性不断从首领副本同步消息

2、工作模式:

(1)跟随者副本从首领副本同步消息,同步方式和消费者消费消息完全一致。跟随者副本告知消费的偏移量和消费数据量,首领副本将消息返回给跟随者副本。

(2)首领副本通过查看每个跟随者请求的最新偏移量,首领就会知道跟随者的进度。通过replica.lag.time.max.ms配置最长不从首领同步数据的时间。超过这个时间或者每次请求的偏移量不变则认为该跟随者副本是不同步副本,反之则是同步副本。

(3)如果首领副本失效,只有同步副本才有可能成为下一个首领副本

(三)kafka如何处理生产者和消费者的请求

1、kafka定义的基于TCP的二进制传输协议:

(1)标准消息头:

2、处理请求

(1)请求来源:客户端、分区副本、控制器

(2)kafka处理请求流程

    a、Processor线程:网络线程,接受来自客户端的请求放入队列并从响应队列获取响应返回给请求发送者

    b、IO线程:负责处理真正的消息写入和读取

(3)请求必须发送给分区首领,那么如何确定分区的首领在哪里呢----元数据请求

    a、客户端向集群发送元数据请求,元数据中包含了对应主题所包含的分区,每个分区都有哪些副本以及哪个副本是首领。(元数据请求可以发送给任意一个broker,因为broker都缓存了这些信息)

    b、一般客户端会缓存这些信息,然后隔一段时间从broker拉取。metadata.max.age.ms参数指定metadata的刷新间隔

(4)客户端发送请求的过程

注:如果新加入了broker或者其他原因导致分区副本重新分配,客户端收到“非首领”的错误,将会重新刷新metadata信息

(5)处理生产者具体请求

    a、消息验证:发送数据的用户是否有主题写权限,acks值是否有效,如果是acks=all,是否有足够的同步副本保证消息被完全写入

    b、将消息写入文件系统缓存,并不是马上被写入磁盘。并不保证何时被写入磁盘。首领写入消息后,检查acks的值,如果是0或者1直接返回,如果是all,直到所有副本都复制了消息,响应才会返回

(6)处理消费者具体请求

    a、消息验证:验证想要获取的偏移量在指定的分区是否存在

    b、从文件系统缓存读取消息到客户端。(不需要管理本地缓存,不需要进行消息的复制)

    c、只有被所有复制者同步的消息可以被消费者读取,如下图所示:

(四)kafka存储

前言:kafka基本存储单元是分区,一个分区无法再在各个broker之间分配,也无法分配到同一个broker的不同磁盘目录上

1、分区分配

(1)目标:

    a、broker之间分区分配平均;

    b、确保每个分区的副本在不同的broker上

(2)分配方法:

    a、随机选择一个broker(假设是4),然后使用轮询的方式给每个broker分区确定首领分区的位置。即:首领分区0在broker4,首领分区1在broker5,首领分区2在broker0(只有6个broker),以此类推。

    b、从首领分区0开始,依次分配跟随者副本。如果分区0的首领在broker4,那么它的每一个跟随者副本在broker5,以此类推。

    c、如果配置了机架信息(如broker0/1/2在一台机架上),那么分配顺序就会变成0、3、1、4、2、5。

    d、为分区选择合适的磁盘目录,计算每个目录上分区的数量,选择分区最少的目录,将分区添加到该目录下面。(不会考虑具体目录的负载)

2、文件管理

(1)kafka为每个主题的数据保留一定时间(可配置),不会一直保留,也不会等到全部被消费

(2)考虑到一个大文件读写数据很费时,将分区分成若干个片段(默认一个片段包含1G或者一周的数据,以较小的那个为准)。写入文件时,如果片段达到上限,则关闭当前片段,打开一个新的文件。

注:当前正在写入的片段成为活跃片段,活跃片段永远不会被删除。对于不活跃的片段,broker会为其打开一个文件句柄。

3、文件格式:

    键,值,偏移量,消息大小,消息格式版本号,压缩算法和时间戳。批量发送的消息格式如图(批量发送的消息中每个消息都有自己的偏移量):

4、索引

(1)目的:为了能够快速读取任意偏移量的数据,kafka为每个分区维护了一个索引。

(2)工作模式:将偏移量映射到片段文件和偏移量在文件中的位置。

(3)保障:如果索引出现损坏,kafka会通过重新读取这些消息的方式重新录制偏移量和位置来重新生成索引。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。