Kafka基本原理详解

(一)概念理解

Apache Kafka是一种开源的分布式流处理平台,专为高性能、高吞吐量的实时数据处理而设计。它最初由LinkedIn公司开发,旨在解决其网站活动中产生的大量实时数据处理和传输问题,后来于2011年开源,并捐赠给了Apache软件基金会,逐渐发展成为大数据和实时数据管道领域的核心组件之一。

(1)产生背景

在Kafka诞生之前,很多大型互联网公司面临着处理海量实时数据的挑战,这些数据通常来源于用户活动跟踪、日志生成、传感器数据、金融交易等。传统的消息队列系统,如RabbitMQ或ActiveMQ,虽然能够处理消息传递,但在处理极高吞吐量、大规模数据存储以及实时分析方面显得力不从心。具体来说,这些挑战包括:

  1. 高吞吐量需求:传统的消息系统难以应对每秒数百万条消息的处理需求。
  2. 可扩展性问题:随着数据量的快速增长,系统需要能够容易地横向扩展。
  3. 数据持久化与实时处理:需要一种既能快速处理数据,又能保证数据可靠存储的解决方案,以便进行即时分析和事后分析。
  4. 复杂的数据流处理:随着业务需求的增长,单一的消息传递已不能满足,需要一个能够支持复杂数据处理逻辑的平台。

(2)关键特性

Kafka正是为了解决这些问题而设计的,它的关键特性包括:

  • 高吞吐量:通过优化磁盘I/O、批量处理和零拷贝技术,Kafka能够达到非常高的数据处理速度。
  • 分布式架构:支持数据的分区和复制,既提高了系统的可用性,也使得系统可以横向扩展以应对更大的数据量。
  • 持久化与实时性:Kafka的消息被持久化到磁盘,并且支持实时消费,实现了数据的可靠存储与近实时处理的平衡。
  • 灵活的消息模型:支持发布-订阅模式和队列模式,满足不同场景的需求。
  • 生态丰富:Kafka不仅仅是消息队列,还发展出了Kafka Streams用于流处理,以及与其他大数据处理框架(如Apache Spark、Flink)的紧密集成,形成了强大的数据处理生态系统。

(3)应用场景

  • 日志收集与处理: Kafka常用于收集各种服务的日志数据,便于日志分析和监控。
  • 实时流处理: 结合Spark、Flink等流处理框架,Kafka可以用于实时数据分析和决策。
  • 事件驱动架构: Kafka作为消息中间件,支撑微服务间的解耦通信,实现事件驱动的系统设计。
  • 数据集成: Kafka可以作为不同数据源和数据仓库之间的桥梁,支持数据的实时同步和ETL流程。
  • 用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。
  • 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。

(二)消息队列的通信模式

(1)点对点(P2P)模式

在点对点模式中,消息队列扮演着“中间人”的角色,用于连接一个消息生产者(发送者)和一个或多个消息消费者(接收者),但是每条消息只会被一个消费者接收和处理。

(2)发布/订阅(Pub/Sub)模式

发布/订阅模式与点对点模式的主要区别在于消息的分发方式。在这种模式下,消息生产者发布消息到一个主题(Topic)上,所有订阅了这个主题的消费者都能收到该主题下的所有消息。

(三) Kafka设计架构

(1)基础架构与名词解释

  • Producer:Producer即生产者,消息的产生者,是消息的入口。
  • Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等……
  • Topic:消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。
  • Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是一个一个的文件夹!
  • Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。
  • Message:每一条发送的消息主体。
  • Consumer:消费者,即消息的消费方,是消息的出口。
  • Consumer Group:我们可以将多个消费组组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量!
  • Zookeeper:kafka集群依赖zookeeper来保存集群的的元信息,来保证系统的可用性。

 (2)工作流程分析

1.发送数据

