第二十四期:面试问:Kafka为什么速度那么快?该怎么回答

针对Kafka的基准测试可以参考,Apache Kafka基准测试:每秒写入2百万(在三台廉价机器上)下面从数据写入和读取两方面分析,为什么Kafka速度这么快

 

Kafka的消息是保存或缓存在磁盘上的,一般认为在磁盘上读写数据是会降低性能的,因为寻址会比较消耗时间,但是实际上,Kafka的特性之一就是高吞吐率。即使是普通的服务器,Kafka也可以轻松支持每秒百万级的写入请求,超过了大部分的消息中间件,这种特性也使得Kafka在日志处理等海量数据场景广泛应用。

针对Kafka的基准测试可以参考,Apache Kafka基准测试:每秒写入2百万(在三台廉价机器上)

下面从数据写入和读取两方面分析,为什么Kafka速度这么快

一、写入数据

Kafka会把收到的消息都写入到硬盘中,它绝对不会丢失数据。为了优化写入速度Kafka采用了两个技术, 顺序写入和MMFile 。

顺序写入

磁盘读写的快慢取决于你怎么使用它,也就是顺序读写或者随机读写。在顺序读写的情况下,磁盘的顺序读写速度和内存持平。

因为硬盘是机械结构,每次读写都会寻址->写入,其中寻址是一个“机械动作”,它是最耗时的。所以硬盘最讨厌随机I/O,最喜欢顺序I/O。为了提高读写硬盘的速度,Kafka就是使用顺序I/O。

而且Linux对于磁盘的读写优化也比较多,包括read-ahead和write-behind,磁盘缓存等。如果在内存做这些操作的时候,一个是JAVA对象的内存开销很大,另一个是随着堆内存数据的增多,JAVA的GC时间会变得很长,使用磁盘操作有以下几个好处:

  1. 顺序写入磁盘顺序读写速度超过内存随机读写
  2. 顺序写入JVM的GC效率低,内存占用大。使用磁盘可以避免这一问题
  3. 顺序写入系统冷启动后,磁盘缓存依然可用

下图就展示了Kafka是如何写入数据的, 每一个Partition其实都是一个文件 ,收到消息后Kafka会把数据插入到文件末尾(虚框部分):

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

  1. 顺序写入Consumer1有两个offset分别对应Partition0、Partition1(假设每一个Topic一个Partition);
  2. 顺序写入Consumer2有一个offset对应Partition2。 这个offset是由客户端SDK负责保存的,Kafka的Broker完全无视这个东西的存在; 一般情况下SDK会把它保存到Zookeeper里面,所以需要给Consumer提供zookeeper的地址。

如果不删除硬盘肯定会被撑满,所以Kakfa提供了两种策略来删除数据:

  1. 顺序写入一是基于时间。
  2. 顺序写入二是基于partition文件大小。

Memory Mapped Files

即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存。所以Kafka的数据并不是实时的写入硬盘 ,它充分利用了现代操作系统分页存储来利用内存提高I/O效率。

Memory Mapped Files(后面简称mmap)也被翻译成 内存映射文件 ,在64位操作系统中一般可以表示20G的数据文件,它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。

完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。

通过mmap,进程像读写硬盘一样读写内存(当然是虚拟机内存),也不必关心内存的大小有虚拟内存为我们兜底。

使用这种方式可以获取很大的I/O提升,省去了用户空间到内核空间复制的开销(调用文件的read会把数据先放到内核空间的内存中,然后再复制到用户空间的内存中。) 但也有一个很明显的缺陷——不可靠,写到mmap中的数据并没有被真正的写到硬盘,操作系统会在程序主动调用flush的时候才把数据真正的写到硬盘。

Kafka提供了一个参数——producer.type来控制是不是主动flush,如果Kafka写入到mmap之后就立即flush然后再返回Producer叫 同步 (sync);写入mmap之后立即返回Producer不调用flush叫异步 (async)。

二、读取数据

Kafka在读取磁盘时做了哪些优化?

基于sendfile实现Zero Copy

传统模式下,当需要对一个文件进行传输的时候,其具体流程细节如下:

  1. 基于sendfile实现Zero Copy调用read函数,文件数据被copy到内核缓冲区
  2. read函数返回,文件数据从内核缓冲区copy到用户缓冲区
  3. write函数调用,将文件数据从用户缓冲区copy到内核与socket相关的缓冲区。
  4. 数据从socket缓冲区copy到相关协议引擎。

