Kafka原理分析

2023-11-17

在基础篇中我们介绍MQ的一些基础原理:这篇文章,我们针对kafka进行较深入的分析:

上篇文章中我们提到了kafka中一个名词broker,其实broker可以理解成为一台kafa服务器。

kafka的特性和功能:

在kafka设计之初是为了实时计算大数据量的场景:例如:

  • 运营活动场景:记录用户的浏览、搜索、点击、活跃度等行为。
  • 系统运维场景:监控服务器的 CPU、内存、请求耗时等性能指标。

 Kafka 从 0.8 版本开始,就已经在提供一些和数据处理有关的组件了,比如:

1、Kafka Streams:一个轻量化的流计算库,性质类似于 Spark、Flink。

2、Kafka Connect:一个数据同步工具,能将 Kafka 中的数据导入到关系数据库、Hadoop、搜索引擎中。

Kafka 的官网介绍提到的 3 种能力,也不难理解了:

1、数据的发布和订阅能力(消息队列)

2、数据的分布式存储能力(存储系统)

3、数据的实时处理能力(流处理引擎)

这样kafka的一些功能就比较清晰了。

kafka的消息模型:

我们尝试分析下 Kafka 的消息模型,看看它究竟是如何演化来的?

首先,为了将一份消息数据分发给多个消费者,并且每个消费者都能收到全量的消息,很自然的想到了广播。

一个生产者生产消息并发送到消息队列,由多个消费者消费队列中的消息。消息被消费后,被删除。

 针对广播的消息模型:如果遇到这样的场景、

比如说消息队列中有6条信息:

消费者1只想消费第1.3.5信息。消费者2只想消费2.4.6消息、

此时,MQ 想到了一个很聪明的办法:它将难题直接抛给了生产者,要求生产者在发送消息时,对消息进行逻辑上的分类,因此就演进出了我们熟知的 Topic 以及发布-订阅模型。

为了降低MQ的设计复杂度。Kafka引入topic的概念。

主要的目标:就是为了解决不同消费者消费不同消息类型的场景:

kafka引入topic(主题):由生产者将不同的消息进行分类:类型不同的消息,存放在不同的topic中。这样消费者就可以针对不同的消息类型,去消费不同topic数据。

假如现在又有了如下的应用场景:

针对上述设计方案:如果针对同一个消息类型即同一个Topic,有多个消费者需要去消费他:

此时如果利用单纯的单播模式,肯定满足不了要求:

有同学就会想到这种场景,复制同样的一个队列给消费者消费:这样设计有一个问题是随着消费者的数据增多,必然会引起队列的性能问题,kafka本身就是为了解决高并发的。显然这种设计不适合kafka的设计:此时kafka就想到了一个聪明的解决方案:

它将所有消息进行了持久化存储,由消费者自己各取所需,想取哪个消息,想什么时候取都行,只需要传递一个消息的 offset 即可。

这样消息就不会被删除。而是被持久化的存储。这也是为什么官方会将 Kakfa 同时定义成存储系统的原因。

从上面的信息我们可以得到的总结是:

  • Kafka 为实时日志流而生,要处理的并发和数据量非常大。可见,Kafka 本身就是一个高并发系统,它必然会遇到高并发场景下典型的三高挑战:高性能、高可用和高扩展
  • 为了简化实现的复杂度,Kafka 最终采用了很巧妙的消息模型:它将所有消息进行了持久化存储,让消费者自己各取所需,想取哪个消息,想什么时候取都行,只需要传递一个消息的 offset 进行拉取即可。

kafka的存储方案

  上面我们已经分析到为了解决多个消费者消费同一个Topic的问题、kafka设计成为存储系统。

那么接下来我们分析下kafka的存储方案。

面对海量数据,单机的存储容量和读写性能肯定有限,大家很容易想到一种存储方案:对数据进行分片存储这种方案在我们实际工作中也非常常见:

kafka为了解决存储的压力:也因此引入了Partition的概念:将数据进行物理分片。

其实partition是针对不同的topic进行细分。将topic的海量数据。均匀地分布在集群中的每台机器上,从而很好地解决了存储的扩展性问题。这里的均匀分布指的是同一个topic在MQ的集群中每台服务器中只会存在一个分区。