我们看上面的架构图中,producer就是生产者,是数据的入口。注意看图中的箭头,Producer在写入数据的时候永远的找leader,不会直接将数据写入follower!那leader怎么找呢?写入的流程又是什么样的呢?我们看下图:
在这里插入图片描述
发送的流程就在图中已经说明了,就不单独在文字列出来了!需要注意的一点是,消息写入leader后,follower是主动的去leader进行同步的!producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的!写入示意图如下:
在这里插入图片描述
上面说到数据会写入到不同的分区,那kafka为什么要做分区呢?相信大家应该也能猜到,分区的主要目的是:

  1. 方便扩展:因为一个topic可以有多个partition,所以我们可以通过扩展机器去轻松的应对日益增长的数据量。
  2. 提高并发:以partition为读写单位,可以多个消费者同时消费数据,提高了消息的处理效率。

在Kafka中,当一个topic拥有多个partition时,producer会通过特定的策略决定数据发送至哪个:

  1. 指定分区(Manual Partitioning):生产者在发送消息时,可以明确指定消息应写入哪个分区。这种方式给予生产者最大的控制权,适用于需要确保某些消息逻辑上相邻或者实现特定消息处理顺序的场景。例如,如果消息关联到特定用户且希望该用户的所有消息保持顺序,可以通过用户ID作为分区键来实现。

  2. 基于键的分区(Key-based Partitioning):如果生产者没有明确指定分区,但是设置了消息的键(key),Kafka会使用该键的哈希值来决定消息的分区。这种方式可以自然地实现某种程度的消息排序和分组,因为具有相同键的消息会被发送到相同的分区。例如,使用用户ID作为键可以确保来自同一用户的请求被顺序处理,尽管这要求消费者端也要按照分区消费并处理消息顺序。

  3. 轮询分区(Round-Robin Partitioning):当生产者既没有指定分区,也没有为消息设置键时,Kafka会采用轮询的方式将消息均匀地分配到各个分区。这种方法简单且有效,可以很好地分散写入负载,确保没有单个分区过载,适合对消息顺序没有严格要求的场景。

Kafka通过ACK应答机制确保消息在生产者向队列写入时不丢失,允许用户根据可靠性需求选择不同级别的确认策略:

  • acks=0策略牺牲数据安全性换取最高写入效率,不等待任何确认直接认为消息发送成功。
  • acks=1策略在消息被首领节点接收后即确认,平衡了可靠性和性能,确保至少被一个副本接收。
  • acks=all策略最为安全,需等待所有副本(包括首领和跟随者)确认消息,确保数据得到备份,但牺牲了一定的写入效率。

若尝试向未创建的Topic发送消息,Kafka默认配置下会自动创建该Topic,初始化其分区数为1,且副本数也为1,虽确保消息发送成功,但这种自动创建行为可能不符合特定场景的安全或性能要求,故生产环境中通常会预先定义Topic并配置合适的分区和副本数量。

2.保存数据

Producer将数据写入kafka后,集群就需要对数据进行保存了!kafka将数据保存在磁盘,可能在我们的一般的认知里,写入磁盘是比较耗时的操作,不适合这种高并发的组件。Kafka初始会单独开辟一块磁盘空间,顺序写入数据(效率比随机写入高)。

(四)Kafka 文件存储架构

这里比较好理解:

一个Topic分别存储在不同的partition中
一个partitioin对应着多个replica备份
一个replica对应着一个Log
一个Log对应多个LogSegment
而在LogSegment中存储着log文件、索引文件、其它文件

(1)Message结构

上面说到log文件就实际是存储message的地方,我们在producer往kafka写入的也是一条一条的message,那存储在log中的message是什么样子的呢?消息主要包含消息体、消息大小、offset、压缩类型……等等!我们重点需要知道的是下面三个:

  • offset:offset是一个占8byte的有序id号,它可以唯一确定每条消息在parition内的位置!
  • 消息大小:消息大小占用4byte,用于描述消息的大小。
  • 消息体:消息体存放的是实际的消息数据(被压缩过),占用的空间根据具体的消息而不一样。

(2)存储策略

无论消息是否被消费,kafka都会保存所有的消息。那对于旧数据有什么删除策略呢?

  • 基于时间,默认配置是168小时(7天)。
  • 基于大小,默认配置是1073741824。

需要注意的是,kafka读取特定消息的时间复杂度是O(1),所以这里删除过期的文件并不会提高kafka的性能!

