一.请求/响应
- 所有的请求都是通过 TCP 网络以Socket 的方式进行通讯的。
Apache Kafka自定义的请求协议:
- PRODUCE请求是用于生产消息的
- FETCH请求是用于消费消息的
- METADATA请求适用于请求Kafka集群元数据信息的。
所有的请求都是通过TCP网络以Socket的方式通讯的。
二.Reactor模式
- Reactor模式:事件驱动架构的实现方式,适合应用于处理多个客户端并发向服务器发送请求的场景。
Acceptor线程只是用于请求分发,不涉及具体的逻辑处理,非常轻量级,因此有很高的吞吐量表现。
Kafka 实例图:
网络线程池:
- kafka提供Broker端参数num.network.threads用于调整该网络线程池的线程数
- 默认值是3,表示每台Broker启动时会创建3个网络线程,专门处理客户端发送的请求。
轮询机制:
- Accept线程采用轮询的方式将入战请求公平的分发到所有网络线程中
- 实现公平调度
三.异步线程池处理
- 当网络线程池拿到请求后,他不会自己处理,而是将请求放入一个共享请求队列
- Broker端还有IO线程池,负责从该队列中取出请求,执行真正的处理
- 如果是PRODUCER生产请求,则将消息写入到底层的磁盘日志中
- 如果FETCH请求,则从磁盘活也页缓存中读取消息。
num.io.threads参数
- IO线程池处中的线程才是执行请求逻辑的线程
- Broker端参数num.io.threads控制了这个线程池中的线程数
- 参数默认值是8,表示每台Broker启动后自动创建8个IO线程处理请求
请求队列和响应队列的差别:
- 请求队列是所有网络线程共享的,响应队列则是每个网络线程专属的
- Dispatcher 只是用于请求分发而不负责响应回传,只能让每个网络线程自己发送 Response 给客户端
四.Purgatory组件
- kafka中著名的"炼狱"组件
- 用于缓存延时请求(Delayed Request),缓存一时为满足条件不能立即处理的请求。
- 当请求不能立即处理时,他就会暂存在Purgatory中。
- 等满足条件时,IO线程会继续处理该请求,将Response放入到网络线程的响应队列中。
例子:
- 设置acks=all的PROUCE请求,一旦设置acks=all,那么请求就必须等待ISR中所有副本都接收了消息才能返回
- 此时处理该请求的IO线程就必须等待其他Broker的写入结果。
控制类请求和数据类请求分离
kafka请求类型:
- 数据类请求:客户端发送PRODUCE请求和FETCH请求
- 控制类请求:负责更新LEADER副本,FOLLOWER副本以及ISR集合的LeaderAndIsr请求 负责勒令副本下线的StopReplica请求