Kafka 核心技术与实战
胡夕
Apache Kafka Committer,老虎证券技术总监
52815 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
结束语 (1讲)
Kafka 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

13 | Java生产者是如何管理TCP连接的?

社区设计的改进想法
Kafka自动关闭
用户主动关闭
在消息发送时
在更新元数据后
在创建KafkaProducer实例时建立
调用KafkaProducer的close方法关闭生产者
使用KafkaProducer的send方法发送消息
创建KafkaProducer对象实例
构造生产者对象所需的参数对象
KafkaProducer
已知的HTTP库在很多编程语言中简陋
TCP提供高级功能
所有通信都是基于TCP的
开放讨论
何时关闭TCP连接
何时创建TCP连接
Kafka生产者程序概览
为何采用TCP
Kafka的Java生产者是如何管理TCP连接的

该思维导图由 AI 生成,仅供参考

你好,我是胡夕。今天我要和你分享的主题是:Kafka 的 Java 生产者是如何管理 TCP 连接的。

为何采用 TCP?

Apache Kafka 的所有通信都是基于 TCP 的,而不是基于 HTTP 或其他协议。无论是生产者、消费者,还是 Broker 之间的通信都是如此。你可能会问,为什么 Kafka 不使用 HTTP 作为底层的通信协议呢?其实这里面的原因有很多,但最主要的原因在于 TCP 和 HTTP 之间的区别。
从社区的角度来看,在开发客户端时,人们能够利用 TCP 本身提供的一些高级功能,比如多路复用请求以及同时轮询多个连接的能力。
所谓的多路复用请求,即 multiplexing request,是指将两个或多个数据流合并到底层单一物理连接中的过程。TCP 的多路复用请求会在一条物理连接上创建若干个虚拟连接,每个虚拟连接负责流转各自对应的数据流。其实严格来说,TCP 并不能多路复用,它只是提供可靠的消息交付语义保证,比如自动重传丢失的报文。
更严谨地说,作为一个基于报文的协议,TCP 能够被用于多路复用连接场景的前提是,上层的应用协议(比如 HTTP)允许发送多条消息。不过,我们今天并不是要详细讨论 TCP 原理,因此你只需要知道这是社区采用 TCP 的理由之一就行了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kafka的Java生产者是如何管理TCP连接的?本文深入探讨了Kafka的通信基于TCP协议的原因以及Java生产者程序的概览。文章首先解释了Kafka选择TCP作为通信协议的主要原因,强调了TCP提供的高级功能和相对简陋的HTTP库在多种编程语言中的限制。随后,文章详细介绍了Kafka的Java生产者API,包括构造生产者对象所需的参数对象、创建KafkaProducer对象实例、使用send方法发送消息以及关闭生产者的步骤。进一步探讨了Kafka的Producer客户端是如何管理TCP连接的,包括TCP连接的创建和关闭时机。文章指出,TCP连接是在创建KafkaProducer实例时建立的,并可能在更新元数据后或消息发送时创建。此外,还讨论了TCP连接的关闭方式,包括用户主动关闭和Kafka自动关闭,以及与connections.max.idle.ms参数相关的设置。最后,文章提出了对Kafka生产者端管理TCP连接方式的挑战,并欢迎读者参与讨论和分享。整体而言,本文深入浅出地解释了Kafka的Java生产者如何管理TCP连接,为读者提供了全面的技术视角和思考空间。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Kafka 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(87)

  • 最新
  • 精选
  • 注定非凡
    Apache Kafka的所有通信都是基于TCP的,而不是于HTTP或其他协议的 1 为什采用TCP? (1)TCP拥有一些高级功能,如多路复用请求和同时轮询多个连接的能力。 (2)很多编程语言的HTTP库功能相对的比较简陋。 名词解释: 多路复用请求:multiplexing request,是将两个或多个数据合并到底层—物理连接中的过程。TCP的多路复用请求会在一条物理连接上创建若干个虚拟连接,每个虚拟连接负责流转各自对应的数据流。严格讲:TCP并不能多路复用,只是提供可靠的消息交付语义保证,如自动重传丢失的报文。 2 何时创建TCP连接? (1)在创建KafkaProducer实例时, A:生产者应用会在后台创建并启动一个名为Sender的线程,该Sender线程开始运行时,首先会创建与Broker的连接。 B:此时不知道要连接哪个Broker,kafka会通过METADATA请求获取集群的元数据,连接所有的Broker。 (2)还可能在更新元数据后,或在消息发送时 3 何时关闭TCP连接 (1)Producer端关闭TCP连接的方式有两种:用户主动关闭,或kafka自动关闭。 A:用户主动关闭,通过调用producer.close()方关闭,也包括kill -9暴力关闭。 B:Kafka自动关闭,这与Producer端参数connection.max.idles.ms的值有关,默认为9分钟,9分钟内没有任何请求流过,就会被自动关闭。这个参数可以调整。 C:第二种方式中,TCP连接是在Broker端被关闭的,但这个连接请求是客户端发起的,对TCP而言这是被动的关闭,被动关闭会产生大量的CLOSE_WAIT连接。

    作者回复: 总结得相当强:)

    2019-10-31
    6
    49
  • 旭杰
    Producer 通过 metadata.max.age.ms定期更新元数据,在连接多个broker的情况下,producer是如何决定向哪个broker发起该请求?

    作者回复: 向它认为当前负载最少的节点发送请求,所谓负载最少就是指未完成请求数最少的broker

    2019-07-23
    4
    27
  • 小马
    老师有个问题请教下: Producer 通过 metadata.max.age.ms 参数定期地去更新元数据信息,默认5分钟更新元数据,如果没建立TCP连接则会创建,而connections.max.idle.ms默认9分钟不使用该连接就会关闭。那岂不是会循环往复地不断地在创建关闭TCP连接了吗?

    作者回复: 如果你的producer长时间没有消息需要发送,TCP连接确实会定期关闭再重建的

    2020-01-09
    2
    20
  • Frank
    最近在使用kafka Connector做数据同步服务,在kafka中创建了许多topic,目前对kafka了解还不够深入,不知道这个对性能有什么影响?topic的数量多大范围比较合适?

    作者回复: topic数量只要不是太多,通常没有什么影响。如果单台broker上分区数超过2k,那么可能要关注是否会出现性能问题了。

    2019-07-10
    17
  • 你好旅行者
    老师好,看了今天的文章我有几个问题: 1.Kafka的元数据信息是存储在zookeeper中的,而Producer是通过broker来获取元数据信息的,那么这个过程是否是这样的,Producer向Broker发送一个获取元数据的请求给Broker,之后Broker再向zookeeper请求这个信息返回给Producer? 2.如果Producer在获取完元数据信息之后要和所有的Broker建立连接,那么假设一个Kafka集群中有1000台Broker,对于一个只需要与5台Broker交互的Producer,它连接池中的链接数量是不是从1000->5->1000->5?这样不是显得非常得浪费连接池资源?

    作者回复: 1. 集群元数据持久化在ZooKeeper中,同时也缓存在每台Broker的内存中,因此不需要请求ZooKeeper 2. 就我个人认为,的确有一些不高效。所以我说这里有优化的空间的。

    2019-07-02
    4
    15
  • 蓝魔丶
    老师,如果Broker端被动关闭,会导致client端产生close_wait状态,这个状态持续一段时间之后,client端不是应该发生FIN完成TCP断开的正常四次握手吗?怎么感觉老师讲的这个FIN就不会再发了,导致了僵尸连接的产生?

    作者回复: 问题在于客户端有可能一直hold住这个连接导致状态一直是CLOSE_WAIT。事实上,这是非常正确的做法,至少符合TCP协议的设计。当然,如果客户端关闭了连接,就像你说的,OS会发起FIN给远端

    2019-08-04
    8
    13
  • kursk.ye
    试想一下,在一个有着 1000 台 Broker 的集群中,你的 Producer 可能只会与其中的 3~5 台 Broker 长期通信,但是 Producer 启动后依次创建与这 1000 台 Broker 的 TCP 连接。一段时间之后,大约有 995 个 TCP 连接又被强制关闭。这难道不是一种资源浪费吗?很显然,这里是有改善和优化的空间的。 这段不敢苟同。作为消息服务器中国,连接应该是种必要资源,所以部署时就该充分给予,而且创建连接会消耗CPU,用到时再创建不合适,我甚至觉得Kafka应该有连接池的设计。 另外最后一部分关于TCP关闭第二种情况,客户端到服务端没有关闭,只是服务端到客户端关闭了,tcp是四次断开,可以单方向关闭,另一方向继续保持连接

    作者回复: 嗯嗯,欢迎不同意见。Kafka对于创建连接没有做任何限制。如果一开始就创建所有TCP连接,之后因为超时的缘故又关闭这些连接,当真正使用时再次创建,那么为什么不把创建时机后延到真正需要的时候呢?实际场景中将TCP连接设置为长连接的情形并不多见,因此我说这种设计是可以改进的。

    2019-07-02
    12
    11
  • 半瓶醋
    胡夕老师,Kafka集群的元数据信息是保存在哪里的呢,以CDH集群为例,我比较菜:)

    作者回复: 最权威的数据保存在ZooKeeper中,Controller会从ZooKeeper中读取并保存在它自己的内存中,然后同步部分元数据给集群所有Broker

    2020-05-13
    2
    8
  • yzh
    老是您好,咨询两个问题。 1. Producer实例创建和维护的tcp连接在底层是否是多个Producer实例共享的,还是Jvm内,多个Producer实例会各自独立创建和所有broker的tcp连接 2.Producer实例会和所有broker维持连接,这里的所有,是指和topic下各个分区leader副本所在的broker进行连接的,还是所有的broker,即使该broker下的所有topic分区都是flower

    作者回复: 1. 这些TCP连接只会被Producer实例下的Sender线程使用。多个Producer实例会创建各自的TCP连接 2. 从长期来看,只和需要交互的Broker有连接

    2019-08-20
    8
  • 电光火石
    谢谢老师。有几个问题请教一下: 1. producer连接是每个broker一个连接,跟topic没有关系是吗?(consumer也是这样是吗?) 2. 我们运维在所有的broker之前放了一个F5做负载均衡,但其实应该也没用,他会自动去获取kafka所有的broker,绕过这个F5,不知道我的理解是否正确? 3. 在线上我们有个kafka集群,大概200个topic,数据不是很均衡,有的一天才十几m,有的一天500G,我们是想consumer读取所有的topic,然后后面做分发,但是consumer会卡死在哪,也没有报错,也没有日志输出,不知道老师有没有思路可能是什么原因? 谢谢了!

    作者回复: 1. 也不能说没有关系。客户端需要和topic下各个分区leader副本所在的broker进行连接的 2. 嗯嗯,目前客户端是直连broker的 3. 光看描述想不出具体的原因。有可能是频繁rebalance、long GC、消息corrupted或干脆就是一个已知的bug

    2019-07-07
    5
收起评论
显示
设置
留言
87
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部