Kafka 为何如此之快?深度解析其背后的秘密

目录

前言

一、生产者

1. 异步发送

2. 多分区并行

3. 消息批量发送

4.支持消息压缩

二、存储端

1. 分区和副本

2. 页缓存

3. 磁盘顺序写入

4. 零拷贝技术

5. 稀疏索引

三、消费端

1. 消费者群组

2. 批量拉取

3. 高效的偏移量管理

4. 并行消费

总结


前言

        Kafka 作为一款分布式消息系统,需应对海量消息的处理工作。Kafka 的设计思路是将所有消息全部写入速度较低但容量巨大的硬盘,借此获取更强大的存储能力,同时使用硬盘这种方式并未造成过多的性能损耗。Kafka单个节点的极限可以处理能力接近每秒 2000万 条消息,是一个相当出色的实时消息流处理平台。本篇文章将带你了解Kafka 通过哪些方式实现这么高的吞吐量。

一、生产者

1. 异步发送

        在发送消息时,Kafka 支持异步发送。这意味着应用程序可以将消息放入发送缓冲区后立即返回,而无需等待消息被确认发送成功。这种方式极大地提高了发送消息的效率,减少了应用程序的阻塞时间。例如,在一个高并发的电商系统中,用户的下单操作可以快速将订单信息异步发送到 Kafka,而不会影响用户的下单体验。

2. 多分区并行

        Kafka 中的分区(Partition)概念是实现高吞吐量的重要基石。生产者通过创建多个分区,将数据分散到不同的存储和处理单元。这就好比将一个大型任务分解为多个子任务,由多个团队并行处理。每个分区都可以独立地接收和存储消息,从而实现了并行写入,大大提升了整体的写入速度。 例如,假设有一个电商平台,每秒产生大量的订单消息。通过将订单消息按照不同的地区或商品类别分配到不同的分区,可以让不同的服务器同时处理这些分区的消息,而不是让单个服务器处理所有的订单,从而显著提高了处理速度。

3. 消息批量发送

        Kafka生产者在消息发送之前,会先把消息存储在 RecordBatch 中。当 RecordBatch 中的消息达到一定数量或者经过一定时间后,再统一进行发送。 这种批量处理的方式有效地减少了网络请求和系统调用的次数。想象一下,每次发送一条消息就像单独邮寄一个小包裹,而批量发送则像是将多个小包裹打包成一个大包裹一起邮寄。这样不仅减少了邮寄的次数,还降低了每次邮寄的准备工作和相关费用。 在实际应用中,比如一个监控系统每秒产生大量的性能指标数据,如果每条数据都单独发送,将会产生巨大的网络开销和系统资源消耗。而通过批量发送,能够显著降低这些成本,提高数据生产的效率。

4.支持消息压缩

        Kafka 支持在发送端进行数据压缩,启用消息压缩后,可以有效地提升数据传输效率,减少数据量,降低网络带宽的占用。 然而,压缩和解压过程会增加 CPU 的计算量。因此,在选择是否压缩以及采用何种压缩算法时,需要综合考虑数据的特点、网络带宽和 CPU 资源等因素。 例如,如果数据本身具有较高的重复性或可压缩性,如文本日志数据,使用压缩可以在不显著增加 CPU 负担的情况下,大幅减少网络传输的数据量。但对于已经高度压缩或计算密集型的数据,压缩可能带来的收益就相对较小,甚至可能因为增加的 CPU 计算量而影响整体性能。

        Kafka 默认情况下消息不进行压缩,生产者(Producer)在发送消息时,可以通过配置参数compression.type来指定消息的压缩类型。

二、存储端

1. 分区和副本

        通过分区,数据可以分布在不同的节点上进行存储和处理,实现了并行和负载均衡。副本机制则保证了数据的可靠性和可用性。比如,在一个分布式的金融交易系统中,交易数据通过分区存储,同时副本保证了数据不会因为节点故障而丢失。