(五)Kafka 消费者架构

消费者使用一个 消费组 名称来进行标识,发布到topic中的每条记录被分配给订阅消费组中的一个消费者实例.消费者实例可以分布在多个进程中或者多个机器上。 

如果所有的消费者实例在同一消费组中,消息记录会负载平衡到每一个消费者实例.

如果所有的消费者实例在不同的消费组中,每条消息记录会广播到所有的消费者进程.

消息存储在log文件后,消费者就可以进行消费了。在讲消息队列通信的两种模式的时候讲到过点对点模式和发布订阅模式。Kafka采用的是发布订阅模式,消费者主动的去kafka集群拉取消息,与producer相同的是,消费者在拉取消息的时候也是找leader去拉取。

(1)消费数据

多个消费者可以组成一个消费者组(consumer group),每个消费者组都有一个组id!同一个消费组者的消费者可以消费同一topic下不同分区的数据,但是不会组内多个消费者消费同一分区的数据!!!我们看下图:
在这里插入图片描述
图示是消费者组内的消费者小于partition数量的情况,所以会出现某个消费者消费多个partition数据的情况,消费的速度也就不及只处理一个partition的消费者的处理速度!如果是消费者组的消费者多于partition的数量,那会不会出现多个消费者消费同一个partition的数据呢?上面已经提到过不会出现这种情况!多出来的消费者不消费任何partition的数据。所以在实际的应用中,建议消费者组的consumer的数量与partition的数量一致

参考文章:

Kafka基本原理详解(超详细!)_kafka工作原理-CSDN博客

Kafka 设计架构原理详细解析(超详细图解)_kafka架构原理-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/762350.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年7月1日 (周一) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键,实现一键唤起、一键隐藏的 Windows 工具,并且支持窗口动态绑定快捷键(无需设置自动实现)。 喜马拉雅下载工具: 字面意思 《星刃》早期概念图分享 末世破败环境推主Genki分享了《星…

ROS2在rviz2中实时显示轨迹和点

本文是将《ROS在rviz中实时显示轨迹和点》博客中rviz轨迹显示转为ROS2环境中的rviz2显示。 ros2的工作空间创建这里就不展示了。 包的创建 ros2 pkg create --build-type ament_cmake showpath --dependencies rclcpp nav_msgs geometry_msgs tf2_geometry_msgsshowpath.cpp…

公网环境使用Potplayer远程访问家中群晖NAS搭建的WebDAV听歌看电影

文章目录 前言1 使用环境要求:2 配置webdav3 测试局域网使用potplayer访问webdav4 内网穿透,映射至公网5 使用固定地址在potplayer访问webdav 前言 本文主要介绍如何在Windows设备使用potplayer播放器远程访问本地局域网的群晖NAS中的影视资源&#xff…

dedecms无法采集怎么办

dedecms无法采集解决方法:1、检查是否设置了正确的采集规则和路径,确保dedecms能够正常访问目标网站,并且有足够的权限进行采集操作;2、尝试使用代理服务器进行采集,或者通过破解验证码的方式绕过网站的反爬虫机制&…

Vue3学习笔记<->创建第一个vue项目(2)

新建一个项目目录 找一个盘新建一个目录,我这里在D盘创建一个vuedemo目录作为项目存放的目录。使用idea打开目录。   单击ieda底部的按钮“Terminal”,打开命令行窗口,如果命令行窗口当前目录不是“vuedemo”,就切换到“vuedem…

2024第17届中国西部(重庆)留学移民海外置业展览会

2024第17届中国西部(重庆)留学移民海外置业展览会 邀请函 主办单位: 中国西部教体医融合博览会组委会 承办单位:重庆中博展览有限公司 展会背景: 成都和重庆是中国新一线城市,是西部经济的核心增长极&a…

OpenStack开源虚拟化平台(一)

目录 一、OpenStack背景介绍(一)OpenStack是什么(二)OpenStack的主要服务 二、计算服务Nova(一)Nova组件介绍(二)Libvirt简介(三)Nova中的RabbitMQ解析 OpenS…

KUKA机器人不同运行方式

