本文来说下Kafka为什么吞吐量大、速度快?

文章目录

  • 概述
  • 顺序读写
  • Page Cache
  • 零拷贝
  • 分区分段+索引
  • 批量读写
  • 批量压缩
  • 本文小结

概述

Kafka是大数据领域无处不在的消息中间件,目前广泛使用在企业内部的实时数据管道,并帮助企业构建自己的流计算应用程序。

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

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


顺序读写

众所周知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更应该需要考虑。

  • 如果每个消息都压缩,但是压缩率相对很低,所以Kafka使用了批量压缩,即将多个消息一起压缩而不是单个消息压缩
  • Kafka允许使用递归的消息集合,批量的消息可以通过压缩的形式传输并且在日志中也可以保持压缩格式,直到被消费者解压缩
  • Kafka支持多种压缩协议,包括Gzip和Snappy压缩协议

Kafka速度的秘诀在于,它把所有的消息都变成一个批量的文件,并且进行合理的批量压缩,减少网络IO损耗,通过mmap提高I/O速度,写入数据的时候由于单个Partion是末尾添加所以速度最优;读取数据的时候配合sendfile直接暴力输出。


本文小结

本文详细介绍了kafka高性能的几个原因,对深刻理解kafka有重要的作用。

关于Kafka高性能的几个问题相关推荐

  1. Kafka设计解析(六)- Kafka高性能架构之道

    原创文章,转载请务必将下面这段话置于文章开头处. 本文转发自技术世界,原文链接 http://www.jasongj.com/kafka/high_throughput/ 摘要 上一篇文章<Ka ...

  2. Kafka高性能相关

    Kafka高性能相关 1 高性能原因 1.1 高效使用磁盘 (1)顺序写磁盘,顺序写磁盘性能高于随机写内存 (2)Append Only 数据不更新,无记录级的数据删除(只会整个segment删除) ...

  3. 深入理解分布式技术 - Kafka 高性能原理剖析

    文章目录 概述 磁盘顺序读写 批量操作优化 Sendfile 零拷贝 MMAP 技术 小结 概述 Kafka 所实现的高性能不需要太高配置的机器,它使用普通服务器就能实现 TB 级别的传输性能.这一点 ...

  4. Kafka设计解析(六)- Kafka高性能关键技术解析

    http://www.infoq.com/cn/articles/kafka-analysis-part-6 宏观架构层面 利用Partition实现并行处理 Partition提供并行处理的能力 K ...

  5. kafka高性能的原因

    http://rdcqii.hundsun.com/portal/article/709.html KAFKA是分布式发布-订阅消息系统,是一个分布式的,可划分的,冗余备份的持久性的日志服务.它主要用 ...

  6. 为什么Kafka这么快,解密Kafka高性能背后的秘密

    介绍 说起 Kafka 很多同学都知道,即使你没有用过也知道,它是消息队列中数一数二的运动健将,他可以承载每秒钟上百万此的数据处理,但问什么 Kafka 可以这么快呢? 归纳原因主要有这四点原因,磁盘 ...

  7. kafka高性能揭秘:顺序写和零拷贝

    顺序写&MMF Zero Copy零拷贝 传统io: DMA: 直接内存访问 传统io一共经历了四次拷贝:其中内核空间到用户空间的拷贝.用户空间拷贝到内核缓冲区这两次拷贝是多余的. 零拷贝只需 ...

  8. Kafka的高性能原理

    本文来说下Kafka的高性能设计 文章目录 什么是高性能设计 Kafka高性能设计的全景图 生产消息的性能优化手段 批量发送消息 消息压缩 高效序列化 内存池复用 存储消息的性能优化手段 IO 多路复 ...

  9. Kafka 精妙的高性能设计(上篇)

    大家好,我是武哥. 这是<吃透 MQ 系列>之 Kafka 的第 4 篇,错过前 3 篇的,通过下面的链接一睹为快: 第 1 篇:扒开 Kafka 的神秘面纱 第 2 篇:Kafka 架构 ...

最新文章

  1. 开源实时日志分析ELK
  2. 如何从阿里云Code升级至Codeup
  3. 有关dubbo面试的那些事儿
  4. 竞品分析实战系列之如何对电商产品条目进行合理设计?
  5. 济南泉水与城市生态主题 第四届泉水文化论坛第二次会议
  6. VMware NSX系列教程-部署NSX Manager(转)
  7. python的pip换源_[Python]Pip换源以及设置代理
  8. 【渝粤题库】陕西师范大学200591 英语语法
  9. python日期时间模块_Python模块|时间处理模块-日期时间模块,python,datetime
  10. halcon 深度学习标注_深度学习in Halcon流程
  11. selenium+phantomjs截长图踩坑
  12. Java零基础入门(五)
  13. KETTLE相关问题处理
  14. mysql straight join_在MySQL中使用STRAIGHT_JOIN的教程
  15. MySql 如何查询某一天内的数据
  16. 2022-2027年中国股权众筹行业市场调研及未来发展趋势预测报告
  17. KMP算法下,长为n的字符串中匹配长度为m的子串的复杂度为O(m+n)
  18. 【C#本质论 十一】合式类型(二)程序集引用、XML注释、垃圾回收和资源清理
  19. 2022.12.13 英语背诵
  20. 苹果x为什么总黑屏_苹果X突然黑屏重启怎么回事?教你强制重启方法

热门文章

  1. ORACLE EBS R12 - 寄售功能知多少
  2. Tengine(Nginx)动静分离简要配置
  3. [转]XHTML+CSS兼容性解决方案小集
  4. 9102 BITRUN Hackathon is COMING!
  5. 【AudioVideo】处理音频输出的变化(13)
  6. 学习笔记———Python内置函数dir()
  7. LinkedIn 开源多媒体对象存储数据库 Ambry
  8. IO is frozen on database xxx, No user action is required
  9. substring,indexof,charAt区别
  10. RabbitMq--AMQP高级消息队列协议--简单了解