Partition便是kafka的最小部署单元、

  • Partition 是存储的关键所在,MQ「一发一存一消费」的核心流程必然围绕它展开。
  • Kafka 高并发设计中最难的三高问题都能和 Partition 关联起来。

那我们再看看消费端,它又是如何跟 Partition 结合并做到并行处理的?

从消费者来看,首先要满足两个基本诉求:

1、广播消费能力:同一个 Topic 可以被多个消费者订阅,一条消息能够被消费多次。

2、集群消费能力:当消费者本身也是集群时,每一条消息只能分发给集群中的一个消费者进行处理。

 为了满足这两点要求,Kafka 引出了消费组的概念,每个消费者都有一个对应的消费组,组间进行广播消费,组内进行集群消费。此外,Kafka 还限定了:每个 Partition 只能由消费组中的一个消费者进行消费。

如果要加快消息的处理速度,该如何做呢?也很简单,向消费组 2 中增加新的消费者即可,Kafka 将以 Partition 为单位重新做负载均衡。当增加到 4 个消费者时,每个消费者仅需处理 1 个 Partition,处理速度将提升两倍。

在 Kafka 集群中,每台机器都存储了一些 Partition,一旦某台机器宕机,上面的数据不就丢失了吗?

此时,你一定会想到对消息进行持久化存储,但是持久化只能解决一部分问题,它只能确保机器重启后,历史数据不丢失。但在机器恢复之前,这部分数据将一直无法访问。这对于高并发系统来说,是无法忍受的。

所以 Kafka 必须具备故障转移能力才行,当某台机器宕机后仍然能保证服务可用。

没错,Kafka 正是通过 Partition 的多副本机制解决了高可用问题。在 Kafka 集群中,每个 Partition 都有多个副本,同一分区的不同副本中保存的是相同的消息。

副本之间是 “一主多从” 的关系,其中 leader 副本负责读写请求,follower 副本只负责和 leader 副本同步消息,当 leader 副本发生故障时,它才有机会被选举成新的 leader 副本并对外提供服务,否则一直是待命状态。

现在,我假设 Kafka 集群中有 4 台服务器,主题 A 和主题 B 都有两个 Partition,且每个 Partition 各有两个副本,那最终的多副本架构将如下图所示:

  • Producer:生产者,负责创建消息,然后投递到 Kafka 集群中,投递时需要指定消息所属的 Topic,同时确定好发往哪个 Partition。
  • Consumer:消费者,会根据它所订阅的 Topic 以及所属的消费组,决定从哪些 Partition 中拉取消息。
  • Broker:消息服务器,可水平扩展,负责分区管理、消息的持久化、故障自动转移等。
  • Zookeeper:负责集群的元数据管理等功能,比如集群中有哪些 broker 节点以及 Topic,每个 Topic 又有哪些 Partition 等。

很显然,在 Kafka 整体架构中,Partition 是发送消息、存储消息、消费消息的纽带。吃透了它,再去理解整体架构,脉络会更加清晰。

总结上述:

  • Kafka 通过巧妙的模型设计,将自己退化成一个海量消息的存储系统。
  • 为了解决存储的扩展性问题,Kafka 对数据进行了水平拆分,引出了 Partition(分区),这是 Kafka 部署的基本单元,同时也是 Kafka 并发处理的最小粒度。
  • 对于一个高并发系统来说,还需要做到高可用,Kafka 通过 Partition 的多副本冗余机制进行故障转移,确保了高可靠。

Kafa副本同步机制:

Kafka每个topic的partition有N个副本,其中N是topic的复制因子。Kafka通过多副本机制实现故障自动转移,当Kafka集群中一个Broker失效情况下仍然保证服务可用。在Kafka中发生复制时确保partition的预写式日志有序地写到其他节点上。N个replicas中。其中一个replica为leader,其他都为follower,leader处理partition的所有读写请求,与此同时,follower会被动定期地去复制leader上的数据。


Kafka必须提供数据复制算法保证,如果leader发生故障或挂掉,一个新leader被选举并接收客户端的消息成功写入。Kafka确保从同步副本列表中选举一个副本为leader,或者换句话说,follower追赶leader数据。leader负责维护和跟踪ISR中所有follower滞后状态。当生产者发送一条消息到Broker,leader写入消息并复制到所有follower。消息提交之后才被成功复制到所有的同步副本。消息复制延迟受最慢的follower限制,重要的是快速检测慢副本,如果follower”落后”太多或者失效,leader将会把它从replicas从ISR移除。

