mirror of
https://github.com/cheetahlou/CategoryResourceRepost.git
synced 2025-11-16 22:23:45 +08:00
del
This commit is contained in:
67
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/01 | 消息引擎系统ABC.md
Normal file
67
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/01 | 消息引擎系统ABC.md
Normal file
@@ -0,0 +1,67 @@
|
||||
<audio id="audio" title="01 | 消息引擎系统ABC" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/0b/4d/0b4336a9167249cf5e269de27944974d.mp3"></audio>
|
||||
|
||||
你好,我是胡夕。欢迎你来到“Kafka核心技术与实战”专栏。如果你对Kafka及其背后的消息引擎、流处理感兴趣,很高兴我们可以在此相聚,并在未来的一段日子里一同学习有关Kafka的方方面面。
|
||||
|
||||
毫无疑问,你现在对Apache Kafka一定充满了各种好奇,那么今天就允许我先来尝试回答下Kafka是什么这个问题。对了,先卖个关子,在下一期我还将继续回答这个问题,而且答案是不同的。那么,Kafka是什么呢?用一句话概括一下:**Apache Kafka是一款开源的消息引擎系统**。
|
||||
|
||||
倘若“消息引擎系统”这个词对你来说有点陌生的话,那么“消息队列”“消息中间件”的提法想必你一定是有所耳闻的。不过说实话我更愿意使用消息引擎系统这个称谓,因为消息队列给出了一个很不明确的暗示,仿佛Kafka是利用队列的方式构建的;而消息中间件的提法有过度夸张“中间件”之嫌,让人搞不清楚这个中间件到底是做什么的。
|
||||
|
||||
像Kafka这一类的系统国外有专属的名字叫Messaging System,国内很多文献将其简单翻译成消息系统。我个人认为并不是很恰当,因为它片面强调了消息主体的作用,而忽视了这类系统引以为豪的消息传递属性,就像引擎一样,具备某种能量转换传输的能力,所以我觉得翻译成消息引擎反倒更加贴切。
|
||||
|
||||
讲到这里,说点题外话。我觉得目前国内在翻译国外专有技术词汇方面做得不够标准化,各种名字和提法可谓五花八门。我举个例子,比如大名鼎鼎的Raft算法和Paxos算法。了解它的人都知道它们的作用是在分布式系统中让多个节点就某个决定达成共识,都属于Consensus Algorithm一族。如果你在搜索引擎中查找Raft算法,国内多是称呼它们为一致性算法。实际上我倒觉得翻译成共识算法是最准确的。我们使用“一致性”这个字眼太频繁了,国外的Consistency被称为一致性、Consensus也唤作一致性,甚至是Coherence都翻译成一致性。
|
||||
|
||||
还是拉回来继续聊消息引擎系统,那这类系统是做什么用的呢?我先来个官方严肃版本的答案。
|
||||
|
||||
根据维基百科的定义,消息引擎系统是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递。
|
||||
|
||||
果然是官方定义,有板有眼。如果觉得难于理解,那么可以试试我下面这个民间版:
|
||||
|
||||
系统A发送消息给消息引擎系统,系统B从消息引擎系统中读取A发送的消息。
|
||||
|
||||
最基础的消息引擎就是做这点事的!不论是上面哪个版本,它们都提到了两个重要的事实:
|
||||
|
||||
- 消息引擎传输的对象是消息;
|
||||
- 如何传输消息属于消息引擎设计机制的一部分。
|
||||
|
||||
既然消息引擎是用于在不同系统之间传输消息的,那么如何设计待传输消息的格式从来都是一等一的大事。试问一条消息如何做到信息表达业务语义而无歧义,同时它还要能最大限度地提供可重用性以及通用性?稍微停顿几秒去思考一下,如果是你,你要如何设计你的消息编码格式。
|
||||
|
||||
一个比较容易想到的是使用已有的一些成熟解决方案,比如使用CSV、XML亦或是JSON;又或者你可能熟知国外大厂开源的一些序列化框架,比如Google的Protocol Buffer或Facebook的Thrift。这些都是很酷的办法。那么现在我告诉你Kafka的选择:它使用的是纯二进制的字节序列。当然消息还是结构化的,只是在使用之前都要将其转换成二进制的字节序列。
|
||||
|
||||
消息设计出来之后还不够,消息引擎系统还要设定具体的传输协议,即我用什么方法把消息传输出去。常见的有两种方法:
|
||||
|
||||
- **点对点模型**:也叫消息队列模型。如果拿上面那个“民间版”的定义来说,那么系统A发送的消息只能被系统B接收,其他任何系统都不能读取A发送的消息。日常生活的例子比如电话客服就属于这种模型:同一个客户呼入电话只能被一位客服人员处理,第二个客服人员不能为该客户服务。
|
||||
- **发布/订阅模型**:与上面不同的是,它有一个主题(Topic)的概念,你可以理解成逻辑语义相近的消息容器。该模型也有发送方和接收方,只不过提法不同。发送方也称为发布者(Publisher),接收方称为订阅者(Subscriber)。和点对点模型不同的是,这个模型可能存在多个发布者向相同的主题发送消息,而订阅者也可能存在多个,它们都能接收到相同主题的消息。生活中的报纸订阅就是一种典型的发布/订阅模型。
|
||||
|
||||
比较酷的是Kafka同时支持这两种消息引擎模型,专栏后面我会分享Kafka是如何做到这一点的。
|
||||
|
||||
提到消息引擎系统,你可能会问JMS和它是什么关系。JMS是Java Message Service,它也是支持上面这两种消息引擎模型的。严格来说它并非传输协议而仅仅是一组API罢了。不过可能是JMS太有名气以至于很多主流消息引擎系统都支持JMS规范,比如ActiveMQ、RabbitMQ、IBM的WebSphere MQ和Apache Kafka。当然Kafka并未完全遵照JMS规范,相反,它另辟蹊径,探索出了一条特有的道路。
|
||||
|
||||
好了,目前我们仅仅是了解了消息引擎系统是做什么的以及怎么做的,但还有个重要的问题是为什么要使用它。
|
||||
|
||||
依旧拿上面“民间版”举例,我们不禁要问,为什么系统A不能直接发送消息给系统B,中间还要隔一个消息引擎呢?
|
||||
|
||||
答案就是“**削峰填谷**”。这四个字简直比消息引擎本身还要有名气。
|
||||
|
||||
我翻了很多文献,最常见的就是这四个字。所谓的“削峰填谷”就是指缓冲上下游瞬时突发流量,使其更平滑。特别是对于那种发送能力很强的上游系统,如果没有消息引擎的保护,“脆弱”的下游系统可能会直接被压垮导致全链路服务“雪崩”。但是,一旦有了消息引擎,它能够有效地对抗上游的流量冲击,真正做到将上游的“峰”填满到“谷”中,避免了流量的震荡。消息引擎系统的另一大好处在于发送方和接收方的松耦合,这也在一定程度上简化了应用的开发,减少了系统间不必要的交互。
|
||||
|
||||
说了这么多,可能你对“削峰填谷”并没有太多直观的感受。我还是举个例子来说明一下Kafka在这中间是怎么去“抗”峰值流量的吧。回想一下你在极客时间是如何购买这个课程的。如果我没记错的话极客时间每门课程都有一个专门的订阅按钮,点击之后进入到付费页面。这个简单的流程中就可能包含多个子服务,比如点击订阅按钮会调用订单系统生成对应的订单,而处理该订单会依次调用下游的多个子系统服务 ,比如调用支付宝和微信支付的接口、查询你的登录信息、验证课程信息等。显然上游的订单操作比较简单,它的TPS要远高于处理订单的下游服务,因此如果上下游系统直接对接,势必会出现下游服务无法及时处理上游订单从而造成订单堆积的情形。特别是当出现类似于秒杀这样的业务时,上游订单流量会瞬时增加,可能出现的结果就是直接压跨下游子系统服务。
|
||||
|
||||
解决此问题的一个常见做法是我们对上游系统进行限速,但这种做法对上游系统而言显然是不合理的,毕竟问题并不出现在它那里。所以更常见的办法是引入像Kafka这样的消息引擎系统来对抗这种上下游系统TPS的错配以及瞬时峰值流量。
|
||||
|
||||
还是这个例子,当引入了Kafka之后。上游订单服务不再直接与下游子服务进行交互。当新订单生成后它仅仅是向Kafka Broker发送一条订单消息即可。类似地,下游的各个子服务订阅Kafka中的对应主题,并实时从该主题的各自分区(Partition)中获取到订单消息进行处理,从而实现了上游订单服务与下游订单处理服务的解耦。这样当出现秒杀业务时,Kafka能够将瞬时增加的订单流量全部以消息形式保存在对应的主题中,既不影响上游服务的TPS,同时也给下游子服务留出了充足的时间去消费它们。这就是Kafka这类消息引擎系统的最大意义所在。
|
||||
|
||||
如果你对Kafka Broker、主题和分区等术语还不甚了解的话也不必担心,我会在专栏后面专门花时间介绍一下Kafka的常见概念和术语。
|
||||
|
||||
在今天结束之前,我还想和你分享一个自己的小故事。在2015年那会儿,我花了将近1年的时间阅读Kafka源代码,期间多次想要放弃。你要知道阅读将近50万行源码是多么痛的领悟。我还记得当初为了手写源代码注释,自己写满了一个厚厚的笔记本。不过幸运的是我坚持了下来,之前的所有努力也没有白费,以至于后面写书、写极客时间专栏就变成了一件件水到渠成的事情。
|
||||
|
||||
最后我想送给你一句话:**聪明人也要下死功夫**。我不记得这是曾国藩说的还是季羡林说的,但这句话对我有很大影响,当我感到浮躁的时候它能帮我静下心来踏踏实实做事情。希望这句话对你也有所启发。切记:聪明人要下死功夫!
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/8b/26/8bc58bf5bb98db09fd6ef343e0f28826.jpg" alt="">
|
||||
|
||||
## 开放讨论
|
||||
|
||||
请谈谈你对消息引擎系统的理解,或者分享一下你的公司或组织是怎么使用消息引擎来处理实际问题的。
|
||||
|
||||
欢迎写下你的思考和答案,我们一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
|
||||
|
||||
|
||||
63
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/02 | 一篇文章带你快速搞定Kafka术语.md
Normal file
63
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/02 | 一篇文章带你快速搞定Kafka术语.md
Normal file
@@ -0,0 +1,63 @@
|
||||
<audio id="audio" title="02 | 一篇文章带你快速搞定Kafka术语" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/5f/11/5f66506bc8a6bc5fa821dd8e547bbc11.mp3"></audio>
|
||||
|
||||
你好,我是胡夕。今天我们正式开启Apache Kafka学习之旅。
|
||||
|
||||
在Kafka的世界中有很多概念和术语是需要你提前理解并熟练掌握的,这对于后面你深入学习Kafka各种功能和特性将大有裨益。下面我来盘点一下Kafka的各种术语。
|
||||
|
||||
在专栏的第一期我说过Kafka属于分布式的消息引擎系统,它的主要功能是提供一套完备的消息发布与订阅解决方案。在Kafka中,发布订阅的对象是主题(Topic),你可以为每个业务、每个应用甚至是每类数据都创建专属的主题。
|
||||
|
||||
向主题发布消息的客户端应用程序称为生产者(Producer),生产者程序通常持续不断地向一个或多个主题发送消息,而订阅这些主题消息的客户端应用程序就被称为消费者(Consumer)。和生产者类似,消费者也能够同时订阅多个主题的消息。我们把生产者和消费者统称为客户端(Clients)。你可以同时运行多个生产者和消费者实例,这些实例会不断地向Kafka集群中的多个主题生产和消费消息。
|
||||
|
||||
有客户端自然也就有服务器端。Kafka的服务器端由被称为Broker的服务进程构成,即一个Kafka集群由多个Broker组成,Broker负责接收和处理客户端发送过来的请求,以及对消息进行持久化。虽然多个Broker进程能够运行在同一台机器上,但更常见的做法是将不同的Broker分散运行在不同的机器上,这样如果集群中某一台机器宕机,即使在它上面运行的所有Broker进程都挂掉了,其他机器上的Broker也依然能够对外提供服务。这其实就是Kafka提供高可用的手段之一。
|
||||
|
||||
实现高可用的另一个手段就是备份机制(Replication)。备份的思想很简单,就是把相同的数据拷贝到多台机器上,而这些相同的数据拷贝在Kafka中被称为副本(Replica)。好吧,其实在整个分布式系统里好像都叫这个名字。副本的数量是可以配置的,这些副本保存着相同的数据,但却有不同的角色和作用。Kafka定义了两类副本:领导者副本(Leader Replica)和追随者副本(Follower Replica)。前者对外提供服务,这里的对外指的是与客户端程序进行交互;而后者只是被动地追随领导者副本而已,不能与外界进行交互。当然了,你可能知道在很多其他系统中追随者副本是可以对外提供服务的,比如MySQL的从库是可以处理读操作的,但是在Kafka中追随者副本不会对外提供服务。对了,一个有意思的事情是现在已经不提倡使用Master-Slave来指代这种主从关系了,毕竟Slave有奴隶的意思,在美国这种严禁种族歧视的国度,这种表述有点政治不正确了,所以目前大部分的系统都改成Leader-Follower了。
|
||||
|
||||
副本的工作机制也很简单:生产者总是向领导者副本写消息;而消费者总是从领导者副本读消息。至于追随者副本,它只做一件事:向领导者副本发送请求,请求领导者把最新生产的消息发给它,这样它能保持与领导者的同步。
|
||||
|
||||
虽然有了副本机制可以保证数据的持久化或消息不丢失,但没有解决伸缩性的问题。伸缩性即所谓的Scalability,是分布式系统中非常重要且必须要谨慎对待的问题。什么是伸缩性呢?我们拿副本来说,虽然现在有了领导者副本和追随者副本,但倘若领导者副本积累了太多的数据以至于单台Broker机器都无法容纳了,此时应该怎么办呢?一个很自然的想法就是,能否把数据分割成多份保存在不同的Broker上?如果你就是这么想的,那么恭喜你,Kafka就是这么设计的。
|
||||
|
||||
这种机制就是所谓的分区(Partitioning)。如果你了解其他分布式系统,你可能听说过分片、分区域等提法,比如MongoDB和Elasticsearch中的Sharding、HBase中的Region,其实它们都是相同的原理,只是Partitioning是最标准的名称。
|
||||
|
||||
Kafka中的分区机制指的是将每个主题划分成多个分区(Partition),每个分区是一组有序的消息日志。生产者生产的每条消息只会被发送到一个分区中,也就是说如果向一个双分区的主题发送一条消息,这条消息要么在分区0中,要么在分区1中。如你所见,Kafka的分区编号是从0开始的,如果Topic有100个分区,那么它们的分区号就是从0到99。
|
||||
|
||||
讲到这里,你可能有这样的疑问:刚才提到的副本如何与这里的分区联系在一起呢?实际上,副本是在分区这个层级定义的。每个分区下可以配置若干个副本,其中只能有1个领导者副本和N-1个追随者副本。生产者向分区写入消息,每条消息在分区中的位置信息由一个叫位移(Offset)的数据来表征。分区位移总是从0开始,假设一个生产者向一个空分区写入了10条消息,那么这10条消息的位移依次是0、1、2、......、9。
|
||||
|
||||
至此我们能够完整地串联起Kafka的三层消息架构:
|
||||
|
||||
- 第一层是主题层,每个主题可以配置M个分区,而每个分区又可以配置N个副本。
|
||||
- 第二层是分区层,每个分区的N个副本中只能有一个充当领导者角色,对外提供服务;其他N-1个副本是追随者副本,只是提供数据冗余之用。
|
||||
- 第三层是消息层,分区中包含若干条消息,每条消息的位移从0开始,依次递增。
|
||||
- 最后,客户端程序只能与分区的领导者副本进行交互。
|
||||
|
||||
讲完了消息层次,我们来说说Kafka Broker是如何持久化数据的。总的来说,Kafka使用消息日志(Log)来保存数据,一个日志就是磁盘上一个只能追加写(Append-only)消息的物理文件。因为只能追加写入,故避免了缓慢的随机I/O操作,改为性能较好的顺序I/O写操作,这也是实现Kafka高吞吐量特性的一个重要手段。不过如果你不停地向一个日志写入消息,最终也会耗尽所有的磁盘空间,因此Kafka必然要定期地删除消息以回收磁盘。怎么删除呢?简单来说就是通过日志段(Log Segment)机制。在Kafka底层,一个日志又进一步细分成多个日志段,消息被追加写到当前最新的日志段中,当写满了一个日志段后,Kafka会自动切分出一个新的日志段,并将老的日志段封存起来。Kafka在后台还有定时任务会定期地检查老的日志段是否能够被删除,从而实现回收磁盘空间的目的。
|
||||
|
||||
这里再重点说说消费者。在专栏的第一期中我提到过两种消息模型,即点对点模型(Peer to Peer,P2P)和发布订阅模型。这里面的点对点指的是同一条消息只能被下游的一个消费者消费,其他消费者则不能染指。在Kafka中实现这种P2P模型的方法就是引入了消费者组(Consumer Group)。所谓的消费者组,指的是多个消费者实例共同组成一个组来消费一组主题。这组主题中的每个分区都只会被组内的一个消费者实例消费,其他消费者实例不能消费它。为什么要引入消费者组呢?主要是为了提升消费者端的吞吐量。多个消费者实例同时消费,加速整个消费端的吞吐量(TPS)。我会在专栏的后面详细介绍消费者组机制,所以现在你只需要了解消费者组是做什么的即可。另外这里的消费者实例可以是运行消费者应用的进程,也可以是一个线程,它们都称为一个消费者实例(Consumer Instance)。
|
||||
|
||||
消费者组里面的所有消费者实例不仅“瓜分”订阅主题的数据,而且更酷的是它们还能彼此协助。假设组内某个实例挂掉了,Kafka能够自动检测到,然后把这个Failed实例之前负责的分区转移给其他活着的消费者。这个过程就是Kafka中大名鼎鼎的“重平衡”(Rebalance)。嗯,其实既是大名鼎鼎,也是臭名昭著,因为由重平衡引发的消费者问题比比皆是。事实上,目前很多重平衡的Bug社区都无力解决。
|
||||
|
||||
每个消费者在消费消息的过程中必然需要有个字段记录它当前消费到了分区的哪个位置上,这个字段就是消费者位移(Consumer Offset)。注意,这和上面所说的位移完全不是一个概念。上面的“位移”表征的是分区内的消息位置,它是不变的,即一旦消息被成功写入到一个分区上,它的位移值就是固定的了。而消费者位移则不同,它可能是随时变化的,毕竟它是消费者消费进度的指示器嘛。另外每个消费者有着自己的消费者位移,因此一定要区分这两类位移的区别。我个人把消息在分区中的位移称为分区位移,而把消费者端的位移称为消费者位移。
|
||||
|
||||
## 小结
|
||||
|
||||
我来总结一下今天提到的所有名词术语:
|
||||
|
||||
- 消息:Record。Kafka是消息引擎嘛,这里的消息就是指Kafka处理的主要对象。
|
||||
- 主题:Topic。主题是承载消息的逻辑容器,在实际使用中多用来区分具体的业务。
|
||||
- 分区:Partition。一个有序不变的消息序列。每个主题下可以有多个分区。
|
||||
- 消息位移:Offset。表示分区中每条消息的位置信息,是一个单调递增且不变的值。
|
||||
- 副本:Replica。Kafka中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓的副本。副本还分为领导者副本和追随者副本,各自有不同的角色划分。副本是在分区层级下的,即每个分区可配置多个副本实现高可用。
|
||||
- 生产者:Producer。向主题发布新消息的应用程序。
|
||||
- 消费者:Consumer。从主题订阅新消息的应用程序。
|
||||
- 消费者位移:Consumer Offset。表征消费者消费进度,每个消费者都有自己的消费者位移。
|
||||
- 消费者组:Consumer Group。多个消费者实例共同组成的一个组,同时消费多个分区以实现高吞吐。
|
||||
- 重平衡:Rebalance。消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。Rebalance是Kafka消费者端实现高可用的重要手段。
|
||||
|
||||
最后我用一张图来展示上面提到的这些概念,希望这张图能够帮助你形象化地理解所有这些概念:
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/58/91/58c35d3ab0921bf0476e3ba14069d291.jpg" alt="">
|
||||
|
||||
## 开放讨论
|
||||
|
||||
请思考一下为什么Kafka不像MySQL那样允许追随者副本对外提供读服务?
|
||||
|
||||
欢迎写下你的思考和答案,我们一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
|
||||
62
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/03 | Kafka只是消息引擎系统吗?.md
Normal file
62
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/03 | Kafka只是消息引擎系统吗?.md
Normal file
@@ -0,0 +1,62 @@
|
||||
<audio id="audio" title="03 | Kafka只是消息引擎系统吗?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/9a/3e/9a70e41801c1cb2d3a50307eb1df6d3e.mp3"></audio>
|
||||
|
||||
你好,我是胡夕。今天我们来聊一个老生常谈的话题:Kafka只是消息引擎系统吗?
|
||||
|
||||
要搞清楚这个问题,我们不可避免地要了解一下Apache Kafka的发展历程。有的时候我们会觉得说了解一个系统或框架的前世今生似乎没什么必要,直接开始学具体的技术不是更快更好吗?其实,不论是学习哪种技术,直接扎到具体的细节中,亦或是从一个很小的点开始学习,你很快就会感到厌烦。为什么呢?因为你虽然快速地搞定了某个技术细节,但无法建立全局的认知观,这会导致你只是在单个的点上有所进展,却没法将其串联成一条线进而扩展成一个面,从而实现系统地学习。
|
||||
|
||||
我这么说是有依据的,因为这就是我当初学习Kafka的方式。你可能不会相信,我阅读Kafka源码就是从utils包开始的。显然,我们不用看源码也知道这玩意是干什么用的,对吧?就是个工具类包嘛,而且这种阅读源码的方式是极其低效的。就像我说的,我是在一个点一个点地学习,但全部学完之后压根没有任何感觉,依然不了解Kafka,因为不知道这些包中的代码组合在一起能达成什么效果。所以我说它是很低效的学习方法。
|
||||
|
||||
后来我修改了学习的方法,转而从自上而下的角度去理解Kafka,竟然发现了很多之前学习过程中忽略掉的东西。更特别的是,我发现这种学习方法能够帮助我维持较长时间的学习兴趣,不会阶段性地产生厌烦情绪。特别是在了解Apache Kafka整个发展历史的过程中我愉快地学到了很多运营大型开源软件社区的知识和经验,可谓是技术之外的一大收获。
|
||||
|
||||
纵观Kafka的发展脉络,它的确是从消息引擎起家的,但正如文章标题所问,**Apache Kafka真的只是消息引擎吗**?通常,在回答这个问题之前很多文章可能就要这样展开了:那我们先来讨论下什么是消息引擎以及消息引擎能做什么事情。算了,我还是直给吧,就不从“唐尧虞舜”说起了。这个问题的答案是,**Apache Kafka是消息引擎系统,也是一个分布式流处理平台**(Distributed Streaming Platform)。如果你通读全篇文字但只能记住一句话,我希望你记住的就是这句。再强调一遍,Kafka是消息引擎系统,也是分布式流处理平台。
|
||||
|
||||
众所周知,Kafka是LinkedIn公司内部孵化的项目。根据我和Kafka创始团队成员的交流以及查阅到的公开信息显示,LinkedIn最开始有强烈的数据强实时处理方面的需求,其内部的诸多子系统要执行多种类型的数据处理与分析,主要包括业务系统和应用程序性能监控,以及用户行为数据处理等。
|
||||
|
||||
当时他们碰到的主要问题包括:
|
||||
|
||||
- 数据正确性不足。因为数据的收集主要采用轮询(Polling)的方式,如何确定轮询的间隔时间就变成了一个高度经验化的事情。虽然可以采用一些类似于启发式算法(Heuristic)来帮助评估间隔时间值,但一旦指定不当,必然会造成较大的数据偏差。
|
||||
- 系统高度定制化,维护成本高。各个业务子系统都需要对接数据收集模块,引入了大量的定制开销和人工成本。
|
||||
|
||||
为了解决这些问题,LinkedIn工程师尝试过使用ActiveMQ来解决这些问题,但效果并不理想。显然需要有一个“大一统”的系统来取代现有的工作方式,而这个系统就是Kafka。
|
||||
|
||||
Kafka自诞生伊始是以消息引擎系统的面目出现在大众视野中的。如果翻看0.10.0.0之前的官网说明,你会发现Kafka社区将其清晰地定位为一个分布式、分区化且带备份功能的提交日志(Commit Log)服务。
|
||||
|
||||
这里引出一个题外话,你可能好奇Kafka这个名字的由来,实际上Kafka作者之一Jay Kreps曾经谈及过命名的原因。
|
||||
|
||||
>
|
||||
因为Kafka系统的写性能很强,所以找了个作家的名字来命名似乎是一个好主意。大学期间我上了很多文学课,非常喜欢Franz Kafka这个作家,另外为开源软件起这个名字听上去很酷。
|
||||
|
||||
|
||||
言归正传,Kafka在设计之初就旨在提供三个方面的特性:
|
||||
|
||||
- 提供一套API实现生产者和消费者;
|
||||
- 降低网络传输和磁盘存储开销;
|
||||
- 实现高伸缩性架构。
|
||||
|
||||
在专栏后面的课程中,我们将陆续探讨Kafka是如何做到以上三点的。总之随着Kafka的不断完善,Jay等大神们终于意识到将其开源惠及更多的人是一个非常棒的主意,因此在2011年Kafka正式进入到Apache基金会孵化并于次年10月顺利毕业成为Apache顶级项目。
|
||||
|
||||
开源之后的Kafka被越来越多的公司应用到它们企业内部的数据管道中,特别是在大数据工程领域,Kafka在承接上下游、串联数据流管道方面发挥了重要的作用:所有的数据几乎都要从一个系统流入Kafka然后再流向下游的另一个系统中。这样的使用方式屡见不鲜以至于引发了Kafka社区的思考:与其我把数据从一个系统传递到下一个系统中做处理,我为何不自己实现一套流处理框架呢?基于这个考量,Kafka社区于0.10.0.0版本正式推出了流处理组件Kafka Streams,也正是从这个版本开始,Kafka正式“变身”为分布式的流处理平台,而不仅仅是消息引擎系统了。今天Apache Kafka是和Apache Storm、Apache Spark和Apache Flink同等级的实时流处理平台。
|
||||
|
||||
诚然,目前国内对Kafka是流处理平台的认知还尚不普及,其核心的流处理组件Kafka Streams更是少有大厂在使用。但我们也欣喜地看到,随着在Kafka峰会上各路大神们的鼎力宣传,如今利用Kafka构建流处理平台的案例层出不穷,而了解并有意愿使用Kafka Streams的厂商也是越来越多,因此我个人对于Kafka流处理平台的前景也是非常乐观的。
|
||||
|
||||
你可能会有这样的疑问:作为流处理平台,Kafka与其他主流大数据流式计算框架相比,优势在哪里呢?我能想到的有两点。
|
||||
|
||||
**第一点是更容易实现端到端的正确性(Correctness)**。Google大神Tyler曾经说过,流处理要最终替代它的“兄弟”批处理需要具备两点核心优势:**要实现正确性和提供能够推导时间的工具。实现正确性是流处理能够匹敌批处理的基石**。正确性一直是批处理的强项,而实现正确性的基石则是要求框架能提供精确一次处理语义,即处理一条消息有且只有一次机会能够影响系统状态。目前主流的大数据流处理框架都宣称实现了精确一次处理语义,但这是有限定条件的,即它们只能实现框架内的精确一次处理语义,无法实现端到端的。
|
||||
|
||||
这是为什么呢?因为当这些框架与外部消息引擎系统结合使用时,它们无法影响到外部系统的处理语义,所以如果你搭建了一套环境使得Spark或Flink从Kafka读取消息之后进行有状态的数据计算,最后再写回Kafka,那么你只能保证在Spark或Flink内部,这条消息对于状态的影响只有一次。但是计算结果有可能多次写入到Kafka,因为它们不能控制Kafka的语义处理。相反地,Kafka则不是这样,因为所有的数据流转和计算都在Kafka内部完成,故Kafka可以实现端到端的精确一次处理语义。
|
||||
|
||||
**可能助力Kafka胜出的第二点是它自己对于流式计算的定位**。官网上明确标识Kafka Streams是一个用于搭建实时流处理的客户端库而非是一个完整的功能系统。这就是说,你不能期望着Kafka提供类似于集群调度、弹性部署等开箱即用的运维特性,你需要自己选择适合的工具或系统来帮助Kafka流处理应用实现这些功能。
|
||||
|
||||
读到这你可能会说这怎么算是优点呢?坦率来说,这的确是一个“双刃剑”的设计,也是Kafka社区“剑走偏锋”不正面PK其他流计算框架的特意考量。大型公司的流处理平台一定是大规模部署的,因此具备集群调度功能以及灵活的部署方案是不可或缺的要素。但毕竟这世界上还存在着很多中小企业,它们的流处理数据量并不巨大,逻辑也并不复杂,部署几台或十几台机器足以应付。在这样的需求之下,搭建重量级的完整性平台实在是“杀鸡焉用牛刀”,而这正是Kafka流处理组件的用武之地。因此从这个角度来说,未来在流处理框架中,Kafka应该是有一席之地的。
|
||||
|
||||
除了消息引擎和流处理平台,Kafka还有别的用途吗?当然有!你能想象吗,Kafka能够被用作分布式存储系统。Kafka作者之一Jay Kreps曾经专门写过一篇文章阐述为什么能把[Kafka用作分布式存储](https://www.confluent.io/blog/okay-store-data-apache-kafka/)。不过我觉得你姑且了解下就好了,我从没有见过在实际生产环境中,有人把Kafka当作持久化存储来用 。
|
||||
|
||||
说了这么多,我只想阐述这样的一个观点:Apache Kafka从一个优秀的消息引擎系统起家,逐渐演变成现在分布式的流处理平台。你不仅要熟练掌握它作为消息引擎系统的非凡特性及使用技巧,最好还要多了解下其流处理组件的设计与案例应用。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ea/59/eafc2d9315a8ba858649c1ecd4201459.jpg" alt="">
|
||||
|
||||
## 开放讨论
|
||||
|
||||
你觉得Kafka未来的演进路线是怎么样的?如果你是Kafka社区的“掌舵人”,你准备带领整个社区奔向什么方向呢?(提示下,你可以把自己想象成Linus再去思考)
|
||||
|
||||
欢迎写下你的思考和答案,我们一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
|
||||
89
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/04 | 我应该选择哪种Kafka?.md
Normal file
89
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/04 | 我应该选择哪种Kafka?.md
Normal file
@@ -0,0 +1,89 @@
|
||||
<audio id="audio" title="04 | 我应该选择哪种Kafka?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/05/63/05f8cce80e5af8f38f7b4b75dc5ee463.mp3"></audio>
|
||||
|
||||
在专栏上一期中,我们谈了Kafka当前的定位问题,Kafka不再是一个单纯的消息引擎系统,而是能够实现精确一次(Exactly-once)处理语义的实时流处理平台。
|
||||
|
||||
你可能听说过Apache Storm、Apache Spark Streaming亦或是Apache Flink,它们在大规模流处理领域可都是响当当的名字。令人高兴的是,Kafka经过这么长时间不断的迭代,现在已经能够稍稍比肩这些框架了。我在这里使用了“稍稍”这个字眼,一方面想表达Kafka社区对于这些框架心存敬意;另一方面也想表达目前国内鲜有大厂将Kafka用于流处理的尴尬境地,毕竟Kafka是从消息引擎“半路出家”转型成流处理平台的,它在流处理方面的表现还需要经过时间的检验。
|
||||
|
||||
如果我们把视角从流处理平台扩展到流处理生态圈,Kafka更是还有很长的路要走。前面我提到过Kafka Streams组件,正是它提供了Kafka实时处理流数据的能力。但是其实还有一个重要的组件我没有提及,那就是Kafka Connect。
|
||||
|
||||
我们在评估流处理平台的时候,框架本身的性能、所提供操作算子(Operator)的丰富程度固然是重要的评判指标,但框架与上下游交互的能力也是非常重要的。能够与之进行数据传输的外部系统越多,围绕它打造的生态圈就越牢固,因而也就有更多的人愿意去使用它,从而形成正向反馈,不断地促进该生态圈的发展。就Kafka而言,Kafka Connect通过一个个具体的连接器(Connector),串联起上下游的外部系统。
|
||||
|
||||
整个Kafka生态圈如下图所示。值得注意的是,这张图中的外部系统只是Kafka Connect组件支持的一部分而已。目前还有一个可喜的趋势是使用Kafka Connect组件的用户越来越多,相信在未来会有越来越多的人开发自己的连接器。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/0e/3d/0ecc8fe201c090e7ce514d719372f43d.png" alt="">
|
||||
|
||||
说了这么多你可能会问这和今天的主题有什么关系呢?其实清晰地了解Kafka的发展脉络和生态圈现状,对于指导我们选择合适的Kafka版本大有裨益。下面我们就进入今天的主题——如何选择Kafka版本?
|
||||
|
||||
## 你知道几种Kafka?
|
||||
|
||||
咦? Kafka不是一个开源框架吗,什么叫有几种Kafka啊? 实际上,Kafka的确有好几种,这里我不是指它的版本,而是指存在多个组织或公司发布不同的Kafka。你一定听说过Linux发行版吧,比如我们熟知的CentOS、RedHat、Ubuntu等,它们都是Linux系统,但为什么有不同的名字呢?其实就是因为它们是不同公司发布的Linux系统,即不同的发行版。虽说在Kafka领域没有发行版的概念,但你姑且可以这样近似地认为市面上的确存在着多个Kafka“发行版”。
|
||||
|
||||
下面我就来梳理一下这些所谓的“发行版”以及你应该如何选择它们。当然了,“发行版”这个词用在Kafka框架上并不严谨,但为了便于我们区分这些不同的Kafka,我还是勉强套用一下吧。不过切记,当你以后和别人聊到这个话题的时候最好不要提及“发行版”这个词 ,因为这种提法在Kafka生态圈非常陌生,说出来难免贻笑大方。
|
||||
|
||||
**1. Apache Kafka**
|
||||
|
||||
Apache Kafka是最“正宗”的Kafka,也应该是你最熟悉的发行版了。自Kafka开源伊始,它便在Apache基金会孵化并最终毕业成为顶级项目,它也被称为社区版Kafka。咱们专栏就是以这个版本的Kafka作为模板来学习的。更重要的是,它是后面其他所有发行版的基础。也就是说,后面提到的发行版要么是原封不动地继承了Apache Kafka,要么是在此之上扩展了新功能,总之Apache Kafka是我们学习和使用Kafka的基础。
|
||||
|
||||
**2. Confluent Kafka**
|
||||
|
||||
我先说说Confluent公司吧。2014年,Kafka的3个创始人Jay Kreps、Naha Narkhede和饶军离开LinkedIn创办了Confluent公司,专注于提供基于Kafka的企业级流处理解决方案。2019年1月,Confluent公司成功融资D轮1.25亿美元,估值也到了25亿美元,足见资本市场的青睐。
|
||||
|
||||
这里说点题外话, 饶军是我们中国人,清华大学毕业的大神级人物。我们已经看到越来越多的Apache顶级项目创始人中出现了中国人的身影,另一个例子就是Apache Pulsar,它是一个以打败Kafka为目标的新一代消息引擎系统。至于在开源社区中活跃的国人更是数不胜数,这种现象实在令人振奋。
|
||||
|
||||
还说回Confluent公司,它主要从事商业化Kafka工具开发,并在此基础上发布了Confluent Kafka。Confluent Kafka提供了一些Apache Kafka没有的高级特性,比如跨数据中心备份、Schema注册中心以及集群监控工具等。
|
||||
|
||||
**3. Cloudera/Hortonworks Kafka**
|
||||
|
||||
Cloudera提供的CDH和Hortonworks提供的HDP是非常著名的大数据平台,里面集成了目前主流的大数据框架,能够帮助用户实现从分布式存储、集群调度、流处理到机器学习、实时数据库等全方位的数据处理。我知道很多创业公司在搭建数据平台时首选就是这两个产品。不管是CDH还是HDP里面都集成了Apache Kafka,因此我把这两款产品中的Kafka称为CDH Kafka和HDP Kafka。
|
||||
|
||||
当然在2018年10月两家公司宣布合并,共同打造世界领先的数据平台,也许以后CDH和HDP也会合并成一款产品,但能肯定的是Apache Kafka依然会包含其中,并作为新数据平台的一部分对外提供服务。
|
||||
|
||||
## 特点比较
|
||||
|
||||
Okay,说完了目前市面上的这些Kafka,我来对比一下它们的优势和劣势。
|
||||
|
||||
**1. Apache Kafka**
|
||||
|
||||
对Apache Kafka而言,它现在依然是开发人数最多、版本迭代速度最快的Kafka。在2018年度Apache基金会邮件列表开发者数量最多的Top 5排行榜中,Kafka社区邮件组排名第二位。如果你使用Apache Kafka碰到任何问题并提交问题到社区,社区都会比较及时地响应你。这对于我们Kafka普通使用者来说无疑是非常友好的。
|
||||
|
||||
但是Apache Kafka的劣势在于它仅仅提供最最基础的组件,特别是对于前面提到的Kafka Connect而言,社区版Kafka只提供一种连接器,即读写磁盘文件的连接器,而没有与其他外部系统交互的连接器,在实际使用过程中需要自行编写代码实现,这是它的一个劣势。另外Apache Kafka没有提供任何监控框架或工具。显然在线上环境不加监控肯定是不可行的,你必然需要借助第三方的监控框架实现对Kafka的监控。好消息是目前有一些开源的监控框架可以帮助用于监控Kafka(比如Kafka manager)。
|
||||
|
||||
**总而言之,如果你仅仅需要一个消息引擎系统亦或是简单的流处理应用场景,同时需要对系统有较大把控度,那么我推荐你使用Apache Kafka。**
|
||||
|
||||
**2. Confluent Kafka**
|
||||
|
||||
下面来看Confluent Kafka。Confluent Kafka目前分为免费版和企业版两种。前者和Apache Kafka非常相像,除了常规的组件之外,免费版还包含Schema注册中心和REST proxy两大功能。前者是帮助你集中管理Kafka消息格式以实现数据前向/后向兼容;后者用开放HTTP接口的方式允许你通过网络访问Kafka的各种功能,这两个都是Apache Kafka所没有的。
|
||||
|
||||
除此之外,免费版包含了更多的连接器,它们都是Confluent公司开发并认证过的,你可以免费使用它们。至于企业版,它提供的功能就更多了。在我看来,最有用的当属跨数据中心备份和集群监控两大功能了。多个数据中心之间数据的同步以及对集群的监控历来是Kafka的痛点,Confluent Kafka企业版提供了强大的解决方案帮助你“干掉”它们。
|
||||
|
||||
不过Confluent Kafka的一大缺陷在于,Confluent公司暂时没有发展国内业务的计划,相关的资料以及技术支持都很欠缺,很多国内Confluent Kafka使用者甚至无法找到对应的中文文档,因此目前Confluent Kafka在国内的普及率是比较低的。
|
||||
|
||||
**一言以蔽之,如果你需要用到Kafka的一些高级特性,那么推荐你使用Confluent Kafka。**
|
||||
|
||||
**3. CDH/HDP Kafka**
|
||||
|
||||
最后说说大数据云公司发布的Kafka(CDH/HDP Kafka)。这些大数据平台天然集成了Apache Kafka,通过便捷化的界面操作将Kafka的安装、运维、管理、监控全部统一在控制台中。如果你是这些平台的用户一定觉得非常方便,因为所有的操作都可以在前端UI界面上完成,而不必去执行复杂的Kafka命令。另外这些平台提供的监控界面也非常友好,你通常不需要进行任何配置就能有效地监控 Kafka。
|
||||
|
||||
但是凡事有利就有弊,这样做的结果是直接降低了你对Kafka集群的掌控程度。毕竟你对下层的Kafka集群一无所知,你怎么能做到心中有数呢?这种Kafka的另一个弊端在于它的滞后性。由于它有自己的发布周期,因此是否能及时地包含最新版本的Kafka就成为了一个问题。比如CDH 6.1.0版本发布时Apache Kafka已经演进到了2.1.0版本,但CDH中的Kafka依然是2.0.0版本,显然那些在Kafka 2.1.0中修复的Bug只能等到CDH下次版本更新时才有可能被真正修复。
|
||||
|
||||
**简单来说,如果你需要快速地搭建消息引擎系统,或者你需要搭建的是多框架构成的数据平台且Kafka只是其中一个组件,那么我推荐你使用这些大数据云公司提供的Kafka。**
|
||||
|
||||
## 小结
|
||||
|
||||
总结一下,我们今天讨论了不同的Kafka“发行版”以及它们的优缺点,根据这些优缺点,我们可以有针对性地根据实际需求选择合适的Kafka。下一期,我将带你领略Kafka各个阶段的发展历程,这样我们选择Kafka功能特性的时候就有了依据,在正式开启Kafka应用之路之前也夯实了理论基础。
|
||||
|
||||
最后我们来复习一下今天的内容:
|
||||
|
||||
- Apache Kafka,也称社区版Kafka。优势在于迭代速度快,社区响应度高,使用它可以让你有更高的把控度;缺陷在于仅提供基础核心组件,缺失一些高级的特性。
|
||||
- Confluent Kafka,Confluent公司提供的Kafka。优势在于集成了很多高级特性且由Kafka原班人马打造,质量上有保证;缺陷在于相关文档资料不全,普及率较低,没有太多可供参考的范例。
|
||||
- CDH/HDP Kafka,大数据云公司提供的Kafka,内嵌Apache Kafka。优势在于操作简单,节省运维成本;缺陷在于把控度低,演进速度较慢。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/a2/11/a2ec80dceb9ba6eeaaeebc662f439211.jpg" alt="">
|
||||
|
||||
## 开放讨论
|
||||
|
||||
设想你是一家创业公司的架构师,公司最近准备改造现有系统,引入Kafka作为消息中间件衔接上下游业务。作为架构师的你会怎么选择合适的Kafka发行版呢?
|
||||
|
||||
欢迎你写下自己的思考或疑问,我们一起讨论 。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
|
||||
|
||||
|
||||
61
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/05 | 聊聊Kafka的版本号.md
Normal file
61
极客时间专栏/geek/Kafka核心技术与实战/Kafka入门/05 | 聊聊Kafka的版本号.md
Normal file
@@ -0,0 +1,61 @@
|
||||
<audio id="audio" title="05 | 聊聊Kafka的版本号" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/0a/d9/0a2078eee0647452a6fe68e5861dead9.mp3"></audio>
|
||||
|
||||
你好,我是胡夕。今天我想和你聊聊如何选择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时,会看到这样的版本:
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c1/23/c10df9e6f72126e9c721fba38e27ac23.png" alt="">
|
||||
|
||||
于是有些同学就会纳闷,难道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版本都有它恰当的使用场景和独特的优缺点,切记不要一味追求最新版本。事实上我周围的很多工程师都秉承这样的观念:不要成为最新版本的“小白鼠”。了解了各个版本的差异之后,我相信你一定能够根据自己的实际情况做出最正确的选择。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/9b/d1/9be3f8c5c2930f6482fb43d8bca507d1.jpg" alt="">
|
||||
|
||||
## 开放讨论
|
||||
|
||||
如何评估Kafka版本升级这件事呢?你和你所在的团队有什么独特的见解?
|
||||
|
||||
欢迎你写下自己的思考或疑问,我们一起讨论 。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
|
||||
Reference in New Issue
Block a user