这一部分主要是接触 Kafka ,并熟悉 Kafka 的使用方式。快速熟练的搭建 kafka 服务,对于快速验证一些基于Kafka 的解决方案,也是非常有用的。
一、 Kafka 介绍
ChatGPT 对于 Apache Kafka 的介绍:
1 、 MQ 的作用
MQ : MessageQueue ,消息队列。 队列,是一种 FIFO 先进先出的数据结构。消息则是跨进程传递的数据。一个典型的MQ 系统,会将消息由生产者发送到 MQ 进行排队,然后根据一定的顺序交由消息的消费者进行处理
MQ 的作用主要有以下三个方面:
· 异步
例子:快递员发快递,直接到客户家效率会很低。引入菜鸟驿站后,快递员只需要把快递放到菜鸟驿站,就可以继续发其他快递去了。客户再按自己的时间安排去菜鸟驿站取快递。
作用:异步能提高系统的响应速度、吞吐量。
· 解耦
例子:《 Thinking in JAVA 》很经典,但是都是英文,我们看不懂,所以需要编辑社,将文章翻译成其他语言,这样就可以完成英语与其他语言的交流。
作用:
1 、服务之间进行解耦,才可以减少服务之间的影响。提高系统整体的稳定性以及可扩展性。
2 、另外,解耦后可以实现数据分发。生产者发送一个消息后,可以由一个或者多个消费者进行消费,并且消费者的增加或者减少对生产者没有影响。
· 削峰
例子:长江每年都会涨水,但是下游出水口的速度是基本稳定的,所以会涨水。引入三峡大坝后,可以把水储存起来,下游慢慢排水。
作用:以稳定的系统资源应对突发的流量冲击。
2 、为什么要用 Kafka
一个典型的日志聚合的应用场景:
业务场景决定了产品的特点。
1 、数据吞吐量很大: 需要能够快速收集各个渠道的海量日志
2 、集群容错性高:允许集群中少量节点崩溃
3 、功能不需要太复杂: Kafka 的设计目标是高吞吐、低延迟和可扩展,主要关注消息传递而不是消息处理。所以,Kafka 并没有支持死信队列、顺序消息等高级功能。
4 、允许少量数据丢失: Kafka 本身也在不断优化数据安全问题,目前基本上可以认为 Kafka 可以做到不会丢数据。
二、 Kafka 快速上手
1 、实验环境
准备了三台虚拟机 192.168.232.128~130 ,预备搭建三台机器的集群。
三台机器均预装 CentOS7 操作系统。分别配置机器名 worker1 , worker2 , worker3 。
然后需要关闭防火墙 ( 实验环境建议关闭 ) 。
然后三台机器上都需要安装 JAVA 。 JAVA 的安装过程就不多说了。实验中采用目前用得最多的 JAVA 8 版本就可以了。
下载 kafka ,选择当前最新的 3.2.0 版本。下载地址: https://kafka.apache.org/downloads 选择
kafka_2.13-3.4.0.tgz 进行下载。
下载 Zookeeper ,下载地址 https://zookeeper.apache.org/releases.html , Zookeeper 的版本并没有强制要求,这里我们选择比较新的3.6.1 版本。
下载完成后,将这两个工具包上传到三台服务器上,解压后,分别放到 /app/kafka 和 /app/zookeeper 目录下。并将部署目录下的bin 目录路径配置到 path 环境变量中。
2 、单机服务体验
下载下来的 Kafka 安装包不需要做任何的配置,就可以直接单击运行。这通常是快速了解 Kafka 的第一步。
1 、启动 Kafka 之前需要先启动 Zookeeper 。 这里就用 Kafka 自带的 Zookeeper 。启动脚本在 bin 目录下。
从 nohup.out 中可以看到 zookeeper 默认会在 2181 端口启动。通过 jps 指令看到一个 QuorumPeerMain 进程,确定服务启动成功。
2 、启动 Kafka 。
启动完成后,使用 jps 指令,看到一个 kafka 进程,确定服务启动成功。服务会默认在 9092 端口启动。
3 、简单收发消息
Kafka 的基础工作机制是消息发送者可以将消息发送到 kafka 上指定的 topic ,而消息消费者,可以从指定的topic上消费消息。
首先,可以使用 Kafka 提供的客户端脚本创建 Topic
然后,启动一个消息发送者端。往一个名为 test 的 Topic 发送消息。
当命令行出现 > 符号后,随意输入一些字符。 Ctrl+C 退出命令行。这样就完成了往 kafka 发消息的操作。
然后启动一个消息消费端,从名为 test 的 Topic 上接收消息。
这样就完成了一个基础的交互。这其中,生产者和消费者并不需要同时启动。他们之间可以进行数据交互,但是又并不依赖于对方。没有生产者,消费者依然可以正常工作,反过来,没有消费者,生产者也依然可以正常工作。这也体现出了生产者和消费者之间的解耦。
4 、其他消费模式
之前我们通过 kafka 提供的生产者和消费者脚本,启动了一个简单的消息生产者以及消息消费者,实际上,kafka还提供了丰富的消息消费方式。
指定消费进度
通过 kafka-console.consumer.sh 启动的控制台消费者,会将获取到的内容在命令行中输出。如果想要消费之前发送的消息,可以通过添加--from-begining 参数指定。
如果需要更精确的消费消息,甚至可以指定从哪一条消息开始消费。
这表示从第 0 号 Partition 上的第四个消息开始读起。 Partition 和 Offset 是什么呢,可以用以下指令查看。
分组消费
对于每个消费者,可以指定一个消费者组。 kafka 中的同一条消息,只能被同一个消费者组下的某一个消费者消费。而不属于同一个消费者组的其他消费者,也可以消费到这一条消息。在kafka-console-consumer.sh脚本中,可以通过 --consumer-property group.id=testGroup 来指定所属的消费者组。例如,可以启动三个消费者组,来验证一下分组消费机制:
查看消费者组的偏移量
接下来,还可以使用 kafka-consumer-groups.sh 观测消费者组的情况。包括他们的消费进度。
从这里可以看到,虽然业务上是通过 Topic 来分发消息的,但是实际上,消息是保存在 Partition 这样一个数据结构上的。
3 、理解 Kakfa 的消息传递机制
从之前的实验可以看到, Kafka 的消息发送者和消息消费者通过 Topic 这样一个逻辑概念来进行业务沟通。但是实际上,所有的消息是存在服务端的Partition 这样一个数据结构当中的。
在 Kafka 的技术体系中,有以下一些概念需要先熟悉起来:
· 客户端 Client : 包括消息生产者 和 消息消费者。之前简单接触过。
· 消费者组:每个消费者可以指定一个所属的消费者组,相同消费者组的消费者共同构成一个逻辑消费者组。每一个消息会被多个感兴趣的消费者组消费,但是在每一个消费者组内部,一个消息只会被消费一 次。
· 服务端 Broker :一个 Kafka 服务器就是一个 Broker 。
· 话题 Topic :这是一个逻辑概念,一个 Topic 被认为是业务含义相同的一组消息。客户端都通过绑定Topic来生产或者消费自己感兴趣的话题。
· 分区 Partition : Topic 只是一个逻辑概念,而 Partition 就是实际存储消息的组件。每个 Partiton 就是一个queue 队列结构。所有消息以 FIFO 先进先出的顺序保存在这些 Partition 分区中。
4 、 Kafka 集群服务
为什么要用集群?
单机服务下, Kafka 已经具备了非常高的性能。 TPS 能够达到百万级别。但是,在实际工作中使用时,单机搭建的Kafka 会有很大的局限性。
一方面:消息太多,需要分开保存。 Kafka 是面向海量消息设计的,一个 Topic 下的消息会非常多,单机服务很难存得下来。这些消息就需要分成不同的Partition ,分布到多个不同的 Broker 上。这样每个 Broker 就只需要保存一部分数据。这些分区的个数就称为分区数。
另一方面:服务不稳定,数据容易丢失。单机服务下,如果服务崩溃,数据就丢失了。为了保证数据安全,就需要给每个Partition 配置一个或多个备份,保证数据不丢失。 Kafka 的集群模式下,每个 Partition 都有一个或多个备份。Kafka 会通过一个统一的 Zookeeper 集群作为选举中心,给每个 Partition 选举出一个主节点Leader ,其他节点就是从节点 Follower 。主节点负责响应客户端的具体业务请求,并保存消息。而从节点则负责同步主节点的数据。当主节点发生故障时,Kafka 会选举出一个从节点成为新的主节点。
最后: Kafka 集群中的这些 Broker 信息,包括 Partition 的选举信息,都会保存在额外部署的 Zookeeper 集群当中,这样,kafka 集群就不会因为某一些 Broker 服务崩溃而中断。
Kafka 的集群架构大体是这样的:
接下来我们就动手部署一个 Kafka 集群,来体验一下 Kafka 是如何面向海量数据进行横向扩展的。
我们先来部署一个基于 Zookeeper 的 Kafka 集群。其中,选举中心部分, Zookeeper 是一种多数同意的选举机制,允许集群中少数节点出现故障。因此,在搭建集群时,通常都是采用3 , 5 , 7 这样的奇数节点,这样可以最大化集群的高可用特性。 在后续的实验过程中,我们会在三台服务器上都部署Zookeeper 和Kafka。
1 、部署 Zookeeper 集群
这里采用之前单独下载的 Zookeeper 来部署集群。 Zookeeper 是一种多数同意的选举机制,允许集群中少半数节点出现故障。因此,在搭建集群时,通常采用奇数节点,这样可以最大化集群的高可用特性。在后续的实现过程中,我们会在三台服务器上都部署Zookeeper 。
先将下载下来的 Zookeeper 解压到 /app/zookeeper 目录。
然后进入 conf 目录,修改配置文件。在 conf 目录中,提供了一个 zoo_sample.cfg 文件,这是一个示例文件。我们只需要将这个文件复制一份zoo.cfg(cp zoo_sample.cfg zoo.cfg) ,修改下其中的关键配置就可以了。其中比较关键的修改参数如下:
接下来将整个 Zookeeper 的应用目录分发到另外两台机器上。就可以在三台机器上都启动 Zookeeper 服务了。
启动完成后,使用 jps 指令可以看到一个 QuorumPeerMain 进程就表示服务启动成功。
三台机器都启动完成后,可以查看下集群状态。
2 、部署 Kafka 集群
kafka 服务并不需要进行选举,因此也没有奇数台服务的建议。
部署 Kafka 的方式跟部署 Zookeeper 差不多,就是解压、配置、启服务三板斧。
首先将 Kafka 解压到 /app/kafka 目录下。
然后进入 config 目录,修改 server.properties 。这个配置文件里面的配置项非常多,下面列出几个要重点关注的配置。
接下来就可以启动 kafka 服务了。启动服务时需要指定配置文件。
通过 jps 指令可以查看 Kafka 的进程。
5 、理解服务端的 Topic 、 Partition 和 Broker
接下来可以对比一下之前的单机服务,快速理解 Kafka 的集群当中核心的 Topic 、 Partition 、 Broker 。
从这里可以看到,
1 、 --create 创建集群,可以指定一些补充的参数。大部分的参数都可以在配置文件中指定默认值。
· partitons 参数表示分区数,这个 Topic 下的消息会分别存入这些不同的分区中。示例中创建的
disTopic ,指定了四个分区,也就是说这个 Topic 下的消息会划分为四个部分。
· replication-factor 表示每个分区有几个备份。示例中创建的 disTopic ,指定了每个 partition 有两个备份。
2 、 --describe 查看 Topic 信息。
· partiton 参数列出了四个 partition ,后面带有分区编号,用来标识这些分区。
· Leader 表示这一组 partiton 中的 Leader 节点是哪一个。这个 Leader 节点就是负责响应客户端请求的主节点。从这里可以看到,Kafka 中的每一个 Partition 都会分配 Leader ,也就是说每个 Partition 都有不同的节点来负责响应客户端的请求。这样就可以将客户端的请求做到尽量的分散。
· Replicas 参数表示这个 partition 的多个备份是分配在哪些 Broker 上的。也称为 AR 。这里的 0,1,2 就对应配置集群时指定的broker.id 。但是, Replicas 列出的只是一个逻辑上的分配情况,并不关心数据实际是不是按照这个分配。甚至有些节点服务挂了之后,Replicas 中也依然会列出节点的 ID 。
· ISR 参数表示 partition 的实际分配情况。他是 AR 的一个子集,只列出那些当前还存活,能够正常同步数据的那些Broker 节点。
接下来,我们还可以查看 Topic 下的 Partition 分布情况。在 Broker 上,与消息,联系最为紧密的,其实就是Partition 了。之前在配置 Kafka 集群时,指定了一个 log.dirs 属性,指向了一个服务器上的日志目录。进入这个目录,就能看到每个Broker 的实际数据承载情况。
从这里可以看到, Broker 上的一个 Partition 对应了日志目录中的一个目录。而这个 Partition 上的所有消息,就保存在这个对应的目录当中。
从整个过程可以看到, Kafka 当中, Topic 是一个数据集合的逻辑单元 。同一个 Topic 下的数据,实际上是存储在Partition 分区中的, Partition 就是数据存储的物理单元 。而 Broker 是 Partition 的物理载体 ,这些Partition分区会尽量均匀的分配到不同的 Broker 机器上。而之前接触到的 offset ,就是每个消息在 partition上的偏移量。
Kafka 为何要这样来设计 Topic 、 Partition 和 Broker 的关系呢?
1 、 Kafka 设计需要支持海量的数据,而这样庞大的数据量,一个 Broker 是存不下的。那就拆分成多个Partition,每个 Broker 只存一部分数据。这样 极大的扩展了集群的吞吐量 。
2 、每个 Partition 保留了一部分的消息副本,如果放到一个 Broker 上,就容易出现单点故障。所以就给每个Partition设计 Follower 节点,进行数据备份,从而保证数据安全。另外,多备份的 Partition 设计也 提高了读 取消息时的并发度 。
3 、在同一个 Topic 的多个 Partition 中,会产生一个 Partition 作为 Leader 。这个 Leader Partition 会负责响应客户端的请求,并将数据往其他Partition 分发。
6 、章节总结: Kafka 集群的整体结构
经过上面的实验,我们接触到了很多 Kafka 中的概念。将这些基础概念整合起来,就形成了 Kafka 集群的整体结构。这次我们先把这个整体结构梳理清楚,后续再一点点去了解其中的细节。
1 、 Topic 是一个逻辑概念, Producer 和 Consumer 通过 Topic 进行业务沟通。
2 、 Topic 并不存储数据, Topic 下的数据分为多组 Partition ,尽量平均的分散到各个 Broker 上。每组
Partition 包含 Topic 下一部分的消息。每组 Partition 包含一个 Leader Partition 以及若干个 Follower Partition进行备份,每组Partition 的个数称为备份因子 replica factor 。
3 、 Producer 将消息发送到对应的 Partition 上,然后 Consumer 通过 Partition 上的 Offset 偏移量,记录自己所属消费者组Group 在当前 Partition 上消费消息的进度。
4 、 Producer 发送给一个 Topic 的消息,会由 Kafka 推送给所有订阅了这个 Topic 的消费者组进行处理。但是在每个消费者组内部,只会有一个消费者实例处理这一条消息。
5 、最后, Kafka 的 Broker 通过 Zookeeper 组成集群。然后在这些 Broker 中,需要选举产生一个担任
Controller 角色的 Broker 。这个 Controller 的主要任务就是负责 Topic 的分配以及后续管理工作。在我们实验的集群中,这个Controller 实际上是通过 ZooKeeper 产生的。
三、 Kraft 集群 -- 了解
1 、 Kraft 集群简介
Kraft 是 Kafka 从 2.8.0 版本开始支持的一种新的集群架构方式。其目的主要是为了摆脱 Kafka 对 Zookeeper的依赖。因为以往基于Zookeeper 搭建的集群,增加了 Kafka 演进与运维的难度,逐渐开始成为 Kakfa 拥抱云原生的一种障碍。使用Kraft 集群后, Kafka 集群就不再需要依赖 Zookeeper ,将之前基于 Zookeeper 管理的集群数据,转为由Kafka 集群自己管理。
传统的 Kafka 集群,会将每个节点的状态信息统一保存在 Zookeeper 中,并通过 Zookeeper 动态选举产生一个Controller 节点,通过 Controller 节点来管理 Kafka 集群,比如触发 Partition 的选举。而在 Kraft 集群中,会固定配置几台Broker 节点来共同担任 Controller 的角色,各组 Partition 的 Leader 节点就会由这些Controller选举产生。原本保存在 Zookeeper 中的元数据也转而保存到 Controller 节点中。
新的 Kraft 集群相比传统基于 Zookeeper 的集群,有一些很明显的好处:
· Kafka 可以不依赖于外部框架独立运行。这样减少 Zookeeper 性能抖动对 Kafka 集群性能的影响,同时Kafka产品的版本迭代也更自由。
· Controller 不再由 Zookeeper 动态选举产生,而是由配置文件进行固定。这样比较适合配合一些高可用工具来保持集群的稳定性。
· Zookeeper 的产品特性决定了他不适合存储大量的数据,这对 Kafka 的集群规模 ( 确切的说应该是
Partition 规模 ) 是极大的限制。摆脱 Zookeeper 后,集群扩展时元数据的读写能力得到增强。
不过,由于分布式算法的复杂性。 Kraft 集群和同样基于 Raft 协议定制的 RocketMQ 的 Dledger 集群一样,都还在不太稳定,在真实企业开发中,用得相对还是比较少。
2 、配置 Kraft 集群
在 Kafka 的 config 目录下,提供了一个 kraft 的文件夹,在这里面就是 Kraft 协议的参考配置文件。在这个文件夹中有三个配置文件,broker.properties,controller.properties,server.properties ,分别给出了 Kraft 中三种不同角色的示例配置。
· broker.properties: 数据节点
· controller.properties: Controller 控制节点
· server.properties: 即可以是数据节点,又可以是 Controller 控制节点。
这里同样列出几个比较关键的配置项,按照自己的环境进行定制即可。
将配置文件分发,并修改每个服务器上的 node.id 属性和 advertised.listeners 属性。
由于 Kafka 的 Kraft 集群对数据格式有另外的要求,所以在启动 Kraft 集群前,还需要对日志目录进行格式化。
接下来就可以指定配置文件,启动 Kafka 的服务了。 例如,在 Worker1 上,启动 Broker 和 Controller 服务。
等三个服务都启动完成后,就可以像普通集群一样去创建 Topic ,并维护 Topic 的信息了。
Kafka快速实战以及基本原理详解
will.tsang2023-10-09 9:03
相关推荐
GitCode官方39 分钟前
GitCode 光引计划投稿 | GoIoT:开源分布式物联网开发平台小扳2 小时前
微服务篇-深入了解 MinIO 文件服务器(你还在使用阿里云 0SS 对象存储图片服务?教你使用 MinIO 文件服务器:实现从部署到具体使用)zquwei12 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket道一云黑板报15 小时前
Flink集群批作业实践:七析BI批作业执行qq_54702617915 小时前
Kafka 常见问题core51215 小时前
flink sink kafka飞来又飞去17 小时前
kafka sasl和acl之间的关系MZWeiei18 小时前
Zookeeper的监听机制莹雨潇潇18 小时前
Hadoop完全分布式环境部署浩哲Zhe19 小时前
RabbitMQ