是什么原因导致分区的副本与leader不同步


一个副本可以不同步Leader有如下几个原因
慢副本:在一定周期时间内follower不能追赶上leader。最常见的原因之一是I / O瓶颈导致follower追加复制消息速度慢于从leader拉取速度。
卡住副本:在一定周期时间内follower停止从leader拉取请求。follower replica卡住了是由于GC暂停或follower失效或死亡。
新启动副本:当用户给主题增加副本因子时,新的follower不在同步副本列表中,直到他们完全赶上了leader日志。
一个partition的follower落后于leader足够多时,被认为不在同步副本列表或处于滞后状态。在Kafka-0.8.2.x中,副本滞后判断依据是副本落后于leader最大消息数量(replica.lag.max.messages)或replicas响应partition leader的最长等待时间(replica.lag.time.max.ms)。前者是用来检测缓慢的副本,而后者是用来检测失效或死亡的副本


副本配置规则


笔者认为真正重要的事情是检测卡或慢副本,这段时间follower replica是“out-of-sync”落后于leader。在服务端现在只有一个参数需要配置replica.lag.time.max.ms。这个参数解释replicas响应partition leader的最长等待时间。检测卡住或失败副本的探测——如果一个replica失败导致发送拉取请求时间间隔超过replica.lag.time.max.ms。Kafka会认为此replica已经死亡会从同步副本列表从移除。检测慢副本机制发生了变化——如果一个replica开始落后leader超过replica.lag.time.max.ms。Kafka会认为太缓慢并且会从同步副本列表中移除。除非replica请求leader时间间隔大于replica.lag.time.max.ms,因此即使leader使流量激增和大批量写消息。Kafka也不会从同步副本列表从移除该副本。
 

参考文章:大佬的文章图文解释:

《吃透 MQ 系列》之扒开 Kafka 的神秘面纱

《吃透 MQ 系列》之 Kafka 架构设计的任督二脉

《吃透 MQ 系列》之 Kafka 存储选型的奥秘

 https://blog.csdn.net/lizhitao/article/details/51718185

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kafka原理分析 的相关文章

