You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
11 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 05 | 聊聊Kafka的版本号
你好我是胡夕。今天我想和你聊聊如何选择Kafka版本号这个话题。今天要讨论的内容实在是太重要了我觉得它甚至是你日后能否用好Kafka的关键。
上一期我介绍了目前流行的几种Kafka发行版其实不论是哪种Kafka本质上都内嵌了最核心的Apache Kafka也就是社区版Kafka那今天我们就来说说Apache Kafka版本号的问题。在开始之前我想强调一下后面出现的所有“版本”这个词均表示Kafka具体的版本号而非上一篇中的Kafka种类这一点切记切记
那么现在你可能会有这样的疑问我为什么需要关心版本号的问题呢直接使用最新版本不就好了吗当然了这的确是一种有效的选择版本的策略但我想强调的是这种策略并非在任何场景下都适用。如果你不了解各个版本之间的差异和功能变化你怎么能够准确地评判某Kafka版本是不是满足你的业务需求呢因此在深入学习Kafka之前花些时间搞明白版本演进实际上是非常划算的一件事。
## Kafka版本命名
当前Apache Kafka已经迭代到2.2版本社区正在为2.3.0发版日期进行投票相信2.3.0也会马上发布。但是稍微有些令人吃惊的是很多人对于Kafka的版本命名理解存在歧义。比如我们在官网上下载Kafka时会看到这样的版本
![](https://static001.geekbang.org/resource/image/c1/23/c10df9e6f72126e9c721fba38e27ac23.png)
于是有些同学就会纳闷难道Kafka版本号不是2.11或2.12吗其实不然前面的版本号是编译Kafka源代码的Scala编译器版本。Kafka服务器端的代码完全由Scala语言编写Scala同时支持面向对象编程和函数式编程用Scala写成的源代码编译之后也是普通的“.class”文件因此我们说Scala是JVM系的语言它的很多设计思想都是为人称道的。
事实上目前Java新推出的很多功能都是在不断向Scala语言靠近罢了比如Lambda表达式、函数式接口、val变量等。一个有意思的事情是Kafka新版客户端代码完全由Java语言编写于是有些人展开了“Java VS Scala”的大讨论并从语言特性的角度尝试分析Kafka社区为什么放弃Scala转而使用Java重写客户端代码。其实事情远没有那么复杂仅仅是因为社区来了一批Java程序员而已而以前老的Scala程序员隐退罢了。可能有点跑题了但不管怎样我依然建议你有空去学学Scala语言。
回到刚才的版本号讨论。现在你应该知道了对于kafka-2.11-2.1.1的提法真正的Kafka版本号实际上是2.1.1。那么这个2.1.1又表示什么呢前面的2表示大版本号即Major Version中间的1表示小版本号或次版本号即Minor Version最后的1表示修订版本号也就是Patch号。Kafka社区在发布1.0.0版本后特意写过一篇文章宣布Kafka版本命名规则正式从4位演进到3位比如0.11.0.0版本就是4位版本号。
坦率说这里我和社区的意见是有点不同的。在我看来像0.11.0.0这样的版本虽然有4位版本号但其实它的大版本是0.11而不是0所以如果这样来看的话Kafka版本号从来都是由3个部分构成即“大版本号 - 小版本号 - Patch号”。这种视角可以统一所有的Kafka版本命名也方便我们日后的讨论。我们来复习一下假设碰到的Kafka版本是0.10.2.2你现在就知道了它的大版本是0.10小版本是2总共打了两个大的补丁Patch号是2。
## Kafka版本演进
Kafka目前总共演进了7个大版本分别是0.7、0.8、0.9、0.10、0.11、1.0和2.0其中的小版本和Patch版本很多。哪些版本引入了哪些重大的功能改进关于这个问题我建议你最好能做到如数家珍因为这样不仅令你在和别人交谈Kafka时显得很酷而且如果你要向架构师转型或者已然是架构师那么这些都是能够帮助你进行技术选型、架构评估的重要依据。
我们先从0.7版本说起,实际上也没什么可说的,这是最早开源时的“上古”版本了,以至于我也从来都没有接触过。这个版本只提供了最基础的消息队列功能,甚至连副本机制都没有,我实在想不出有什么理由你要使用这个版本,因此一旦有人向你推荐这个版本,果断走开就好了。
Kafka从0.7时代演进到0.8之后正式引入了**副本机制**至此Kafka成为了一个真正意义上完备的分布式高可靠消息队列解决方案。有了副本备份机制Kafka就能够比较好地做到消息无丢失。那时候生产和消费消息使用的还是老版本的客户端API所谓的老版本是指当你用它们的API开发生产者和消费者应用时你需要指定ZooKeeper的地址而非Broker的地址。
如果你现在尚不能理解这两者的区别也没关系我会在专栏的后续文章中详细介绍它们。老版本客户端有很多的问题特别是生产者API它默认使用同步方式发送消息可以想见其吞吐量一定不会太高。虽然它也支持异步的方式但实际场景中可能会造成消息的丢失因此0.8.2.0版本社区引入了**新版本Producer API**即需要指定Broker地址的Producer。
据我所知国内依然有少部分用户在使用0.8.1.1、0.8.2版本。**我的建议是尽量使用比较新的版本。如果你不能升级大版本我也建议你至少要升级到0.8.2.2这个版本因为该版本中老版本消费者API是比较稳定的。另外即使你升到了0.8.2.2也不要使用新版本Producer API此时它的Bug还非常多。**
时间来到了2015年11月社区正式发布了0.9.0.0版本。在我看来这是一个重量级的大版本更迭0.9大版本增加了基础的安全认证/权限功能同时使用Java重写了新版本消费者API另外还引入了Kafka Connect组件用于实现高性能的数据抽取。如果这么多眼花缭乱的功能你一时无暇顾及那么我希望你记住这个版本的另一个好处那就是**新版本Producer API在这个版本中算比较稳定了**。如果你使用0.9作为线上环境不妨切换到新版本Producer这是此版本一个不太为人所知的优势。但和0.8.2引入新API问题类似不要使用新版本Consumer API因为Bug超多的绝对用到你崩溃。即使你反馈问题到社区社区也不会管的它会无脑地推荐你升级到新版本再试试因此千万别用0.9的新版本Consumer API。对于国内一些使用比较老的CDH的创业公司鉴于其内嵌的就是0.9版本,所以要格外注意这些问题。
0.10.0.0是里程碑式的大版本,因为该版本**引入了Kafka Streams**。从这个版本起Kafka正式升级成分布式流处理平台虽然此时的Kafka Streams还基本不能线上部署使用。0.10大版本包含两个小版本0.10.1和0.10.2它们的主要功能变更都是在Kafka Streams组件上。如果你把Kafka用作消息引擎实际上该版本并没有太多的功能提升。不过在我的印象中自0.10.2.2版本起新版本Consumer API算是比较稳定了。**如果你依然在使用0.10大版本我强烈建议你至少升级到0.10.2.2然后使用新版本Consumer API。还有个事情不得不提0.10.2.2修复了一个可能导致Producer性能降低的Bug。基于性能的缘故你也应该升级到0.10.2.2。**
在2017年6月社区发布了0.11.0.0版本引入了两个重量级的功能变更一个是提供幂等性Producer API以及事务Transaction API另一个是对Kafka消息格式做了重构。
前一个好像更加吸引眼球一些毕竟Producer实现幂等性以及支持事务都是Kafka实现流处理结果正确性的基石。没有它们Kafka Streams在做流处理时无法向批处理那样保证结果的正确性。当然同样是由于刚推出此时的事务API有一些Bug不算十分稳定。另外事务API主要是为Kafka Streams应用服务的实际使用场景中用户利用事务API自行编写程序的成功案例并不多见。
第二个重磅改进是消息格式的变化。虽然它对用户是透明的但是它带来的深远影响将一直持续。因为格式变更引起消息格式转换而导致的性能问题在生产环境中屡见不鲜所以你一定要谨慎对待0.11版本的这个变化。不得不说的是这个版本中各个大功能组件都变得非常稳定了国内该版本的用户也很多应该算是目前最主流的版本之一了。也正是因为这个缘故社区为0.11大版本特意推出了3个Patch版本足见它的受欢迎程度。我的建议是如果你对1.0版本是否适用于线上环境依然感到困惑那么至少将你的环境升级到0.11.0.3,因为这个版本的消息引擎功能已经非常完善了。
最后我合并说下1.0和2.0版本吧因为在我看来这两个大版本主要还是Kafka Streams的各种改进在消息引擎方面并未引入太多的重大功能特性。Kafka Streams的确在这两个版本有着非常大的变化也必须承认Kafka Streams目前依然还在积极地发展着。如果你是Kafka Streams的用户至少选择2.0.0版本吧。
去年8月国外出了一本书叫Kafka Streams in Action中文版《Kafka Streams实战》它是基于Kafka Streams 1.0版本撰写的。最近我用2.0版本去运行书中的例子,居然很多都已经无法编译了,足见两个版本变化之大。不过如果你在意的依然是消息引擎,那么这两个大版本都是适合于生产环境的。
最后还有个建议不论你用的是哪个版本都请尽量保持服务器端版本和客户端版本一致否则你将损失很多Kafka为你提供的性能优化收益。
## 小结
我希望现在你对如何选择合适的Kafka版本能做到心中有数了。每个Kafka版本都有它恰当的使用场景和独特的优缺点切记不要一味追求最新版本。事实上我周围的很多工程师都秉承这样的观念不要成为最新版本的“小白鼠”。了解了各个版本的差异之后我相信你一定能够根据自己的实际情况做出最正确的选择。
![](https://static001.geekbang.org/resource/image/9b/d1/9be3f8c5c2930f6482fb43d8bca507d1.jpg)
## 开放讨论
如何评估Kafka版本升级这件事呢你和你所在的团队有什么独特的见解
欢迎你写下自己的思考或疑问,我们一起讨论 。如果你觉得有所收获,也欢迎把文章分享给你的朋友。