您当前的位置:首页 > 电脑百科 > 程序开发 > 容器

Kafka为什么这么快?

时间:2023-08-23 12:04:56  来源:微信公众号  作者:waynblog

Kafka 是一个基于发布-订阅模式的消息系统,它可以在多个生产者和消费者之间传递大量的数据。Kafka 的一个显著特点是它的高吞吐率,即每秒可以处理百万级别的消息。那么 Kafka 是如何实现这样高得性能呢?本文将从七个方面来分析 Kafka 的速度优势。

  • 零拷贝技术
  • 仅可追加日志结构
  • 消息批处理
  • 消息批量压缩
  • 消费者优化
  • 未刷新的缓冲写入
  • GC 优化

以下是对本文中使用得一些英文单词解释:

Broker:Kafka 集群中的一台或多台服务器统称 broker
Producer:消息生产者
Consumer:消息消费者
zero copy:零拷贝

1. 零拷贝技术

零拷贝技术是指在读写数据时,避免将数据在内核空间和用户空间之间进行拷贝,而是直接在内核空间进行数据传输。对于 Kafka 来说,它使用了零拷贝技术来加速磁盘文件的网络传输,以提高读取速度和降低 CPU 消耗。下图说明了数据如何在生产者和消费者之间传输,以及零拷贝原理。

图片

步骤 1.1~1.3:生产者将数据写入磁盘
步骤 2:消费者不使用零拷贝方式读取数据

2.1:数据从磁盘加载到 OS 缓存

2.2:将数据从 OS 缓存复制到 Kafka 应用程序

2.3:Kafka 应用程序将数据复制到 socket 缓冲区

2.4:将数据从 socket 缓冲区复制到网卡

2.5:网卡将数据发送给消费者

步骤 3:消费者以零拷贝方式读取数据

3.1:数据从磁盘加载到 OS 缓存

3.2:OS 缓存通过 sendfile() 命令直接将数据复制到网卡

3.3:网卡将数据发送到消费者

可以看到,零拷贝技术避免了多余得两步操作,数据直接从OS 缓存复制到网卡再到消费者。这样做的好处是极大地提高了I/O效率,降低了CPU和内存的消耗。

2. 仅可追加日志结构

Kafka 中存在大量的网络数据持久化到磁盘(生产者到代理)和磁盘文件通过网络发送(代理到消费者)的过程。这一过程的性能会直接影响 Kafka 的整体吞吐量。为了优化 Kafka 的数据存储和传输,Kafka 采用了一种仅可追加日志结构方式来持久化数据。仅可追加日志结构是指将数据以顺序追加(Append-only)的方式写入到文件中,而不是进行随机写入或更新。这样做的好处是可以减少磁盘 I/O 的开销,提高写入速度。

人们普遍认为磁盘的读写速度很慢,但实际上存储介质(尤其是旋转介质)的性能很大程度上取决于访问模式。常见的 7,200 RPM SATA 磁盘上的随机 I / O 的性能要比顺序 I / O 慢 3 ~ 4 个数量级。此外,现代操作系统提供了预读和延迟写入技术,可以预先取出大块的数据,并将较小的逻辑写入组合成较大的物理写入。因此,即使在闪存和其他形式的固态非易失性介质中,随机 I/O 和顺序 I/O 的差异仍然很明显,尽管与旋转介质相比,这种差异性已经很小了。

3. 消息批处理

Kafka 的高吞吐率设计的核心要点之一是批处理,即 Kafka 在消息发送端和接收端都引入了一个缓冲区,将多条消息打包成一个批次(Batch),然后一次性发送或接收。这样做的好处是可以减少网络请求的次数,减少了网络压力,提高了传输效率。

Kafka 的消息批处理优化主要涉及以下几个方面:

发送端(Producer)

Kafka 的 Producer 只提供了单条发送的 send()方法,并没有提供任何批量发送的接口。当调用 send()方法发送一条消息之后,无论是同步还是异步发送,这条消息不会立即发送出去,而是先放入到一个双端队列中,然后 Kafka 使用一个异步线程从队列中成批发送消息。