随机推荐

  • 学Java需要的英语水平以及关键词汇总

    还是需要英语的 但是是编程英语 和从小到大学的 英语 不是一回事 Java语言的输出语句 System out print 你好 此处的 System表示 系统 out表示 在 外面 print表示 打印 每一个单词之间使用 英文输入法的点
  • streamlit——搭建学生评分网站(告别问卷星)

    streamlit搭建多人评分网站 文章目录 streamlit搭建多人评分网站 一 引言 二 数据准备 三 streamlit代码 四 数据合并代码 一 引言 当需要对班级内多人进行打分时 为了不使用问卷星等平台进行评分 使用pandas
  • AJAX核心基础知识之倒计时抢购案例

    倒计时 分析 两个时间 目标时间 当前时间 目标时间 当前时间 计算时间差中包含多少小时 多少分钟 多少秒 每间隔一秒钟重新获取当前时间 定时器 重算时间 核心问题 1当前时间不可以获取客户端本地的 本地的时间客户可以肆意修改 获取服务器的
  • 遗传算法理解(通俗易懂)

    最近研究模糊识别的一些经典算法 为更好地理解遗传算法的运算过程 下面用手工计算来简单地模拟遗传算法的各个主要执行步骤 例 求下述二元函数的最大值 1 个体编码 遗传算法的运算对象是表示个体的符号串 所以必须把变量 x1 x2 编码为一种 符
  • Gitee问题解决1:Gitee如何下载历史提交版本

    1 把在线的git历史版本代码下载到本地 打开gitee某个项目的主页 点击统计 点击提交 能够看到自己历史的提交信息 选择需要下载版本出的浏览文件 通过左上方黄色框能够看到提交版本的id 之后点击克隆 下载 点击下载ZIP即可 解压 2
  • mysql中sql语句使日期增加一年

    mysql表中有一些字段是显示日期的 因为各种需要 需要将它时间往后调整1年 mysql 日期增加一年的更新语句更新的语句如下 UPDATE table SET date DATE ADD date INTERVAL 1 YEAR 如果要增
  • 递推和递归、迭代的关系简介

    递推和递归 迭代的关系简介 在编程里 递推关系可以通过递归或者迭代来实现 但是递归和迭代又不仅仅只能用来实现递推关 有更广泛的用途 递推 递归和迭代都是解决问题的方法 它们之间有一定的联系 递归和迭代可以用于实现递推关系 但它们也有各自独立
  • k8s中Endpoint是什么

    在Kubernetes K8s 中 Endpoint是一种资源对象 用于表示一个Service所依赖的真实后端节点的Pod信息 它存储了一组IP地址和端口号的列表 这些IP地址和端口号对应着提供相同服务的Pod实例 主要作用 Endpoin
  • 预估db2、oracle、teradata数据库sql执行代价和时间方法

    DB2 只能得到cost 1 执行存贮过程建表 CALL SYSPROC SYSINSTALLOBJECTS EXPLAIN C CAST NULL AS VARCHAR 128 数据库用户名 2 执行 EXPLAIN PLAN SET Q
  • Unity中容易被忽略的小技巧

    今天在游戏蛮牛上看到慕容小匹夫的一篇文章 感觉对自己现在的水平很实用 就给转载了过来 以便日后好温习一下 这里还是要支持原创作者 原文地址在这里 一 编辑器染色 一个常见的工作情景是我们在调整场景内的某些组件参数时 没有注意到自己是在Pla
  • iphone查看/private/var/mobile/Containers/Data/Application/文件

    xcode查看iPhone的private var 文件夹 xcode连接iPhone真机 选择app下载Containers文件夹到mac电脑中 查看手机中下载的文件 使用xcode真机调试的时候 文件目录都是这种 private var
  • 51单片机用c语言在液晶1602上显示汉字,51单片机LCD1602显示汉字(中文)源程序...

    include stc15f2k60s2 h define uchar unsigned char define uint unsigned int 数据端口接 P0 sbit lcdrs P2 7 端口定义 sbit lcdrw P2 6
  • php 自带过滤和转义函数

    php 自带过滤和转义函数 函数名 释义 介绍 htmlspecialchars 将与 单双引号 大于和小于号化成HTML格式 转成 amp 转成 quot 转成 039 lt 转成 lt gt 转成 gt htmlentities 所有字
  • LeGO-LOAM中的数学公式推导

    LeGO LOAM是一种在LOAM之上进行改进的激光雷达建图方法 建图效果比LOAM要好 但是建图较为稀疏 计算量也更小了 本文原地址 wykxwyc的博客 github注释后LeGO LOAM源码 LeGO LOAM NOTED 关于代码
  • c语言while break用法举例,c语言中continue和break的用法

    目前 随着计算机在人们生活和工作中的普及 其教学研究地位也在逐渐提升 C语言是一种计算机程序设计语言 其具有高级语言和汇编语言的特点 下面小编就跟你们详细介绍下c语言中continue和break的用法 希望对你们有用 c语言中contin
  • Git SSL certificate problem: unable to get local issuer certificate

    错误 Push failed Unable to access https github com ttsin gitTest git SSL certificate problem unable to get local issuer ce
  • Python物理数值解析

    让我们回忆一下库仑定律 来自位于 r 0 r 0 r0 处的单个点电荷 q 0 q 0
  • 自动驾驶是用Python实现的?你敢用吗?

    一 安装环境 gym是用于开发和比较强化学习算法的工具包 在python中安装gym库和其中子场景都较为简便 安装gym pip install gym 安装自动驾驶模块 这里使用Edouard Leurent发布在github上的包hig
  • eclipse汉化.设置为中文 简单好操作 java初学者看过来

    方法 1 查找语言包下载网址 并复制 2 打开eclipse 点击 help Install New Software Add 3 在 Location 中粘帖网址 点击 Add 4 勾选 简体中文包 5 等待加载完 重启 本教程操作环境
  • Kafka原理分析

    在基础篇中我们介绍MQ的一些基础原理 这篇文章 我们针对kafka进行较深入的分析 上篇文章中我们提到了kafka中一个名词broker 其实broker可以理解成为一台kafa服务器 kafka的特性和功能 在kafka设计之初是为了实时