以上细节是传统read/write方式进行网络文件传输的方式,我们可以看到,在这个过程当中,文件数据实际上是经过了四次copy操作:

  • 硬盘—>内核buf—>用户buf—>socket相关缓冲区—>协议引擎

而sendfile系统调用则提供了一种减少以上多次copy,提升文件传输性能的方法。

在内核版本2.1中,引入了sendfile系统调用,以简化网络上和两个本地文件之间的数据传输。sendfile的引入不仅减少了数据复制,还减少了上下文切换。 sendfile(socket, file, len);

运行流程如下:

  1. sendfile系统调用,文件数据被copy至内核缓冲区
  2. 再从内核缓冲区copy至内核中socket相关的缓冲区
  3. 最后再socket相关的缓冲区copy到协议引擎 相较传统read/write方式,2.1版本内核引进的sendfile已经减少了内核缓冲区到user缓冲区,再由user缓冲区到socket相关缓冲区的文件copy,而在内核版本2.4之后,文件描述符结果被改变,sendfile实现了更简单的方式,再次减少了一次copy操作。

在Apache、Nginx、lighttpd等web服务器当中,都有一项sendfile相关的配置,使用sendfile可以大幅提升文件传输性能。

Kafka把所有的消息都存放在一个一个的文件中,当消费者需要数据的时候Kafka直接把文件发送给消费者,配合mmap作为文件读写方式,直接把它传给sendfile。

批量压缩

在很多情况下,系统的瓶颈不是CPU或磁盘,而是网络IO,对于需要在广域网上的数据中心之间发送消息的数据流水线尤其如此。进行数据压缩会消耗少量的CPU资源,不过对于kafka而言,网络IO更应该需要考虑。

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

三、总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构与算法】平衡二叉树、红黑树

1.树、二叉树 2.二叉查找树 3.平衡二叉树、红黑树 4.递归树 一,什么是“平衡二叉查找树” 1,定义:二叉树中任意一个节点的左右子树的高度相差不能大于1。 所以:完全二叉树,满二叉树都是平衡二叉树,非完全…

第五十一期:互联网不如国企,去BAT的程序员都是diao丝?

要说互联网是目前最热门的行业,应该没人反驳吧。尤其是技术,大家都想毕业后去BAT大厂,甚至比如微软、google等外企科技公司,学编程出身的高校学子,去国企的还是比较少。除非为了拿一线城市的户口,不然可能真…

文档排序--相似度模型--VSM

说明:文章内容来源于课程视频和课程ppt。我只学习了课程没有做习题。文章不是翻译,是我对课程的理解。 上文提到文档排序函数是TR的核心。文档排序函数的实现有几种思路,其中一种是基于相似度的模型。这种模型具体是用空间向量模型(Vector Sp…

第二十五期:搞定Linux Shell文本处理工具,看完这篇集锦就够了

Linux Shell是一种基本功,由于怪异的语法加之较差的可读性,通常被Python等脚本代替。既然是基本功,那就需要掌握,毕竟学习Shell脚本的过程中,还是能了解到很多Linux系统的内容。 Linux Shell是一种基本功,由…

【数据结构与算法】递归树

1.树、二叉树 2.二叉查找树 3.平衡二叉树、红黑树 4.递归树 一、什么是递归树 如果我们把这个一层一层的分解过程画成图,它其实就是一棵树。我们给这棵树起一个名字,叫作递归树。 时间复杂度分析的递归树法 分析每一步核心操作的时间复杂度分析树高&…

【02】Kubernets:使用 kubeadm 部署 K8S 集群

写在前面的话 通过上一节,知道了 K8S 有 Master / Node 组成,但是具体怎么个组成法,就是这一节具体谈的内容。概念性的东西我们会尽量以实验的形式将其复现。 部署 K8S 集群 互联网常用的 K8S 集群部署方式: 1. kubeadm&#xff0…

构建一个文本搜索系统

说明:文章内容来源于课程视频和课程ppt。我只学习了课程没有做习题。文章不是翻译,是我对课程的理解。 1 TR的主要构成 在文章中文本检索系统全文检索系统TR System  从图中看到(红色的方框)TR的主要过程有:分词(Tokenizer)、索引(Indexer)…

[Linux][Ubuntu]Linux实习常用操作/Debug总结

一、 Win下装Jupter 1.安装anaconda 配置环境变量 打开jupyter 2.切换目录 装软件 二、 移动复制粘贴上锁文件 sudo nautilus 三、 视频播放 sudo nano /etc/environment 添加QT_X11_NO_MITSHM1 四、 修改阿里源 提高下载速度 1.1打开software&updates 1.2 打…

第二十六期:100 个网络基础知识普及,看完成半个网络高手

本篇文章是关于100个网络基础知识普及,看完成半个网络高手!下面,我们一起来看。 作者:佚名来源 本篇文章是关于100个网络基础知识普及,看完成半个网络高手!下面,我们一起来看。 1)什么是链接? 链接是指两个设备之间…

