这篇文章向你展示了如何认识卡夫卡。内容简洁易懂。一定会让你眼前一亮。希望通过这篇文章的详细介绍,你能有所收获。
今天我们来谈谈卡夫卡,主要是带大家重新认识卡夫卡,谈谈卡夫卡中的一些重要概念和问题。
现在我们经常提到Kafka缺省情况下是一个非常好的消息队列,我们也会经常把它和RocketMQ、RabbitMQ进行比较。我认为与其他消息队列相比,卡夫卡的主要优势如下:
极致性能:基于Scala和Java语言开发,设计中广泛使用了批处理和异步的思想,每秒可以处理数千万条消息。
生态系统兼容性无与伦比:卡夫卡与周围生态系统的兼容性是最好的之一,尤其是在大数据和流计算领域。
事实上,卡夫卡在早期并不是一个合格的消息队列。早期的卡夫卡就像是消息队列领域的一个衣衫褴褛的孩子,功能不全,还有一些小问题,比如消息缺失,不能保证消息可靠性等等。当然,这也和LinkedIn最早开发的处理海量日志的卡夫卡有很大关系。哈哈哈哈,人们一开始并不想成为消息队列,但是谁知道后来这个错误在消息队列领域占据了一席之地。
随着后来的发展,这些缺点逐渐被卡夫卡修复和完善。所以* *,卡夫卡作为消息队列不靠谱的说法已经过时了!**
初识 Kafka
来看看官网的介绍吧,应该是最权威最实时的。如果是英语也没关系。我已经为你提取了所有更重要的信息。
我们可以从官方介绍中获得以下信息:
Kafka是一个分布式流处理平台。这到底是什么意思?
流媒体平台有三个关键功能:
消息队列:发布和订阅消息流。这个功能类似于消息队列,这就是为什么卡夫卡也被归类为消息队列。
容错持久化方式存储记录的消息流:Kafka将消息持久化到磁盘,有效避免消息丢失middot的风险;
流处理平台:消息发布时进行处理。卡夫卡提供了一个完整的流媒体类库。
Kafka有两个主要的应用场景:
消息队列:建立实时流数据管道,在系统或应用程序之间可靠地获取数据。
数据处理:构建实时流数据处理程序,对数据流进行转换或处理。
关于卡夫卡的几个非常重要的概念:
Kafka将记录的流(流数据)存储在主题中。
每条记录由一个关键字、一个值和一个时间戳组成。
Kafka 消息模型
“题外话:早期的JMS和AMQP是消息服务领域权威组织制定的相关标准,我在JavaGuide的文章《消息队列其实很简单》中介绍过。但是这些标准的演进跟不上消息队列的演进速度,这些标准实际上已经过时了。因此,不同的消息队列可能有自己的消息模型。
”队列模型:早期的消息模型
队列被用作消息通信载体,以满足生产者-消费者模型。一条消息只能由一个使用者使用,未被使用的消息将保留在队列中,直到它们被使用或超时。例如,如果我们的生产者发送100条消息,两个消费者将消费。一般两个消费者会按照发送消息的顺序(即一个给你,一个给我)各消费一半。)
队列模型存在的问题
假设有一种情况,我们需要将生产者生成的消息分发给多个消费者,每个消费者都可以接收到完整的消息内容。
在这种情况下,队列模型不容易解决。许多老练的人说:我们可以为每个消费者创建一个单独的队列,让生产者发送多个副本。这是一种非常愚蠢的做法,浪费了资源,违背了使用消息队列的目的。
发布-订阅模型:Kafka 消息模型
怎样认识 Kafka">
发布-订阅模型主要是为了解决队列模型存在的问题。
发布订阅模型(Pub-Sub) 使用主题(Topic) 作为消息通信载体,类似于广播模式;发布者发布一条消息,该消息通过主题传递给所有的订阅者,在一条消息广播之后才订阅的用户则是收不到该条消息的。
在发布 - 订阅模型中,如果只有一个订阅者,那它和队列模型就基本是一样的了。所以说,发布 - 订阅模型在功能层面上是可以兼容队列模型的。
Kafka 采用的就是发布 - 订阅模型。 如下图所示:
“RocketMQ 的消息模型和 Kafka 基本是完全一样的。唯一的区别是 RocketMQ 中没有队列这个概念,与之对应的是 Partion(分区)。
”Kafka 重要概念解读
Kafka 将生产者发布的消息发送到 Topic(主题) 中,需要这些消息的消费者可以订阅这些 Topic(主题),如下图所示:
Kafka Topic Partition
上面这张图也为我们引出了,Kafka 比较重要的几个概念:
-
Producer(生产者) : 产生消息的一方。
-
Consumer(消费者) : 消费消息的一方。
-
Broker(代理) : 可以看作是一个独立的 Kafka 实例。多个 Kafka Broker 组成一个 Kafka Cluster。
同时,你一定也注意到每个 Broker 中又包含了 Topic 以及 Partion 这两个重要的概念:
-
Topic(主题) : Producer 将消息发送到特定的主题,Consumer 通过订阅特定的 Topic(主题) 来消费消息。
-
Partion(分区) : Partion 属于 Topic 的一部分。一个 Topic 可以有多个 Partion ,并且同一 Topic 下的 Partion 可以分布在不同的 Broker 上,这也就表明一个 Topic 可以横跨多个 Broker 。这正如我上面所画的图一样。
“划重点:Kafka 中的 Partion(分区) 实际上可以对应成为消息队列中的队列。这样是不是更好理解一点?”
另外,还有一点我觉得比较重要的是 Kafka 为分区(Partion)引入了多副本(Replica)机制。分区(Partion)中的多个副本之间会有一个叫做 leader 的家伙,其他副本称为 follower。我们发送的消息会被发送到 leader 副本,然后 follower 副本才能从 leader 副本中拉取消息进行同步。
“生产者和消费者只与 leader 副本交互。你可以理解为其他副本只是 leader 副本的拷贝,它们的存在只是为了保证消息存储的安全性。当 leader 副本发生故障时会从 follower 中选举出一个 leader,但是 follower 中如果有和 leader 同步程度达不到要求的参加不了 leader 的竞选。
”Kafka 的多分区(Partition)以及多副本(Replica)机制有什么好处呢?
-
Kafka 通过给特定 Topic 指定多个 Partition, 而各个 Partition 可以分布在不同的 Broker 上, 这样便能提供比较好的并发能力(负载均衡)。
-
Partition 可以指定对应的 Replica 数, 这也极大地提高了消息存储的安全性, 提高了容灾能力,不过也相应的增加了所需要的存储空间。
Zookeeper 在 Kafka 中的作用
“要想搞懂 zookeeper 在 Kafka 中的作用 一定要自己搭建一个 Kafka 环境然后自己进 zookeeper 去看一下有哪些文件夹和 Kafka 有关,每个节点又保存了什么信息。 一定不要光看不实践,这样学来的也终会忘记!”
后面的文章中会介绍如何搭建 Kafka 环境,你且不要急,看了后续文章 3 分钟就能搭建一个 Kafka 环境。
“这部分内容参考和借鉴了这篇文章:https://www.jianshu.com/p/a036405f989c 。”
下图就是我的本地 Zookeeper ,它成功和我本地的 Kafka 关联上(以下文件夹结构借助 idea 插件 Zookeeper tool 实现)。
ZooKeeper 主要为 Kafka 提供元数据的管理的功能。
从图中我们可以看出,Zookeeper 主要为 Kafka 做了下面这些事情:
-
Broker 注册 :在 Zookeeper 上会有一个专门用来进行 Broker 服务器列表记录的节点。每个 Broker 在启动时,都会到 Zookeeper 上进行注册,即到/brokers/ids 下创建属于自己的节点。每个 Broker 就会将自己的 IP 地址和端口等信息记录到该节点中去
-
Topic 注册 :在 Kafka 中,同一个Topic 的消息会被分成多个分区并将其分布在多个 Broker 上,这些分区信息及与 Broker 的对应关系也都是由 Zookeeper 在维护。比如我创建了一个名字为 my-topic 的主题并且它有两个分区,对应到 zookeeper 中会创建这些文件夹:/brokers/topics/my-topic/partions/0、/brokers/topics/my-topic/partions/1
-
负载均衡 :上面也说过了 Kafka 通过给特定 Topic 指定多个 Partition, 而各个 Partition 可以分布在不同的 Broker 上, 这样便能提供比较好的并发能力。对于同一个 Topic 的不同 Partition,Kafka 会尽力将这些 Partition 分布到不同的 Broker 服务器上。当生产者产生消息后也会尽量投递到不同 Broker 的 Partition 里面。当 Consumer 消费的时候,Zookeeper 可以根据当前的 Partition 数量以及 Consumer 数量来实现动态负载均衡。
-
......
Kafka 如何保证消息的消费顺序?
我们在使用消息队列的过程中经常有业务场景需要严格保证消息的消费顺序,比如我们同时发了 2 个消息,这 2 个消息对应的操作分别对应的数据库操作是:更改用户会员等级、根据会员等级计算订单价格。假如这两条消息的消费顺序不一样造成的最终结果就会截然不同。
我们知道 Kafka 中 Partition(分区)是真正保存消息的地方,我们发送的消息都被放在了这里。而我们的 Partition(分区) 又存在于 Topic(主题) 这个概念中,并且我们可以给特定 Topic 指定多个 Partition。
Kafka Topic Partions Layout
每次添加消息到 Partition(分区) 的时候都会采用尾加法,如上图所示。Kafka 只能为我们保证 Partition(分区) 中的消息有序,而不能保证 Topic(主题) 中的 Partition(分区) 的有序。
“消息在被追加到 Partition(分区)的时候都会分配一个特定的偏移量(offset)。Kafka 通过偏移量(offset)来保证消息在分区内的顺序性。”
所以,我们就有一种很简单的保证消息消费顺序的方法:1 个 Topic 只对应一个 Partion。这样当然可以解决问题,但是破坏了 Kafka 的设计初衷。
Kafka 中发送 1 条消息的时候,可以指定 topic, partition, key,data(数据) 4 个参数。如果你发送消息的时候指定了 partion 的话,所有消息都会被发送到指定的 partion。并且,同一个 key 的消息可以保证只发送到同一个 partition,这个我们可以采用表/对象的 id 来作为 key 。
总结一下,对于如何保证 Kafka 中消息消费的顺序,有了下面两种方法:
-
1 个 Topic 只对应一个 Partion。
-
(推荐)发送消息的时候指定 key/partion。
当然不仅仅只有上面两种方法,上面两种方法是我觉得比较好理解的,
上述内容就是怎样认识 Kafka,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/147016.html