2. 页缓存

        数据先存在 PageCache 中,定时 flush 到硬盘上。PageCache 是操作系统用于缓存磁盘数据的内存区域,其读写速度远高于磁盘。 当生产者写入数据时,首先将数据写入 PageCache。由于内存的高速读写特性,这一过程非常迅速。然后,Kafka 会定时将 PageCache 中的数据 flush 到硬盘上,确保数据的持久化存储。 这种方式充分利用了内存的优势,减少了直接对硬盘的频繁写入操作。在实际场景中,比如一个实时的金融交易系统,短时间内会产生大量的交易数据,通过将这些数据先缓存在 PageCache 中,可以快速响应生产者的写入请求,保证系统的低延迟和高吞吐量。

3. 磁盘顺序写入

        Kafka 采用顺序写磁盘的方式,这是其实现快速写入的原因之一。相比于随机写磁盘,顺序写磁盘的速度要快得多。 当写入数据时,Kafka 将消息依次追加到文件的末尾,就像在一个长长的卷轴上连续书写,而不是在不同的位置随机跳跃着书写。这种顺序写的方式避免了磁盘磁头的频繁寻道和旋转等待,大大提高了写入的效率。 以一个视频流媒体平台为例,大量的视频播放记录需要快速存储。采用 Kafka 的顺序写方式,可以高效地将这些记录连续写入磁盘,确保系统能够及时处理海量的用户行为数据。

4. 零拷贝技术

        消费者利用零拷贝技术从 socket 缓冲区中读取数据,避免了不必要的数据拷贝,极大地提高了数据读取的效率。

        传统的数据读取方式通常需要多次数据拷贝,从磁盘到内核缓冲区,再从内核缓冲区到用户空间缓冲区。而Kafka 利用了 Linux 的 sendFile 技术(NIO)零拷贝技术,省去了进程切换和一次数据拷贝。

5. 稀疏索引

        Kafka的索引并不是每一条消息都会建立索引,而是一种稀疏索引 也就是说,Kafka插入一批消息才会产生一条索引记录。后续利用二分查找,可以大大提高检索效率。 稀疏索引:kafka存储消息是通过分段的日志文件,每个分段都有自己的索引文件,这些索引文件中的条目不 是对分段中的每条消息都建立索引,而是每隔一定数量的消息建立一个索引点,这就构成了稀疏索引,稀疏索 引减少了索引大小,使得加载到内存中的索引更小,提高了查找特定消息的效率。例如,在一个大规模的日志存储系统中,稀疏索引可以帮助快速找到特定时间段的日志。

三、消费端

1. 消费者群组

Kafka 引入了消费者组(Consumer Group)的概念,多个消费者可以组成一个消费者组共同消费数据。通过消费者组的机制,可以实现负载均衡,提高数据消费的效率。 当组内的某个消费者出现故障时,其他消费者可以自动接管其未消费的分区,确保数据不会丢失和积压。这种自动的故障转移和负载均衡机制,使得 Kafka 在数据消费方面具有高度的可靠性和扩展性。 比如在一个分布式计算系统中,多个计算节点组成消费者组来消费任务分配消息,通过消费者组的协调工作,可以保证任务的均衡分配和高效处理。

2. 批量拉取

消费者不是逐个获取消息,而是批量拉取消息进行处理。这样减少了网络请求次数,提高了消费的性能。比如,在一个数据处理任务中,一次性拉取一批数据进行处理,而不是频繁地拉取单个数据。

3. 高效的偏移量管理

        Kafka 为消费者提供了偏移量(Offset)的概念,用于记录消费者消费的位置。通过高效的偏移量管理,消费者可以准确地从上次停止的位置继续消费,避免了重复消费或数据丢失。 偏移量的存储和管理方式也经过了精心设计,以确保其高效性和可靠性。例如,可以将偏移量存储在专门的主题中,或者使用外部存储系统来保证其持久性。 在一个实时数据分析系统中,准确的偏移量管理能够确保数据分析的连续性和完整性,提高数据处理的效率和准确性。

