大家好,我是吴哥。这是《吃透 MQ 系列》的第二集。某杉杉来晚了,被几位读者在后台催更新。真的对不起!这篇文章已经延迟了几个星期。最初的想法是:针对每一则具体的新闻,既要写得透彻,又要控制篇幅。写下来太难了,很难兼得。最后,我决定分成多篇。一方面可以加快输出频率;另一方面,大家更容易消化。废话不多说,第二弹开始。01为什么要从Kafka入手?《吃透 MQ 》开篇围绕MQ的本质“一帖一存一消费”,讲解了MQ的常识,系统地回答:如何开始设计一个MQ?从本文开始,我将对具体的消息中间件进行讲解。之所以选择入手Kafka,是出于三方面的考虑:第一,RocketMQ和Kafka是目前最流行的两种消息中间件,互联网公司使用最为广泛。重点。其次,从MQ的发展来看,Kafka早于RocketMQ诞生,阿里团队在实现RocketMQ时充分借鉴了Kafka的设计思路。掌握了Kafka的设计原理之后,后面理解RocketMQ就会容易很多。第三,Kafka其实是一个轻量级的MQ。它具有MQ最基本的能力,但不支持延迟队列、重试机制等高级特性,从而降低了实现的复杂度。从Kafka入手,将帮助你快速掌握MQ的核心。交代完背景,请跟随我的思路,由浅入深地分析一下Kafka。02揭开Kafka的面纱在深入分析一项技术之前,不建议了解架构和技术细节,而是先搞清楚它是什么?它是为了解决什么问题而创建的?掌握了这些背景知识后,有助于我们理解其背后的设计考虑和设计思路。写这篇文章的时候,查阅了很多资料。Kafka的定义可以说是五花八门,不仔细研究很容易搞混。我们先看看Kafka官网给出的定义:ApacheKafka是一个开源的分布式事件流平台。翻译成中文就是:ApacheKafka是一个开源的分布式流处理平台。Kafka不是消息系统吗?为什么叫分布式流处理平台?两者是一回事吗?一定有读者有这样的疑问。要说明这个问题,还得从卡夫卡诞生崛起的背景说起。Kafka最初是Linkedin的内部孵化项目。设计之初,将其视为“数据管道”,处理以下两种场景:1.运营活动场景:记录用户的浏览、搜索、点击、活动等行为。2、系统运维场景:监控CPU、内存、请求耗时等服务器性能指标。可以看出,这两种数据都属于日志类,特点是:数据是实时产生的,数据量大。Linkedin一开始也尝试过使用ActiveMQ来解决数据传输问题,但是性能达不到要求,后来决定自己开发Kafka。所以从一开始,Kafka就是为实时日志流而生的。了解了这个背景,就不难理解Kafka和流数据的关系,以及为什么Kafka在大数据领域应用如此广泛?也是因为它本来就是为了解决大数据的管道问题而诞生的。然后解释一下:为什么官方将Kafka定义为流处理平台?不是提供数据通道能力吗,为什么跟平台有关?这是因为Kafka一直提供一些与数据处理相关的Components,例如:1.KafkaStreams:一个轻量级的流计算库,本质上类似于Spark和Flink。2.KafkaConnect:一个数据同步工具,可以将数据从Kafka导入到关系型数据库、Hadoop、搜索引擎中。可见,Kafka的野心不仅仅是一个消息系统,它早就朝着“实时流处理平台”的方向发展了。这时候就不难理解Kafka官网介绍中提到的三种能力:1.数据发布订阅能力(消息队列)2.数据分布式存储能力(存储系统)3.数据这样,kafka的发展历史和定义基本清楚。当然,本系列只关注Kafka的前两个能力,因为这两个能力都与MQ强相关。03从Kafka的消息模型入手,了解Kafka的定位和诞生背景,然后分析Kafka的设计思路。我在上一篇文章中提到:要深入了解一个MQ,建议从“消息模型”这一核心理论层面入手,而不是一上来就看技术架构,千万不要不要直接进入技术细节。所谓消息模型,可以理解为一种逻辑结构,是技术架构之上的抽象层,往往暗含核心设计思想。我们试着分析一下Kafka的消息模型,看看它是如何演变而来的?首先,为了将一条消息数据分发给多个消费者,并且每个消费者都能收到全量的消息,自然而然就想到了广播。那么问题来了:消息来了,广播给所有的消费者,但并不是每个消费者都想要所有的消息。比如消费者A只想要消息1、2、3,而消费者B只想要消息4、5、6,这时候怎么办呢?这个问题的关键点在于:MQ不理解消息的语义,根本无法对消息进行分类和传递。这时候,MQ想到了一个很巧妙的办法:直接把问题丢给生产者,要求生产者在发送消息的时候对消息进行逻辑分类,于是演化出了大家熟知的Topic和Publish-Subscription模型。这样消费者只需要订阅自己感兴趣的Topic,然后从Topic中获取消息即可。但是这样做之后还有一个问题:如果多个消费者对同一个Topic感兴趣(下图中的消费者C),如何解决呢?如果采用传统的队列模式(单播),那么当一个消费者从队列中取消息时,该消息会被删除,其他消费者将无法获取。这时候很自然地想到了下面的解决方案:即在topic中添加新的消费者时,“复制”一个相同的数据队列。这个问题是解决了,但是随着下游消费者数量的增加,会导致MQ性能快速下降。尤其是对于为应对大数据场景而生的Kafka来说,这种复制操作的成本显然太高了。这时候,就有了Kafka最画龙点睛的解决方案之一:它把所有的消息都持久化存储起来,消费者可以得到自己需要的,想要的消息,想要得到的时候,只需要传递一个消息偏移量就可以了.这样一个根本性的改变,将复杂的消费问题完全转移到了消费者身上,大大降低了Kafka本身的复杂度,从而为它的高性能、高扩展性打下了良好的基础。(这就是Kafka和ActiveMQ、RabbitMQ的核心区别)最后简化一下,就是下图:这是Kafka原始的消息模型。这也在第二章间接解释了:为什么官方同时将Kakfa定义为存储系统。当然,Kafka的精美设计远不止这些。由于篇幅原因,后面的文章会继续分析。04写在最后这篇文章从Kafka的诞生背景说起,带大家厘清Kafka的定义以及它要解决的问题。另外,一步步分析了Kafka的消息模型和设计思路,这是Kafka的顶层抽象。本文转载自微信公众号《五哥谈IT》,可通过以下二维码关注。转载本文请联系五哥谈IT公众号。
