【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)

菜雞一隻,下次再見拜拜~

 

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