Apache Kafka 是一个分布式消息发布订阅系统。它最初由 LinkedIn 公司基于独特的设计实现为一个分布式的提交日志系统,之后成为 Apache 项目的一部分。Kafka 系统快速、可扩展并且可持久化。它的分区、可复制和可容错等特性都是非常出色的。
Kafka 社区在 0.10.0.0 版本正式推出了流处理组件 Kafka Streams,使 Kafka 一跃变为分布式的流处理平台,而不仅仅是消息引擎系统了。可以说目前的 Kafka 是和 Storm、Spark、Flink 同等级的实时流处理平台。
出于对 Kafka 技术和其发展路径的好奇,我们找到了胡夕老师。胡夕老师是 Kafka 的技术专家,曾经在极客时间上开设了《Kafka 核心技术与实战》和《Kafka 核心源码解读》两个专栏,对 Kafka 的研究很是深入,也是社区里面非常活跃的 Committer。他不仅对 Kafka 及其它开源流处理框架与技术有深刻理解,对于如何阅读源码更是有着长期的探索和实践。他曾主导过多个十亿级 / 天的消息引擎业务系统的设计与搭建,具有丰富的线上环境定位和诊断调优经验,曾给多家大型公司提供企业级的 Kafka 培训。
同时他也是本月上线的 QCon+ 案例研习社「Kafka 业界最佳实践」专题的出品人,带队来分享 Kafka 的最佳技术实践。因此我们针对 Kafka 技术对胡夕老师进行了采访,让我们一起来看看老师的思考吧。
胡夕:目前我手头的工作主要由三个部分组成:
第一部分是和团队一起负责公司的数据平台建设,包括完善公司内的数据湖平台,整合上下游离线 / 实时数据,同时进一步构建我们自研的实时用户画像系统,为公司更多的核心业务以及国际化展业提供数据支撑;
第二部分的工作是负责公司活动营销的研发,包括营销活动的研发上线以及辅助营销增长的各类内部支撑系统的开发;
最后一部分是负责公司的社区产品研发。互联网券商的社区是一个高度垂直类的 C 端社区产品,它需要将券商领域内的业务特点与互联网社区的形态相结合。我们就负责这个社区产品的开发工作。
胡夕:在我过往的 Kafka 使用经验中,我认为有两大问题是比较突出的,这也是和很多业界同仁们交流之后得到的一致性结论:一个是 Kafka 消费的问题;另一个就是 Kafka 运维,特别是版本升级的问题。
我们先说第一个,其实我认为大家都同意 Kafka 这个框架的上手成本是比较低的,学习曲线也很平坦。工程师一般自行阅读文档或者查阅网上的资料,不需要几天就能把 Kafka 跑起来。我没有怎么碰到过消息生产,也就是 Producer 端的问题,但消息的消费却很容易出现各种各样的线上问题,最常遇到的应该就是消息堆积。
造成消息堆积的原因可能有很多,大致可以概括为以下两种:
1. 消息处理速度太慢了,至少落后于生产的速度
2. 消息处理出错碰到异常了
在这两个原因中又以第一个最为常见。
我们自己的系统里面消费消息的逻辑很重,通常涉及很重的 I/O 操作,所以消费速度的问题是比较常见的。这一点我相信业界同行们应该也有类似的体会。解决这个问题的方法有很多,比如调参、使用多线程甚至是生产者降速等等。具体用哪种还要结合自身的业务特点来决定。
在我们的环境中,我们更倾向于优先调整消费者端的参数,之后才会考虑一些更加复杂的手段。在这个事情上,我也思考过一些有意思的事情。比如我见过很多 Kafka 资料和书籍里面都写:如果消费堆积,需要考虑优化消费处理逻辑,降低消息处理时间;我自己写的书里好像也是这么说的。但是在实际环境中,你会发现优化处理逻辑这件事情其实并不容易。后端或下游的消费逻辑哪里是那么容易就被简化的,不给你增加逻辑就谢天谢地了。这是典型的书本理论与现实之间的差异。
我们继续来说 Kafka 运维的问题。我必须承认目前的状况已经比前几年好太多太多了。国内大厂自研并开源出来的运维框架有很多,不管是帮助做日常集群管理,集群监控的还是协助做扩缩容的。总体上而言,运维成本是被极大地降低了。
不过这依然是一个令很多中小型公司运维工程师们头疼的问题。比如如何做集群节点的维护,怎么能不宕机升级版本,如何实现跨机房之间的数据同步等等。实际上我们公司就碰到了以上提到的所有问题。
我们是有多个机房,还有云,那么应该如何设计并建设公司级的消息队列服务呢?是部署多套 Kafka 集群还是构建单体型的大一统集群?这些其实在 Kafka 社区并没有清晰明确的最佳实践,我们也只能是摸着石头过河。要知道中小型公司的运维团队不会太多太大,不可能像大厂那样固定“养”几个人就专门研究 Kafka,这在中小型互联网公司是不太可能的,因为成本太高了。
实际上在我的团队,如果有人天天研究这些技术,不做业务,我也是持反对意见的。很简单,我“养不起你”。所以这个运维的过程中必然存在着很多磕磕绊绊的事情。就部署集群来说,最终我们公司用的是多套集群加集群间数据同步的方案。不能说是完美无缺,但至少满足了业务的需求。
胡夕:我对 Kafka 确实还算比较熟悉,但对其他的消息引擎还真是不太熟悉,因此也不敢妄言。在我看来,Kafka 推出的时机非常好,这是它的一个显著优势。它起家于 LinkedIn 公司,骨子里就带有互联网的基因。什么基因呢?大数据量、低延时、分布式等。所有在 Kafka 成名之前的消息引擎框架好像并没有同时展现出这些基因。应该说,Kafka 在其出现之时是将这些优势结合的最好的一个。至于系统级的架构优势或设计优势,我个人倒是觉得每家都各有所长,它们并不是令 Kafka 如今这么受欢迎的最重要因素。
来到 2020 年之后,消息队列往云原生架构演进的方向算是更加清晰明朗了。云上的类似于多租户、按量计费、动态扩缩容等特性也越来越成为各家产品的标配。我个人觉得,在这些方面 Kafka 现今反而是有些落后了。不过欣喜的是,社区早就意识到了这一点。为了适配云上多种异质存储,Kafka 提供了分层存储的功能,算是往云原生又迈进了一步。
胡夕:其实关于这个问题,我还真有一些自己的看法。当初,社区同时推出了 Kafka Connect 和 Kafka Streams 两个组件。从当时的研发配比和宣传力度上,我们可以看到无论是社区,还是商业化公司 Confluent 都重点强调 Kafka Streams,对 Kafka Connect 组件并不是很重视。这一点我们可以从社区版就能看出来。社区版的 Kafka Connect 真是有点“惨不忍睹”,仅仅支持一个 File Connector。很多与主流框架集成的 Connector 都放入了商业版。
当然,这里面的商业化考量我们不去评判。我只想说,相比于当时普天遍地的 Kafka Streams 的宣传,Kafka Connect 明显要弱势得多。我相信即使到现在,听说过 Kafka Connect 的人应该也不是很多,这会导致一个什么问题呢?
Kafka 作为一个消息队列,它承载的是数据上下游的流转。从功能角度上看,它的场景很单一,无法像 Hadoop 那样自成一个生态。如果要对外开疆拓土,数据计算和连接算是一个很好的破局之路。但若要计算,必先连接。靠什么呢?靠的就是 Kafka Connect。
从战略的角度,我倒是觉得应该首先重点开发和建设 Kafka Connect,统一上下游框架的数据接入与流出,特别是应该在社区版推出开发难度小且易上手的 Connector 框架。只把这些 Connector 放入商业版而忽略广大的社区用户未免有些短视。
现实的情况是,由于投入重点在 Kafka Streams,所以其一经推出便迅速引起波澜,激起了人们对于它和当时主流计算框架的比较,诸如 Flink VS Kafka Streams 这样的文章比比皆是。几年之后,人们发现 Kafka Streams 的处境有些尴尬,随着 Flink 渐渐一统江湖,Kafka Streams 的使用者终是小众,没有掀起太大的浪花出来。
我个人认为,从技术实力、系统架构方面看,Kafka Streams 相较于 Flink 并没有太大的劣势,甚至有些方面还有胜出,毕竟它与 Kafka 是天然集成在一起的。另外,Kafka Streams 核心开发者之一 Matthias J. Sax 同时也是 Flink、Kafka Streams 和 Storm 的 PMC Committer。你说有这么一个猛人在团队里面写代码,Kafka Streams 的技术能差吗?可为什么好像还是不如 Flink 呢?我依然觉得这是一个战略上的错误,即轻视了 Kafka Connect 的发展。大家如果有兴趣可以自行翻开 Flink 的源代码,找到里面的 flink-connectors 目录,里面 Connector 的丰富程度不用我说,大家自己体会下就能知道了。
不过俗话说:失之东隅,收之桑榆。Kafka Streams 虽然没有取得巨大的成功,但在内部倒成了 Confluent 公司下一代 Steaming SQL 产品的基石。从目前的宣传态势上看,Confluent 公司正在推 ksqlDB 这个东西,它的底层就是用 Kafka Streams 做的。这种实时的流式数据 SQL 查询引擎目前还属于比较新的东西,未来有可能直接用它来构建实时数仓或做实时 ETL 引擎。从这个角度来说,Kafka Streams 也许能在日后的竞争格局中抢得先机。
胡夕:社区最近移出对 ZooKeeper 的依赖显示了其对简化集群对外部系统依赖性和降低运维成本方面的考虑。这种瘦身我认为未来可能会继续下去,也就是说相比于做加法,我觉得未来可能更多地是做减法,去除一些无用的或者有助于减轻系统开销的功能组件。同时,我认为社区会继续往云原生方向演进:动态扩缩容、按量计费、多租户等这些标配的功能陆续还是需要相应的功能组件来支撑,目前来说,至少对于社区版的 Kafka,做到这些很难。也许只会有那些有能力的大厂自己来定制化开发,提供各自云上的 Kafka 服务了。
另外,在国内,由于很多传统行业有着强烈的数字化转型需求,需要重新整理、集中和处理企业中海量的历史业务数据,因此必然存在着千奇百怪的数据连接和数据 ETL 场景。实际上正是由于社区版在这方面的欠缺,这里面存在着巨大的商业机会。未来在国内可能会诞生多个以咨询公司或解决方案实施公司为主体的企业来帮助传统企业、科研院所完成数字化转型。我期待社区也能在这个方面有所响应,特别是国内的代码贡献者也能参与其中。毕竟我们每个人都要紧跟国家的时代发展需要来顺势而为。
胡夕:我不知道大家的感受如何,就我个人而言,读源码是个特别痛苦的过程。读着读着就想要放弃,这应该是最自然朴素的感受了。第一次读源码我甚至都不知道这些代码写出来是做什么的。但是感觉好像也没有特别高效的方法,也许把时间花够了,自然有量变产生质变的效果。
至于比较高效的方法,我推荐结合单元测试用例来阅读。在阅读每个部分的源码时,实际跑一下对应的测试用例,加上单步调试能够快速地帮你理解源码是做什么事情的。另外,我也推荐先从服务器端的源码开始读,毕竟弄明白底层的消息以及处理逻辑,会更容易理解客户端的代码。
胡夕:前些年软件开源还仅仅是有兴趣的技术人员的乐土而已。不过最近几年,我发现软件开源和之后的商业化已经慢慢地变成了一个成熟的商业模式。由于我自己本身在券商公司,因此对这个赛道的玩家也多多少少有所了解。不管是之前上市的 MongoDB,还是最近的 Confluent、GitLab 和 HashiCorp 等,都是依托开源社区抓住用户和开发者,不断迭代产品来满足用户需求。之后再转型商业化,把控好开源的占比实现收入。这似乎越来越被验证是一条可行的路。我曾经听说有投资人笑称,凡是 GitHub 社区 Star 超过 1000 的一律投。足见这两年资本对软件开源是多么地看好。
另外,我始终觉得商业的本质还是要盈利。自 2022 年开始,美股的科技股就一直被杀估值。很多在美股上市的开源商业化公司目前还是不赚钱的,也就是市盈率是负的,资本市场会狠狠地碾压这类公司的估值。比如,国外大名鼎鼎的云数仓公司 Snowflake 自去年 11 月起就已经跌去了将近 30% 的市值。
因此我觉得未来的软件开源趋势一定是越来越火爆,但商业化的道路可能也不会很顺利,每个 CEO 或社区领导者都要思考对用户的价值需要如何变现以及如何保护自身知识产权不受侵犯,否则像 Log4j2 维护者诉苦自己没工资拿还要被全网 diss 的场景还会再次发生。
胡夕:面对这个问题我真是没有特别好的答案。套用巴菲特老人家的风格:学习 Kafka 需要记住两条:1. 坚持学习;2. 参考第一条。
胡夕
Apache Kafka Committer , 老虎证券技术总监
著有《Apache Kafka 实战》一书,曾任职于 IBM、搜狗和新浪微博等公司,也是极客时间《Kafka 核心技术与实战》和《Kafka 核心源码解读》专栏的作者。胡夕对 Kafka 及其它开源流处理框架与技术有深刻理解,他精通 Kafka 原理,主导过多个十亿级 / 天的消息引擎业务系统的设计与搭建,具有丰富的线上环境定位和诊断调优经验,曾给多家大型公司提供企业级 Kafka 培训。
5 月 12-14 日,QCon 全球软件开发大会将落地北京国际会议中心,关注下一代大数据系统架构、分布式数据库、云原生数据湖。此外,还有业务架构、Rust、WASM、可观测、业务安全合规、产品设计、大前端新基建、组织管理等多个热点专题,与你一起探讨技术新趋势。
现在购票即可享受 8 折特惠,购票立减 1760 元,扫码立即购票。点击底部【阅读原文】获取大会专题详情。