Kafka 提供了以下几个参数来控制发送端的批处理策略:

  • batch.size:指定每个批次可以收集的消息数量的最大值。默认是 16KB。
  • buffer.memory:指定每个 Producer 可以使用的缓冲区内存的总量。默认是 32MB。
  • linger.ms:指定每个批次可以等待的时间的最大值。默认是 0ms。
  • compression.type:指定是否对每个批次进行压缩,以及使用哪种压缩算法。默认是 none。

接收端(Broker)

Kafka 的 Broker 在接收到 Producer 发送过来的批次后,不会把批次再还原成多条消息,而是直接将整个批次写入到磁盘中。这样做的好处是可以减少磁盘 I/O 的开销,提高写入速度。

Kafka 利用了操作系统提供的内存映射文件(memory mapped file)功能,将文件映射到内存中,使得对文件的读写操作就相当于对内存的读写操作。这样就避免了用户空间和内核空间之间的数据拷贝,也避免了系统调用的开销。

消费端(Consumer)

Kafka 的 Consumer 在从 Broker 拉取数据时,也是以批次为单位进行传递的。Consumer 从 Broker 拉到一批消息后,客户端把批次解开,再一条一条交给用户代码处理。

Kafka 提供了以下几个参数来控制消费端的批处理策略:

  • fetch.min.bytes:指定每次拉取请求至少要获取多少字节的数据。默认是 1B。
  • fetch.max.bytes:指定每次拉取请求最多能获取多少字节的数据。默认是 50MB。
  • fetch.max.wAIt.ms:指定每次拉取请求最多能等待多长时间。默认是 500ms。
  • max.partition.fetch.bytes:指定每个分区每次拉取请求最多能获取多少字节的数据。默认是 1MB。

4. 消息批量压缩

消息批量压缩通常与消息批处理一起使用。Kafka 会将多个消息打包成一个批次(Batch),并对批次进行压缩(例如使用 gzip 或 snappy 算法),然后再发送给消费者。这样做的好处是可以节省网络带宽,提高传输效率。

当然,压缩也有一定的代价,即需要消耗 CPU 资源来进行压缩和解压缩。但是对于 Kafka 这样的高吞吐量的系统来说,网络带宽往往是更大的瓶颈,所以压缩是值得的。

Kafka 还提供了一种灵活的压缩策略,即可以让生产者、代理和消费者之间协商压缩格式和级别。生产者可以选择是否对消息进行压缩,以及使用哪种压缩算法;代理可以选择是否保留生产者压缩的消息,或者对其进行重新压缩;消费者可以选择是否对收到的消息进行解压缩。这样可以根据不同的场景和需求来平衡性能和资源的消耗。

5. 消费者优化

Kafka 的消费者是基于拉模式(pull)的,即消费者主动向服务器请求数据,而不是服务器主动推送数据给消费者。这样做的好处是可以让消费者自己控制消费的速度和时机,也可以减轻服务器的负担,提高整体的吞吐量。

Kafka 的消费者所实现的功能是比较简洁的,即它们不需要维护太多的状态和资源,也不需要和服务器进行复杂的交互。Kafka 的消费者只需要做以下几件事:

  • 订阅一个或多个主题(topic),并加入一个消费者组(consumer group)。向群组协调器(group coordinator)发送心跳,表明自己还活着,并参与分区再均衡(partition rebalance)。
  • 向分区所在的代理(broker)发送拉取请求(fetch request),获取消息数据。
  • 提交自己消费到的偏移量(offset),以便在出现故障时恢复消费位置。

可以看到,Kafka 的消费者并不需要保存消息数据,也不需要对消息进行确认或回复,也不需要处理重试或重复的问题。这些都由服务器端来负责。Kafka 的消费者只需要关注如何从服务器获取数据,并进行业务处理即可。

6. 未刷新的缓冲写入

Kafka 在写入数据时,使用了一种未刷新(flush)的缓冲写入技术,即它不会立即将数据写入硬盘,而是先写入内存缓存中,然后由操作系统在适当的时候刷新到硬盘上。这样做的好处是可以提高写入速度,减少磁盘 I/O 的开销。

