• 明翼
    2019-07-28
    有两种方法:1 是直接替换数据处理队列中的最前面的数据进行处理,处理完控制队列,再将这个消息插队到队头;2 双队列设计,不过双队列,如果先处理控制消息,如果一直来控制消息,数据队列的消息岂不会被延迟很大;

    关于复制一套,我看了下面评论,我和部分网友的理解不一样,我觉得是复制一套网络线程持+中间队列+IO线程池;也就是有两个网络线程池,+2个中间队列,和2套IO线程持;

    网络线程池作用将数据分发到中间队列,和接受IO线程池的处理结果回复给客户端。我理解为什么要加这个中间队列是为了将网络处理的线程数和IO处理的线程数解耦,达到高性能和资源少占用的目的。
    展开

    作者回复: 我觉得不错:)

    
     5
  • cricket1981
    2019-07-27
    双队列设计,分别存放数据类和控制类请求,每次先处理完所有控制类请求再处理数据类请求。
     1
     5
  • 拾光
    2019-12-03
    为什么不直接将Acceptor线程收到的请求存入共享队列,而要引入网络线程池来存?

    作者回复: 我认为就是单纯地想要在做一层生产者-消费者分离

    
     3
  • ban
    2019-07-28
    老师,社区完全拷贝了这张图中的一套组件,实现了两类请求的分离。也就是说,Kafka Broker 启动后,会在后台分别创建网络线程池和 IO 线程池,它们分别处理数据类请求和控制类请求。

    上面这段话不太懂,意思是说:分别建立两套组件(A套 网络线程池IO线程池:负责处理数据类请求)、(B套 网络线程池IO线程池:负责处理控制类请求),这样理解对吗?

    作者回复: 嗯嗯,差不多是这个意思

    
     3
  • Sunney
    2019-07-29
    老师您好,这两天做项目遇到一个问题想咨询一下,对于网络摄像头的视频流数据和抓拍到的照片数据,kafka应该如何传输呢?

    作者回复: 相同的方法,都要传输字节数组。你需要找到合适的方法把你的视频流数据或照片编码成字节序列。当然Kafka其实并不适合传输特别大的消息,因此你可以评估一下是否真的需求传视频本身?

     3
     2
  • 电光火石
    2019-07-27
    优先级队列方案,可以开两个队列,分别处理,前面的监听端口不需要重新构建,只是后面的处理线程不同即可。
    另外,想问一下:
    1. 为什么当时kafka做的时候,没有考虑使用netty作为通信框架?
    2. 对IO这一块的处理比较感兴趣,老师可以介绍一下broker的入口类吗,想去看一下源码
    谢谢了!

    作者回复: 1. Kafka社区当初主要是为了jar依赖的问题而选择不使用netty,转而使用Java NIO的
    2. Broker入口类是kafka.server.KafkaServer.scala

    
     2
  • lmtoo
    2019-07-27
    小结部分的图片把数据类请求放到了网络线程池中,而控制类请求放到了IO线程池,弄反了吧;我觉得社区的决定是正确的,这两类请求分离之后,职责更明确了
     2
     2
  • Riordon
    2019-07-27
    数据类请求和控制类请求的分离,我理解的是多开一套端口,实现一套网络线程池+IO线程池?不对吗?
    Acceptor线程:公平转发请求到网络线程
    网络线程池:将请求放入共享队列
    IO线程池:从共享队列取出请求,执行真正的IO
    
     2
  • 注定非凡
    2019-11-07
    1 Apache Kafka 自己定义了组请求协议,用于实现各种交互操作。常见有:
        a. PRODUCE 请求用于生产消息
        b. FETCH请求是用于消费消息
        c. METADATA请求是用于请求Kafka集群元数据信息。
        
        Kafka定义了很多类似的请求格式,所有的请求都是通过TCP网络以Socket的方式进行通讯的。

    2 KaKfa Broker端处理请求的全流程
        A :常用请求处理方案
            a:顺序处理请求
            实现方法简答,但吞吐量太差是致命缺陷。因为是顺序处理,每个请求都必须等待前一个请求处理完毕才能得到处理。这只适用于请求发送非常不频繁的系统。
            b:每个请求使用单独线程处理
            它是完全异步的,每个请求的处理都创建单独线程处理,但缺陷明显,为每个请求都创建线程开销极大,某些场景甚至会压垮整个服务。

        B :Kafka的方案:使用Reactor模式
            a:Reactor模式是JUC包作者的作品
            b:Reactor模式是事件驱动架构的一种实现方式,特别适应用于处理多个客户端并发向服务端发送请求的场景。
        
    3 Kafka的请求处理方式
        A :Reactor模式中,多个客户端发送请求到Reactor。Reactor有个请求分发线程Dispatcher,它会将不同的请求下发到多个工作线程中处理。
            Acceptor线程只用于请求分发,不涉及具体逻辑处理,因此有很高的吞吐量。而工作线程可以根据实际业务处理需要任意增减,从而动态调节系统负载能力。
        
        B :kakfa中,Broker端有个SocketServer组件,类似于Reactor模式中的Dispatcher,他也有对应的Acceptor线程和一个工作线程池,在kafka中,被称为网络线程池。
            Broker端参数num.network.threads,用于调整该网络线程池的线程数,默认为4,表示每台Broker启动时,会创建3个网络线程,专门处理客户端发送的请求。

        C :Acceptor线程采用轮询的方式将入站请求公平的发送到所有网络线程中。

        D :当网络线程接收到请求后,Kafka在这个环节又做了一层异步线程池的处理。
            (1)当网络线程拿到请求后,她不是自己处理,而是将请求放入到一个共享请求队列中。
            (2)Broker端还有个IO线程池,负责从该队列中取出请求,执行真正的处理。如果是PRODUCE生产请求,则将消息写入到底层的磁盘日志中;如果是FETCH请求,则从磁盘或页缓存中读取消息。

        E :IO线程池中的线程是执行请求逻辑的线程。Broker端参数num.io.threads控制了这个线程数,默认为8,表示每台Broker启动后自动创建8个IO线程处理请求。
        
        F :请求队列是所有网络线程共享的,而响应队列则是每个网络线程专属的。原因在于Dispatcher只是用于请求分发而不负责响应回传,因此只能让每个网络线程自己发送Repsone给客户端,所有这些Response没必要放在一个公共的地方。
        
        G :Purgatory组件,专门用来缓存延时请求(Delayed Requset)。如设置了acks=all的PRODUCE请求,该请求要必须等待ISR中所有副本都接收了消息后才能返回,此时处理该请求的IO线程就必须瞪大其他Broker的写入结果。当请求不能立即处理时,他就会暂存在Purgatory中。待满足了完成条件,IO线程会继续处理该请求,并将Response放入到对应的网络线程的响应队列中

    4 Kafka对请求的处理特点
        A :Kafka Broker对所有的请求都是一视同仁的。
        B :这些请求根据功能,可分为不同的请求类型。从业务的权重角度来讲,是有高低之分的,如控制类请求可以影响数据类请求。
        C :无原则的平等,会造成混乱

        社区采取的方案是,同时创建两套完全样的组件,实现两类请求的分离。
    展开
    
     1
  • Mick
    2019-08-05
    老师麻烦帮我看下这个请求流程图我画的对不对?https://www.processon.com/view/link/5d481e6be4b07c4cf3031755

    作者回复: 我觉得挺好的:)

     1
     1
  • 锦
    2019-07-30
    我理解Acceptor是用来接收连接的(三次握手),连接成功后把读写请求的Socket提交到网络线程池,网络线程池中的线程通过Selector收到读请求后,从内核读取消息数据,然后再把待处理消息数据放入共享请求队列中。共享请求队列应该是多生产者多消费者模式(这里如何设计比较关键)。io线程池从共享请求队列中取出消息处理,处理完成再把响应提交到网络线程池中,由网络线程池发送至客户端。这里的共享请求队列为什么不直接使用io线程池自带的工作队列呢?另外控制类请求单独走不同线程池处理比较合理。
    
     1
  • AAA_叶子
    2019-12-18
    producer 发送消息给broker 这块还没讲呢,这里涉及到消息的分组和分批次发送。

    作者回复: 在producer部分的专栏有涉及到

    
    
  • 飞翔
    2019-11-13
    老师 请问有多少线程 在处理请求响应队列里的response消息呀

    作者回复: 网络线程池的个数

    
    
  • 飞翔
    2019-11-13
    老师 kafka 为什么不用reactor 最后一种模式 把用boss reactor 和work reactor 模型 而用较简单的第一种reactor
    
    
  • 朱东旭
    2019-11-02
    胡老师您好,为什么有时候听到epoll,有时候听到reactor,这俩有啥区别。。

    作者回复: 不是一个层级的东西。epoll是一种IO模型,而Reactor是一种IO处理模式(IO pattern)。可以这么说:我们可以使用epoll来实现Reactor

    
    
  • 云师兄
    2019-10-14
    老师能否解答下kafka要分成网络线程和io线程?像tomcat这类请求模型中,网络线程也是执行线程,kafka大费周章,除了延迟请求,还有其他目的吗

    作者回复: 我不是设计人员不好妄言:)直观的感受是,可能就是单纯地想把分发线程和处理线程分开吧

    
    
  • B+Tree
    2019-10-09
    reactor模式特别适合多客户端向服务端请求的场景,同样场景的还有redis
    
    
  • 代码搬运工
    2019-09-17
    控制类请求直接创建新的线程池执行。
    
    
  • aof
    2019-09-15
    老师可不可以这么理解,这一节其实就是讲的Kafka的网络模型?

    作者回复: 可以的:)

    
    
  • shjdwxy
    2019-09-14
    如果共享请求队列满了,会出现什么问题呢?

    作者回复: 相应的线程阻塞住,表现为请求处理延时增加

    
    
我们在线,来聊聊吧