团队冲刺第一天

今天要做什么:每个人都在网上学习Android软件开发的知识,完成简单的操作,实现简单功能。 明天要做什么:学习各种控件的作用,用法 站立会议照片: 任务看板照片: 燃尽图: 转载于:https…

[Leetcode][第679题][JAVA][24点游戏][回溯][暴力]

【问题描述】[困难] 【解答思路】 回溯 时间复杂度:O(1) 空间复杂度:O(1) class Solution {static final int TARGET 24;static final double EPSILON 1e-6;static final int ADD 0,MULTIPLY1,SUBTRACT 2,DIVIDE 3;public boolean judgePoint24(int…

第二十七期:网络爬虫程序员被抓,我们还敢爬虫吗?细数那些Java爬虫技术

最近,某大数据科技公司因为涉嫌非法抓取某招聘网站用户的简历信息,公司被查封,负责编写抓取程序的程序员也将面临坐牢。 作者:架构之路来源 最近,某大数据科技公司因为涉嫌非法抓取某招聘网站用户的简历信息&#xff…

文本搜索系统的评估

说明:文章内容来源于课程视频和课程ppt。我只学习了课程没有做习题。文章不是翻译,是我对课程的理解。  这部分本应该继续说反馈(FeedBack)的。但是课程中安排的是评估(Evaluation)。评估是用于衡量搜索引擎质量的。反馈是为了提高搜索引擎质量而进行的…

UE3客户端服务器GamePlay框架

客户端(当前玩家)与服务器对应关系图: 整体上看,UE3的GamePlay框架使用的是MVC架构 ① 橙色的Actor对象及橙色箭头相连的成员变量只会被同步给Owner客户端 Controller:控制器,包括PlayerController和AIController InventoryManage…

[Leetcode][第201题][JAVA][数字范围按位与][位运算][Brian Kernighan]

【问题描述】[中等] 【解答思路】 1. 暴力 逐位与 ,只需要判断i 0 或 i 2147483647 的话,就跳出 for 循环即可。 时间复杂度:O(N) 空间复杂度:O(1) public int rangeBitwiseAnd(int m, int n) {//m 要赋值给 i,所…

文档排序模型--查询似然Query Likelihood

在概率模型中,我们定义排序函数是基于文档与查询之间的相关度、可能性来做的。f(d,q) p(R1|d,q), R ∈{0,1}。概率模型有几个小分类:   经典概率模型——>BM25   语言模型Language Model —–>Query Likelihood   Divergence from rando…

第五十二期:甲骨文遭遇“中年危机”:继阿里后,再被亚马逊永久抛弃

42岁的甲骨文迎来“中年危机”。10月15日,亚马逊AWS技术布道者Jeff Barr在AWS官网宣布亚马逊消费者业务永久弃用甲骨文(Oracle)数据库。 作者:温暖来源:镁客网 42岁的甲骨文迎来“中年危机”。 10月15日,亚马逊AWS技术布道者Jef…

[Leetcode][第461题][JAVA][汉明距离][位运算][Brian Kernighan]

【问题描述】[简单] 【解答思路】 1. 内置位计数功能 时间复杂度:O(1) 空间复杂度:O(1) class Solution {public int hammingDistance(int x, int y) {return Integer.bitCount(x ^ y); } }2. 移位 时间复杂度:O(1) 空间复杂度&#xff1…

第二十八期:Notepad++ 新 Logo 出炉,官网全新改版采用自适应设计

Notepad 的推特帐号发布了关于 notepad 的消息。与旧版 Logo 相比,新 Logo 整体的变化不大,不过官方则表示新版 Logo 比旧版的更吸引人,也更加简洁且更具意义。 新旧 Logo 对比如下(左边为旧版 Logo): 除了…

React Navigation 导航栏样式调整+底部角标消息提示

五一佳节匆匆而过,有人选择在外面看人山人海,有人选择宅在家中度过五一,也有人依然坚守在第一线,致敬! 这是坚持学习react-native的第二篇文章,可能会迟到,但是绝不会缺席,这篇要涉及…