Kafka 利用了操作系统提供的内存映射文件(memory mapped file)功能,将文件映射到内存中,使得对文件的读写操作就相当于对内存的读写操作。这样就避免了用户空间和内核空间之间的数据拷贝,也避免了系统调用的开销。

当生产者向 Kafka 发送消息时,Kafka 会将消息追加到内存映射文件中,并返回一个确认给生产者。此时消息并没有真正写入硬盘,而是由操作系统负责将内存中的数据刷新到硬盘上。操作系统会根据一些策略来决定何时刷新数据,例如定期刷新、缓存满了刷新、系统空闲时刷新等。

当然,这种技术也有一定的风险,即如果操作系统在刷新数据之前发生崩溃或断电,那么内存中未刷新的数据就会丢失。为了解决这个问题,Kafka 提供了一些参数来控制刷新策略,例如:

  • log.flush.interval.messages:指定多少条消息后强制刷新数据。
  • log.flush.interval.ms:指定多少毫秒后强制刷新数据。
  • producer.type:指定生产者是同步还是异步模式。同步模式下,生产者会等待服务器刷新数据后再返回确认;异步模式下,生产者不会等待服务器刷新数据,而是立即返回确认。

7. GC 优化

Kafka 作为一个 JAVA 编写得高性能的分布式消息系统,它需要处理大量的数据读写和网络传输。这些操作都会涉及到 Java 虚拟机(JVM)的内存管理和垃圾回收(GC)机制。如果 GC 不合理或不及时,就会导致 Kafka 的性能下降,甚至出现内存溢出或频繁的停顿。为了帮助使用者优化 GC,Kakfa 有如下建议。

堆内存大小

堆内存是 JVM 用来存储对象实例的内存区域,它会受到 GC 的管理和回收。堆内存的大小会影响 Kafka 的性能和稳定性,如果堆内存太小,就会导致频繁的 GC,影响吞吐量和延迟;如果堆内存太大,就会导致 GC 时间过长,影响响应速度和可用性。

通常来说,Kafka 并不需要设置太大的堆内存,因为它主要依赖于操作系统的文件缓存(page cache)来缓存和读写数据,而不是将数据保存在堆内存中。因此 Kafka 建议将堆内存大小设置为 4GB 到 6GB 之间。

堆外内存大小

堆外内存是 JVM 用来存储非对象实例的内存区域,它不会受到 GC 的管理和回收。堆外内存主要用于网络 I/O 缓冲区、直接内存映射文件、压缩库等。

Kafka 在进行网络 I/O 时,会使用堆外内存作为缓冲区,以减少数据在用户空间和内核空间之间的拷贝。同时,Kafka 在进行数据压缩时,也会使用堆外内存作为临时空间,以减少 CPU 资源的消耗。

因此,堆外内存对于 Kafka 的性能也很重要,如果堆外内存不足,就会导致缓冲区分配失败或压缩失败,影响吞吐量和延迟。通常来说,Kafka 建议将堆外内存大小设置为 8GB 左右。

GC 算法和参数

GC 算法是 JVM 用来回收无用对象占用的堆内存空间的方法,它会影响 Kafka 的停顿时间和吞吐量。GC 算法有多种选择,例如串行 GC、并行 GC、CMS GC、G1 GC 等。

不同的 GC 算法有不同的优缺点和适用场景,例如串行 GC 适合小型应用和低延迟场景;并行 GC 适合大型应用和高吞吐量场景;CMS GC 适合大型应用和低停顿时间场景;G1 GC 适合大型应用和平衡停顿时间和吞吐量场景等。

通常来说,Kafka 建议使用 G1 GC 作为默认的 GC 算法,因为它可以在保证较高吞吐量的同时,控制停顿时间在 200ms 以内。同时,Kafka 还建议根据具体情况调整一些 GC 参数,例如:

  • -XX:MaxGCPauseMillis:指定最大停顿时间目标,默认是 200ms。
  • -XX:InitiatingHeapOccupancyPercent:指定触发并发标记周期的堆占用百分比,默认是 45%。
  • -XX:G1ReservePercent:指定为拷贝存活对象预留的空间百分比,默认是 10%。
  • -XX:G1HeapRegionSize:指定每个堆区域的大小,默认是 2MB。
 