4. 并行消费

        消费者可以同时处理多个分区的消息,提高消费的效率。例如,在一个数据分析系统中,可以同时对多个数据源的消息进行分析处理。

总结

        综上所述,Kafka 在发送端、存储端和消费端的一系列优化策略,使得它能够在大数据处理场景中展现出惊人的速度和性能。无论是构建实时数据管道、流处理应用还是大规模的消息系统,Kafka 都是一个可靠且高效的选择。 希望通过这篇文章,能让您对 Kafka 为什么快有更深入的理解。

本文内容的思维导图如下:

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

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

相关文章

观测云赋能「阿里云飞天企业版」,打造全方位监控观测解决方案

近日,观测云成功通过了「阿里云飞天企业版」的生态集成认证测试,并荣获阿里云颁发的产品生态集成认证证书。作为监控观测领域的领军者,观测云一直专注于提供统一的数据视角,助力用户构建起全球范围内的端到端全链路可观测服务。此…

SwanLinkOS首批实现与HarmonyOS NEXT互联互通,软通动力子公司鸿湖万联助力鸿蒙生态统一互联

在刚刚落下帷幕的华为开发者大会2024上,伴随全场景智能操作系统HarmonyOS Next的盛大发布,作为基于OpenHarmony的同根同源系统生态,软通动力子公司鸿湖万联全域智能操作系统SwanLinkOS首批实现与HarmonyOS NEXT互联互通,率先攻克基…

Appium adb 获取appActivity

方法一(最简单有效的方法) 通过cmd命令,前提是先打开手机中你要获取包名的APP adb devices -l 获取连接设备详细信息 adb shell dumpsys activity | grep mFocusedActivity 有时获取到的不是真实的Activity 方法二 adb shell monkey -p …

Java中反射的使用

