kafka源码学习(二)服务端源码

写在前面

本篇主要说明了源码学习过程中服务端的相关知识点。通过本章节的学习,
1、对服务端的网络、存储、副本同步、集群管理相关的细节又回顾了一篇,比之前死记硬背好很多。
2、感觉很多架构的设计还是来源于实际需求,当然kafka的核心点就是:异步、削峰、解耦。

注意:
1、Kafka网络设计,理解超高并发的网络设计
2、juc,跳表,log【存储】,内存映射写稀松索引,时间轮机制,后续需要持续跟进。

1、服务端—网络

参考链接:深度剖析:Kafka 请求是如何处理? 看完这篇文章彻底懂了!
Kafka 服务端的网络设计通常采用三层架构,它包括以下三层:
网络层:Acceptor负责接受来自客户端的连接请求,并创建对应的网络连接。
请求层:Processor 负责处理来自客户端的请求,并将其传递给合适的 Handler 进行处理。它处于请求处理的中间层,负责请求的分发和路由。
处理层:Handler 接收到 Processor 分发的请求后,负责解析请求、执行相应的操作,并生成响应返回给客户端
在这里插入图片描述

1.1、服务端acceptor线程启动

  1. 入口函数:main;完成参数设置,调用启动函数
    包名kafka.Kafka
    在这里插入图片描述

  2. kafka服务端启动的核心方法在startup()中,Start up API for bringing up a single instance of the Kafka server.,启动NIO服务端
    kafka.server.KafkaServer
    在这里插入图片描述

  3. SocketServer启动后,创建acceptor线程
    位置1:endpoints取决于配置kafka的时候,在config/server.properties里面的配置个数,例如:kafka1:9092,一般设置一个服务实例就可以
    位置2:创建一个acceptor对象,继承AbstractServerThread,Acceptor 是整个网络通信的入口点之一,负责处理客户端的连接请求,从而允许客户端与 Kafka 集群进行通信
    位置3:Utils是一个工具类,里面由一个newThead方法,帮我们启动线程使用
    在这里插入图片描述

  4. run()方法中,执行逻辑就像JavaNIO中服务端轮询查看是否有请求接入
    位置1:ServerChannel向Selector注册一个OP_ACCEPT事件,表示Selector会检查ServerChannel中是否有新的请求到达
    位置2、位置3:Selector遍历注册的Key,如果key=OP_ACCEPT,调用accept()接收请求
    位置4:创建SocketChannel,以轮询的方式放入到不同的Processor线程
    在这里插入图片描述

1.2、服务端Processor线程

1.2.1、Processor线程启动

  1. 创建位置和Acceptor一样,不过这里并没有启动Processor线程
    processorBeginIndex:0
    numProcessorThreads:默认值是3,由参数num.network.threads控制
    在这里插入图片描述
  2. Acceptor构造的时候,会在其主构造函数中执行(Scala),这个时候Processor线程启动
    在这里插入图片描述

1.2.2、Processor如何接收请求

在Processor的run()方法,

  1. configureNewConnections()
    Register any new connections that have been queued up
    位置1:不断轮询,获取队列里面的SocketChannel
    位置2:获取配置信息,产生ConnectionId
    位置3:向Selector中注册这个SocketChannel,这里的Selector是kafka自己封装的一个KSelector,和Acceptor中的Selector不是一个
    import org.apache.kafka.common.network.{ChannelBuilders, KafkaChannel, LoginType, Mode, Selector => KSelector}(对生产者代码封装的Selector进行复用)
    在这里插入图片描述

  2. 向KSelector中注册一个OP_READ的事件,这个时候就可以读取来自客户端发送过来的请求;此外,封装了一个KafkaChannel,放入到
    在这里插入图片描述

  3. poll():根据之前对Producer源码剖析,读取和发送数据的底代码都是在这个方法里面完成,具体剖析过程略;将数据放入stagedReceives(尚未处理的数据)

1.2.3、Processor如何处理stagedReceives的请求

在Processor的run()方法,

  1. processCompletedReceives(),处理接收标记完成的数据,
    位置1:遍历每一个请求
    位置2:对于获取到的请求按照协议进行解析,解析出来就是一个个Request
    位置3:本质上调用requestQueue.put(request),把这个请求放入RequestQueue
    通过参数queued.max.requests设置,RequestChannel在SocketServer初始化的时候创建
    位置4:底层代码,移除OP_READ事件,因为接下来要写数据在这里插入图片描述

1.2.4、队列里面的Request什么时候被处理?

  1. KafkaRequestHandlerPool处理请求队列里面的请求

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值