KUKA机器人有以下四种运行方式: 1、手动慢速运行(T1) 2、手动快速运行(T2) 3、自动运行(AUT) 4、外部自动运行(AUT EXT) 将示教器上的钥匙向右旋转,就会…

ruoyi—cloud 新建模块+生成代码

1.复制一个模块——修改名字 2.打开模块下的yml文件,修改端口号和名字 (1)修改一个名字 (2)打开yml文件 (3)修改端口号,不要重复 (4)改名字和模块一致 3.…

arm_uart4实验

#include "uart4.h" //UART //初始化 void hal_uart4_init() { //rcc_init //…

Python中常用的有7种值(数据)的类型及type()语句的用法

目录 0.Python中常用的有7种值(数据)的类型Python中的数据类型主要有:Number(数字)、Boolean(布尔)、String(字符串)、List(列表)、Tuple&#xf…

MySQL-数据操作类型的角度理解 S锁 X锁

文章目录 1、S锁和S锁互相兼容2、S锁和X锁互斥3、X锁和X锁也互斥4、X锁和S锁也互斥5、select * from account for update;6、select * from account for update nowait;7、select * from account for update skip locked; 1、S锁和S锁互相兼容 2、S锁和X锁互斥 3、X锁和X锁也互…

LLaVA1.5训练数据和时间分析

LLaVA的PT+SFT训练_llava sft-CSDN博客文章浏览阅读379次。这个阶段,使用8个A100(80G)训练LLaVA-v1.5-13B大约需要20h。全量微调,非lora跑不起来啊,以前一直用swift,llama-factory这种框架式的代码库,但用原作者开源的代码也是有很多好处的。在这个阶段,使用 8 个 A100(…

App测试技术(纯理论)

之前我们也学习过一些普通用例的设计, 如功能, 性能, 安全性, 兼容性, 易用性, 界面的测试用例设计, 之前我们讲的基本都是对于Web应用而言的, 这里我们来讲一下移动端的App测试用例设计. 功能方面 安装&卸载测试 这是只属于App的一类测试, 再平常我们使用移动设备(手机…

nodejs--【Express基本使用】

10 【Express基本使用】 https://www.expressjs.com.cn/ 基于 Node.js 平台,快速、开放、极简的 web 开发框架。 1.Express的安装方式 Express的安装可直接使用npm包管理器上的项目,在安装npm之前可先安装淘宝镜像: npm install -g cnpm -…

[工业网络][2] 安全背景知识

安全背景知识 物理、网络和人员安全 在考虑企业和工业的安全性时,安全从业人员传统上将自己划分为三个专业领域。我们借助于安全中经常使用的两个术语来描述这三个领域 业内人士。属于您的设施的人员,包括员工和受邀承包商,访客或交付和服…

Skipfish一键扫描网站漏洞(KALI工具系列三十四)

目录 1、KALI LINUX 简介 2、Skipfish工具简介 3、信息收集 3.1 目标IP 3.2 kali的IP 4、操作步骤 4.1创建目录 4.2开始扫描 4.3 配置扫描 4.4 指定范围 4.5 查看扫描结果 5、总结 1、KALI LINUX 简介 Kali Linux 是一个功能强大、多才多艺的 Linux 发行版 &#xf…

TopK问题与如何在有限内存找出前几最大(小)项(纯c语言版)

目录 0.前言 1.知识准备 2.实现 1.首先是必要的HeapSort 2.造数据 其他注意事项 3.TopK的实现 0.前言 在我们的日常生活中总有排名系统,找出前第k个分数最高的人,而现在让我们用堆来在有限内存中进行实现 1.知识准备 想要实现topk问题首先我们要…

windows下启动redisSentinel

如果已经安装redis的就继续往下看&#xff0c;还没安装redis&#xff0c;先安装一下redis 安装完redis之后&#xff0c;打开redis的目录。 新建一个sentinel.conf文件 # 端口号 port 26379# Sentinel 监控的主节点信息&#xff0c;格式为 <master-name> <ip> &l…

Spring Cloud Sentinel

官网代码案例: 注意&#xff1a; 1. 引入依赖 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> 2. 配置文件application.yml spring:cloud:sent…