无参构造器 方法的调用 package com.studio;import java.lang.reflect.Method;class User {private String name;/*无参构造器*/public User() {}public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic String toString…

PHP景区旅游多商户版微信小程序系统源码

解锁景区新玩法!​ 引言:一站式旅行新体验 厌倦了传统景区的单调游览?想要一次旅行就能体验多种风情?那么,“景区旅游多商户版”绝对是你的不二之选!这个创新模式将景区内多个商户资源整合,为…

C# WPF自制批注工具(方便标记重点和演示)

在教学和演示中,我们通常需要对重点进行批注,下载安装第三方工具批注显得很麻烦。本篇使用WPF开发了一个批注工具,工具小巧,功能丰富,非常使用日常免费使用,或者进行再次开发。 自制批注工具具有以下功能特…

自动驾驶水泥搅拌车在梁场的应用(下)

自动驾驶水泥搅拌车在梁场的应用(下) 北京渡众机器人科技有限公司的自动驾驶水泥搅拌车在梁场(也称为预制梁场)的应用可以带来多方面的优势和效益: 1. 自动化搅拌和运输 在梁场中,通常需要大量的混凝土搅…

查询 条件列值用notepad++批量添加单引号和逗号

参考:Notepad批量添加引号_notepad字符串统一加引号-CSDN博客 我需要批量修改数据表中某一列值指定的部分列,比如某个编号为CP0408242321001到CP0408242321101的条件。 我从数据表中把这个条件的所有编号复制出来了粘贴到了notepad里面。 如下图所示 从…

数据开源|GigaSpeech 2:三万小时东南亚多语种语音识别开源数据集发布

“Giga”一词源于“gigantic”,互联网上具有海量音频资源,但语音质量良莠不齐,高质量音频文本对数据十分稀缺且标注成本高昂,特别是在小语种领域。GigaSpeech 是一个非常成功的英文开源数据集,以 YouTube 和 Podcast 为…

读书笔记-Java并发编程的艺术-第4章(Java并发编程基础)-第1节(线程简介)

文章目录 4.1 线程简介4.1.1 什么是线程4.1.2 为什么要使用多线程4.1.3 线程优先级4.1.4 线程的状态4.1.5 Daemon 线程 Java从诞生开始就明智地选择了内置对多线程的支持,这使得Java语言相比同一时期的其他语言具有明显的优势。线程作为操作系统调度的最小单元&…

DC/AC电源模块:为智能家居设备提供恒定的电力供应

BOSHIDA DC/AC电源模块:为智能家居设备提供恒定的电力供应 DC/AC电源模块是一种常见的电源转换器,它将直流电源(DC)转换为交流电源(AC),为智能家居设备提供恒定的电力供应。在智能家居系统中&a…

Linux运维:mysql视图,用户及远程登录,用户密码的修改和破解

目 录 一、视图 二、用户 2.1 新建用户 三、创建远程登录用户test 3.1 远程登录mysql​编辑 3.1 7-1需要赋予权限 3.3 修改远程登录用户的密码 3.4 修改远程登录的用户名 3.5 删除用户:drop user lisi192.168.114.%; 四、修改用户密码 4.1 修改当前本地…

网安小贴士(3)网安协议

一、前言 网络安全协议是构建安全网络环境的基础,它们帮助保护网络通信免受各种威胁和攻击。 二、定义 网络安全协议是指在计算机网络中用于确保网络通信和数据传输安全的协议。它们定义了在网络通信过程中的安全机制、加密算法、认证和授权流程等,以保…

【论文阅读】自动驾驶光流任务 DeFlow: Decoder of Scene Flow Network in Autonomous Driving

再一次轮到讲自己的paper!耶,宣传一下自己的工作,顺便完成中文博客的解读 方便大家讨论。 Title Picture Reference and pictures paper: https://arxiv.org/abs/2401.16122 code: https://github.com/KTH-RPL/DeFlow b站视频: https://www.b…

关于 Mybatis 的开启二级缓存返回对象不一致问题

做实验报告的时候&#xff0c;跟着学习&#xff0c;发现我已经将 开启 二级缓存的 配置都配置好了&#xff0c;但是返回值地址不一致&#xff0c;说明对象不一致&#xff0c;二级缓存命中失败。 跟着流程配置&#xff1a; mybatis-config <settings><!-- 启用 myba…

SpringBoot+Thymeleaf项目重定向到另一个系统HTTPS变成HTTP

SpringBootThymeleaf项目是一个简单的单体项目&#xff0c;只有一个页面。 重定向的是前后分离&#xff0c;前端用的vue。 浏览器看到重定向后 https成了http&#xff0c;F12控制台看到是 301 Moved Permanently 单体项目最开始写法&#xff1a; response.sendRedirect(url); …

react native中使用@react-navigation/native进行自定义头部

react native中使用react-navigation/native进行自定义头部 效果示例图实例代码 效果示例图 实例代码 /* eslint-disable react-native/no-inline-styles */ /* eslint-disable react/no-unstable-nested-components */ import React, { useLayoutEffect } from react; import…

基于uniapp(vue3)H5附件上传组件,可限制文件大小

代码&#xff1a; <template><view class"upload-file"><text>最多上传5份附件&#xff0c;需小于50M</text><view class"" click"selectFile">上传</view></view><view class"list" v…

html+css+js气球消除小游戏

气球消除小游戏 消除15个就成功 源码在图片后 点赞加关注&#xff0c;谢谢 左上角的数字显示消除气球的数量 定时随机生成气球 &#x1f388;&#x1f388;&#x1f388; 图片 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset&…

C++部分复习笔记上

C语法复习 1. C入门基础 缺省参数 半缺省参数必须从右往左依次来给出&#xff0c;不能间隔着给缺省参数不能在函数声明和定义中同时出现缺省值必须是常量或者全局变量C语言不支持&#xff08;编译器不支持&#xff09; 函数重载 函数重载是函数的一种特殊情况&#xff0c;…