本文参考

  • https://medium.com/swlh/why-kafka-is-so-fast-bde0d987cd03
  • https://blog.bytebytego.com/p/why-is-kafka-fast
  • https://blog.csdn.NET/csdnnews/article/details/104471147

总结

最后感谢大家阅读,希望本文能对你有所帮助。



Tags:Kafka   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  Search: Kafka  点击:(84)  评论:(0)  加入收藏
如何使用Python、Apache Kafka和云平台构建健壮的实时数据管道
译者 | 李睿审校 | 重楼在当今竞争激烈的市场环境中,为了生存和发展,企业必须能够实时收集、处理和响应数据。无论是检测欺诈、个性化用户体验还是监控系统,现在都需要接近即时...【详细内容】
2024-01-26  Search: Kafka  点击:(46)  评论:(0)  加入收藏
深入浅出Kafka:高可用、顺序消费及幂等性
在我们旅行于数据海洋的途中,如果把 Kafka 比作是一艘承载无数信息航行的快船,前文《Kafka实战漫谈:大数据领域的不败王者》已经讲述了如何搭建起这艘快船,让它在起风的早晨开始...【详细内容】
2023-12-18  Search: Kafka  点击:(173)  评论:(0)  加入收藏
7k Star,一款开源的 Kafka 管理平台,功能齐全、页面美观!
Apache Kafka UI 是一个免费的开源 Web UI,用于监控和管理 Apache Kafka 集群,可方便地查看 Kafka Brokers、Topics、消息、Consumer 等情况,支持多集群管理、性能监控、访问控...【详细内容】
2023-12-15  Search: Kafka  点击:(129)  评论:(0)  加入收藏
利用Apache Kafka、Flink和Druid构建实时数据架构
译者 | 陈峻审校 | 重楼如今,对于使用批处理工作流程的数据团队而言,要满足业务的实时要求并非易事。从数据的交付、处理到分析,整个批处理工作流往往需要大量的等待,其中包括:等...【详细内容】
2023-12-11  Search: Kafka  点击:(229)  评论:(0)  加入收藏
运维兄弟!Kafka怎么又"超时"了?
现象凌晨,当运维刚躺下,就被业务研发的电话叫醒,"哥们!kafka服务又异常了?影响到业务了,快看看",业务研发给出的异常日志如下:基本分析 集群检查:立即确认kafka集群以及涉及到topic健...【详细内容】
2023-12-07  Search: Kafka  点击:(137)  评论:(0)  加入收藏
图解Kafka适用场景,全网最全!
消息系统消息系统被用于各种场景,如解耦数据生产者,缓存未处理的消息。Kafka 可作为传统的消息系统的替代者,与传统消息系统相比,kafka有更好的吞吐量、更好的可用性,这有利于处...【详细内容】
2023-11-29  Search: Kafka  点击:(183)  评论:(0)  加入收藏
Kafka有哪些应用场景?你能说上来几个?
下面我们来总结一下Kafka的一些应用场景:1、日志处理与分析(最常用的场景)下图显示了典型的 ELK(Elastic-Logstash-Kibana)堆栈。Kafka 有效地从每个实例收集日志流。ElasticSe...【详细内容】
2023-11-28  Search: Kafka  点击:(163)  评论:(0)  加入收藏
Kafka:解锁大数据时代的搜索与分析
在当今大数据时代,数据湖作为一种新兴的数据存储和分析解决方案,正受到越来越多企业的青睐。而作为一种高性能、可扩展的事件流平台,Kafka在数据湖领域发挥着重要的作用。本文...【详细内容】
2023-11-24  Search: Kafka  点击:(287)  评论:(0)  加入收藏
解密Kafka主题的分区策略:提升实时数据处理的关键
Kafka几乎是当今时代背景下数据管道的首选,无论你是做后端开发、还是大数据开发,对它可能都不陌生。开源软件Kafka的应用越来越广泛。面对Kafka的普及和学习热潮,哪吒想分享一...【详细内容】
2023-11-21  Search: Kafka  点击:(180)  评论:(0)  加入收藏
▌简易百科推荐
Docker 和传统虚拟机有什么区别?
我有一个程序员朋友,他每年情人节都要送女朋友一台服务器。他说:“谁不想在过节当天收到一台 4核8g 的服务器呢?”“万一对方不要,我还能留着自己用。” 给他一次过节的机会,他能...【详细内容】
2024-03-26  小白debug  微信公众号  Tags:Docker   点击:(12)  评论:(0)  加入收藏
掌握Docker网络驱动程序:优化容器通信
Docker为在容器内包装、交付和运行应用程序提供了一个强大的平台,从而彻底改变了容器化。网络是容器化的重要组成部分,Docker提供了各种网络驱动程序来支持容器之间的通信以...【详细内容】
2024-03-22    51CTO  Tags:Docker   点击:(10)  评论:(0)  加入收藏
Containerd容器管理
Nginx 指定容器名称 使用 ctr container create 命令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。容器基本操作容器基本操作主要是 ctr image 命令,查看命令帮...【详细内容】
2024-03-20  云原生运维圈  微信公众号  Tags:容器   点击:(13)  评论:(0)  加入收藏
如何基于Docker镜像逆向生成Dockerfile
引言你是否曾经遇到过一个想要使用的 Docker 镜像,但却无法修改以适应你的特定需求?或者你可能发现了一个喜欢的 Docker 镜像,但想要了解它是如何构建的?在这两种情况下,将 Docke...【详细内容】
2024-03-07  云原生运维圈  微信公众号  Tags:Docker   点击:(22)  评论:(0)  加入收藏
Kubernetes是什么?主要特点是什么?
Kubernetes是什么?Kubernetes,也称为K8s,是一个开源的容器编排系统,由Google首次开发和维护。它允许容器化的应用程序在集群中自动部署、扩展和管理。Kubernetes提供了一种容器...【详细内容】
2024-02-01    简易百科  Tags:Kubernetes   点击:(154)  评论:(0)  加入收藏
我们一起聊聊容器资源自愈
在企业实际在使用容器这类资源的时候,除了技术本身,要考虑的其他问题也会很多。企业管理的容器有千千万万,出于效率考虑,对于有特殊需求的容器如何进行批量创建和管理呢,这就需要...【详细内容】
2024-01-30  匠心独运维妙维效  微信公众号  Tags:容器   点击:(47)  评论:(0)  加入收藏
Docker与Docker Compose入门:释放你应用部署的威力
今天给大家介绍一项强大而有趣的技能,那就是使用 Docker 和 Docker Compose 来释放你的应用部署的威力!无论你是一名开发人员还是系统管理员,掌握这个技能都将为你的工作带来巨...【详细内容】
2024-01-17  waynblog  微信公众号  Tags:Docker   点击:(65)  评论:(0)  加入收藏
Docker镜像与容器的交互及在容器内部执行代码的原理与实践
Docker作为一种流行的容器技术,已经成为现代应用程序开发和部署的重要工具。在Docker中,镜像是构建和运行容器的基础,而容器则是基于镜像创建的可执行实例。Docker镜像与容器的...【详细内容】
2024-01-10  编程技术汇  今日头条  Tags:Docker   点击:(77)  评论:(0)  加入收藏
如何在 Ubuntu 上安装 Docker
使用 Docker 意味着开启一个新的计算领域,但如果你刚刚开始使用 Docker,安装可能看起来是一项艰巨的任务。在 Ubuntu 上安装 Docker 有两种推荐的方法: 从 Ubuntu 的仓库安装 D...【详细内容】
2024-01-04    Linux中国  Tags:Docker   点击:(124)  评论:(0)  加入收藏
从Kubernetes的探针到DevOps
今天在群里又看有人问如何设置 Kubernetes 的探针,感觉要补充的话太多了,结合我们在一些 DevOps 项目中痛苦的体验,今天一劳永逸的全部说完,此外,也为大家展现一下为什么 DevOps...【详细内容】
2023-12-27  云云众生s  微信公众号  Tags:Kubernetes   点击:(114)  评论:(0)  加入收藏
站内最新
站内热门
站内头条