关于java:网易二面Kafka为什么吞吐量大速度快

51次阅读

共计 3177 个字符,预计需要花费 8 分钟才能阅读完成。

起源:cnblogs.com/starluke/p/12558952.html

Kafka 是大数据畛域无处不在的消息中间件,目前宽泛应用在企业外部的实时数据管道,并帮忙企业构建本人的流计算应用程序。

Kafka 尽管是基于磁盘做的数据存储,但却具备高性能、高吞吐、低延时的特点,其吞吐量动辄几万、几十上百万。

然而很多应用过 Kafka 的人, 常常会被问到这样一个问题,Kafka 为什么速度快, 吞吐量大;大部分被问的人都是一下子就懵了,或者是只晓得一些简略的点,本文就简略的介绍一下 Kafka 为什么吞吐量大,速度快。

另外,最近面试整顿了 Java 最新、最全的面试题:

https://www.javastack.cn/mst/

一、程序读写

家喻户晓 Kafka 是将音讯记录长久化到本地磁盘中的,个别人会认为磁盘读写性能差,可能会对 Kafka 性能如何保障提出质疑。实际上不论是内存还是磁盘,快或慢关键在于寻址的形式,磁盘分为程序读写与随机读写,内存也一样分为程序读写与随机读写。基于磁盘的随机读写的确很慢,但磁盘的程序读写性能却很高,一般而言要高出磁盘随机读写三个数量级,一些状况下磁盘程序读写性能甚至要高于内存随机读写。

这里给出驰名学术期刊 ACM Queue 上的性能比照图:

磁盘的程序读写是磁盘应用模式中最有法则的,并且操作系统也对这种模式做了大量优化,Kafka 就是应用了磁盘程序读写来晋升的性能。Kafka 的 message 是一直追加到本地磁盘文件开端的,而不是随机的写入,这使得 Kafka 写入吞吐量失去了显著晋升。

上图就展现了 Kafka 是如何写入数据的,每一个 Partition 其实都是一个文件,收到音讯后 Kafka 会把数据插入到文件开端(虚框局部)。

这种办法有一个缺点—— 没有方法删除数据,所以 Kafka 是不会删除数据的,它会把所有的数据都保留下来,每个消费者(Consumer)对每个 Topic 都有一个 offset 用来示意 读取到了第几条数据。

两个消费者,Consumer1 有两个 offset 别离对应 Partition0、Partition1(假如每一个 Topic 一个 Partition);Consumer2 有一个 offset 对应 Partition2。这个 offset 是由客户端 SDK 负责保留的,Kafka 的 Broker 齐全忽视这个货色的存在;个别状况下 SDK 会把它保留到 zookeeper 外面。(所以须要给 Consumer 提供 zookeeper 的地址)。

如果不删除硬盘必定会被撑满,所以 Kakfa 提供了两种策略来删除数据。一是基于工夫,二是基于 partition 文件大小。具体配置能够参看它的配置文档。

二、Page Cache

为了优化读写性能,Kafka 利用了操作系统自身的 Page Cache,就是利用操作系统本身的内存而不是 JVM 空间内存。这样做的益处有:

  • 防止 Object 耗费:如果是应用 Java 堆,Java 对象的内存耗费比拟大,通常是所存储数据的两倍甚至更多。
  • 防止 GC 问题:随着 JVM 中数据一直增多,垃圾回收将会变得复杂与迟缓,应用零碎缓存就不会存在 GC 问题

相比于应用 JVM 或 in-memory cache 等数据结构,利用操作系统的 Page Cache 更加简略牢靠。

首先,操作系统层面的缓存利用率会更高,因为存储的都是紧凑的字节构造而不是独立的对象。

其次,操作系统自身也对于 Page Cache 做了大量优化,提供了 write-behind、read-ahead 以及 flush 等多种机制。

再者,即便服务过程重启,零碎缓存仍然不会隐没,防止了 in-process cache 重建缓存的过程。

通过操作系统的 Page Cache,Kafka 的读写操作基本上是基于内存的,读写速度失去了极大的晋升。

三、零拷贝

