【kafka】为什么快(why‘s kafka so fast)?

大家好我又来了!我先提前说下,本文其实是比较早之前我整理给自己看的,那时候是看到外网有一篇文章说到这个事情,具体作者是谁我已经忘记了(因为原文已经访问不了,好像是因为域名过期了),但是其实大家直接搜索“why's kafka so fast”这样的关键字,还是可以找到不少转载的英文原文博客!

外网原文地址:http://searene.me/2017/07/09/Why-is-Kafka-so-fast/

 

这次来说说面试中时场被问到的kafka为什么快?

kafka这个框架应该很多做流式数据处理的公司都避不开的,一般是把各种各样的数据灌入kafka,后面对接各种数据处理框架,比如spark,flink,druid

1、顺序读写磁盘(避免了随机读写)

kafka数据的写入和消费者读取数据都是顺序读写的

kafka官网给的图:

 

(速度明显好很多)

 

2-1、kafka写数据到磁盘,而不写到内存

对,我相信很多人看到这句话就懵了!啥,写磁盘不是反而慢吗,但是大多数说磁盘比内存慢,是基于随机读写的磁盘的场景说的,kafka用顺序读写磁盘其实速度上不会比随机读写内存差太多,但是确实顺序内存会比顺序磁盘快!

 

 

那么为什么kafka还是选用磁盘不用内存?

1)、因为kafka运行在JVM,如果数据写成object存在内存中,占用的空间要翻倍(因为有一些对象信息七七八八的)

2)、用JVM的内存就必须涉及到GC,GC非常的影响速度

所以kafka使用MMAP来解决这个场景

 

2-2、Memory Mapped Files(MMAP)

通常来说,MMAP是把磁盘上的文件映射到内存中,我们写数据到这块映射的内存上,系统会延迟flush到磁盘上,所以写入也很快,因为实际上是写入了内存,不是直接写磁盘。但是使用MMAP就有可能数据丢失,因为数据先写到内存上,如果这时候机器断电,那数据就会丢失,所以其实kafka生产者可以设置同步发送还是异步发送!

 

 

3、Zero Copy(零拷贝)

linux内存分为内核态和用户态,当我们通过一个spring服务访问服务器上磁盘上数据的时候,其实是Kernel从把磁盘上的数据读取到内核态中然后推送到用户态(应用程序)中,然后再通过Socket发送到网络中(发送给请求的那个client)

但是linux底层实现了零拷贝机制(sendfile),应用程序直接调用linux底层的sendfile,告诉内核态要把数据发送到哪里,然后内核态读到数据之后,直接发给对应的Socket,避免了数据流进用户态的步骤!

但是零拷贝也是有缺陷的!数据不经过应用程序就发出去了,也就是说我不能对数据进行任何的处理,所以你发现kafka确实是不对数据做任何的修改过滤对吧!

 

这是linux提供的零拷贝的功能

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

sendfile(socket, file, len);

如下图:

 

4、Batch Data(数据批量处理)

1、这个也很好理解,kafka只有当达到batch.size才发送数据,代替了一条一条发送的方式,批量处理的方式在很多地方都会用到,比如数据库批量插入等等

2、并且批量发送数据的时候也可以做一些压缩,减少io的压力,增加发送消息的能力

 

嗯,本文基本上是翻译了那篇英文原文,然后加上了自己的一些些想法和叙述!大家如果有兴趣建议还是可以去看看英文原文的,我就不放链接了,还是比较好搜索到的(关键词:why's kafka so fast)

菜鸡一只,下次再见拜拜~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章