linux 操作系统“零拷贝”机制应用了 sendfile 办法,容许操作系统将数据从 Page Cache 间接发送到网络,只须要最初一步的 copy 操作将数据复制到 NIC 缓冲区,这样防止从新复制数据。示意图如下:

通过这种“零拷贝”的机制,Page Cache 联合 sendfile 办法,Kafka 生产端的性能也大幅晋升。这也是为什么有时候生产端在一直生产数据时,咱们并没有看到磁盘 io 比拟高,此刻正是操作系统缓存在提供数据。

当 Kafka 客户端从服务器读取数据时,如果不应用零拷贝技术,那么大抵须要经验这样的一个过程:

  1. 操作系统将数据从磁盘上读入到内核空间的读缓冲区中。
  2. 应用程序(也就是 Kafka)从内核空间的读缓冲区将数据拷贝到用户空间的缓冲区中。
  3. 应用程序将数据从用户空间的缓冲区再写回到内核空间的 socket 缓冲区中。
  4. 操作系统将 socket 缓冲区中的数据拷贝到 NIC 缓冲区中,而后通过网络发送给客户端。

从图中能够看到,数据在内核空间和用户空间之间穿梭了两次,那么是否防止这个多余的过程呢?当然能够,Kafka 应用了零拷贝技术,也就是间接将数据从内核空间的读缓冲区间接拷贝到内核空间的 socket 缓冲区,而后再写入到 NIC 缓冲区,防止了在内核空间和用户空间之间穿梭。

可见,这里的零拷贝并非指一次拷贝都没有,而是防止了在内核空间和用户空间之间的拷贝。如果真是一次拷贝都没有,那么数据发给客户端就没了不是?不过,光是省下了这一步就能够带来性能上的极大晋升。

四、分区分段 + 索引

Kafka 的 message 是按 topic 分类存储的,topic 中的数据又是依照一个一个的 partition 即分区存储到不同 broker 节点。每个 partition 对应了操作系统上的一个文件夹,partition 实际上又是依照 segment 分段存储的。这也十分合乎分布式系统分辨别桶的设计思维。

通过这种分区分段的设计,Kafka 的 message 音讯实际上是分布式存储在一个一个小的 segment 中的,每次文件操作也是间接操作的 segment。为了进一步的查问优化,Kafka 又默认为分段后的数据文件建设了索引文件,就是文件系统上的.index 文件。这种分区分段 + 索引的设计,不仅晋升了数据读取的效率,同时也进步了数据操作的并行度。

五、批量读写

Kafka 数据读写也是批量的而不是单条的。

除了利用底层的技术外,Kafka 还在应用程序层面提供了一些伎俩来晋升性能。最显著的就是应用批次。在向 Kafka 写入数据时,能够启用批次写入,这样能够防止在网络上频繁传输单个音讯带来的提早和带宽开销。假如网络带宽为 10MB/S,一次性传输 10MB 的音讯比传输 1KB 的音讯 10000 万次显然要快得多。

六、批量压缩

在很多状况下,零碎的瓶颈不是 CPU 或磁盘,而是网络 IO,对于须要在广域网上的数据中心之间发送音讯的数据流水线尤其如此。进行数据压缩会耗费大量的 CPU 资源, 不过对于 kafka 而言, 网络 IO 更应该须要思考。

  1. 如果每个音讯都压缩,然而压缩率绝对很低,所以 Kafka 应用了批量压缩,行将多个音讯一起压缩而不是单个消息压缩
  2. Kafka 容许应用递归的音讯汇合,批量的音讯能够通过压缩的模式传输并且在日志中也能够放弃压缩格局,直到被消费者解压缩
  3. Kafka 反对多种压缩协定,包含 Gzip 和 Snappy 压缩协定

Kafka 速度的秘诀在于,它把所有的音讯都变成一个批量的文件,并且进行正当的批量压缩,缩小网络 IO 损耗,通过 mmap 进步 I / O 速度,写入数据的时候因为单个 Partion 是开端增加所以速度最优;读取数据的时候配合 sendfile 间接暴力输入。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿 (2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0