Kafka如何實現每秒上百萬的超高併發寫入?掌握好面試給你打滿分!

這篇文章來聊一下 Kafka 的一些架構設計原理,這也是互聯網公司面試時很是高頻的技術考點。java

Kafka 是高吞吐低延遲的高併發、高性能的消息中間件,在大數據領域有極爲普遍的運用。配置良好的 Kafka 集羣甚至能夠作到每秒幾十萬、上百萬的超高併發寫入。python

那麼 Kafka 究竟是如何作到這麼高的吞吐量和性能的呢?這篇文章咱們來詳細說一下。linux

頁緩存技術 + 磁盤順序寫

首先 Kafka 每次接收到數據都會往磁盤上去寫,以下圖所示:web

webp

那麼在這裏咱們不由有一個疑問了,若是把數據基於磁盤來存儲,頻繁的往磁盤文件裏寫數據,這個性能會不會不好?你們確定都以爲磁盤寫性能是極差的。
面試

沒錯,要是真的跟上面那個圖那麼簡單的話,那確實這個性能是比較差的。緩存

可是實際上 Kafka 在這裏有極爲優秀和出色的設計,就是爲了保證數據寫入性能,首先 Kafka 是基於操做系統的頁緩存來實現文件寫入的。性能優化

操做系統自己有一層緩存,叫作 Page Cache,是在內存裏的緩存,咱們也能夠稱之爲 OS Cache,意思就是操做系統本身管理的緩存。對大數據以及人工智能概念都是模糊不清的,該按照什麼線路去學習,學完往哪方面發展,想深刻了解,想學習的同窗歡迎加入大數據學習扣羣:數據515—269+數字485,有大量乾貨(零基礎以及進階的經典實戰)分享給你們,而且有清華大學畢業的資深大數據講師給你們免費授課,給你們分享目前國內最完整的大數據高端實戰實用學習流程體系 。從java和linux入手,其後逐步的深刻到HADOOP-hive-oozie-web-flume-python-hbase-kafka-scala-SPARK等相關知識一一分享!架構

你在寫入磁盤文件的時候,能夠直接寫入這個 OS Cache 裏,也就是僅僅寫入內存中,接下來由操做系統本身決定何時把 OS Cache 裏的數據真的刷入磁盤文件中。併發

僅僅這一個步驟,就能夠將磁盤文件寫性能提高不少了,由於其實這裏至關因而在寫內存,不是在寫磁盤,你們看下圖:分佈式

webp

接着另一個就是 kafka 寫數據的時候,很是關鍵的一點,它是以磁盤順序寫的方式來寫的。

也就是說,僅僅將數據追加到文件的末尾,不是在文件的隨機位置來修改數據。

普通的機械磁盤若是你要是隨機寫的話,確實性能極差,也就是隨便找到文件的某個位置來寫數據。

可是若是你是追加文件末尾按照順序的方式來寫數據的話,那麼這種磁盤順序寫的性能基本上能夠跟寫內存的性能自己也是差很少的。

因此你們就知道了,上面那個圖裏,Kafka 在寫數據的時候,一方面基於 OS 層面的 Page Cache 來寫數據,因此性能很高,本質就是在寫內存罷了。

另一個,它是採用磁盤順序寫的方式,因此即便數據刷入磁盤的時候,性能也是極高的,也跟寫內存是差很少的。

基於上面兩點,Kafka 就實現了寫入數據的超高性能。那麼你們想一想,假如說 Kafka 寫入一條數據要耗費 1 毫秒的時間,那麼是否是每秒就是能夠寫入 1000 條數據?

可是假如 Kafka 的性能極高,寫入一條數據僅僅耗費 0.01 毫秒呢?那麼每秒是否是就能夠寫入 10 萬條數據?

因此要保證每秒寫入幾萬甚至幾十萬條數據的核心點,就是盡最大可能提高每條數據寫入的性能,這樣就能夠在單位時間內寫入更多的數據量,提高吞吐量。

零拷貝技術

說完了寫入這塊,再來談談消費這塊。

你們應該都知道,從 Kafka 裏咱們常常要消費數據,那麼消費的時候實際上就是要從 Kafka 的磁盤文件裏讀取某條數據而後發送給下游的消費者,以下圖所示:


webp

那麼這裏若是頻繁的從磁盤讀數據而後發給消費者,性能瓶頸在哪裏呢?

假設要是 Kafka 什麼優化都不作,就是很簡單的從磁盤讀數據發送給下游的消費者,那麼大概過程以下所示:

先看看要讀的數據在不在 OS Cache 裏,若是不在的話就從磁盤文件裏讀取數據後放入 OS Cache。

接着從操做系統的 OS Cache 裏拷貝數據到應用程序進程的緩存裏,再從應用程序進程的緩存裏拷貝數據到操做系統層面的 Socket 緩存裏。

最後從 Socket 緩存裏提取數據後發送到網卡,最後發送出去給下游消費。

整個過程,以下圖所示:

webp

你們看上圖,很明顯能夠看到有兩次不必的拷貝吧!一次是從操做系統的 Cache 裏拷貝到應用進程的緩存裏,接着又從應用程序緩存裏拷貝回操做系統的 Socket 緩存裏。

並且爲了進行這兩次拷貝,中間還發生了好幾回上下文切換,一下子是應用程序在執行,一下子上下文切換到操做系統來執行。

因此這種方式來讀取數據是比較消耗性能的。Kafka 爲了解決這個問題,在讀數據的時候是引入零拷貝技術。

也就是說,直接讓操做系統的 Cache 中的數據發送到網卡後傳輸給下游的消費者,中間跳過了兩次拷貝數據的步驟,Socket 緩存中僅僅會拷貝一個描述符過去,不會拷貝數據到 Socket 緩存。

你們看下圖,體會一下這個精妙的過程:

webp

webp

經過零拷貝技術,就不須要把 OS Cache 裏的數據拷貝到應用緩存,再從應用緩存拷貝到 Socket 緩存了,兩次拷貝都省略了,因此叫作零拷貝。

對 Socket 緩存僅僅就是拷貝數據的描述符過去,而後數據就直接從 OS Cache 中發送到網卡上去了,這個過程大大的提高了數據消費時讀取文件數據的性能。

並且你們會注意到,在從磁盤讀數據的時候,會先看看 OS Cache 內存中是否有,若是有的話,其實讀數據都是直接讀內存的。

若是 Kafka 集羣通過良好的調優,你們會發現大量的數據都是直接寫入 OS Cache 中,而後讀數據的時候也是從 OS Cache 中讀。

至關因而 Kafka 徹底基於內存提供數據的寫和讀了,因此這個總體性能會極其的高。

說個題外話,下回有機會給你們說一下 Elasticsearch 的架構原理,其實 ES 底層也是大量基於 OS Cache 實現了海量數據的高性能檢索的,跟 Kafka 原理相似。

總結

經過這篇文章對 Kafka 底層的頁緩存技術的使用,磁盤順序寫的思路,以及零拷貝技術的運用,你們應該就明白 Kafka 每臺機器在底層對數據進行寫和讀的時候採起的是什麼樣的思路,爲何它的性能能夠那麼高,作到每秒幾十萬的吞吐量。

這種設計思想對咱們平時本身設計中間件的架構,或者是出去面試的時候,都有很大的幫助。

看到最後的都是真愛了,感受文章不錯的記得給小編點個贊哦,關注小編,之後會有更多的精品文章輸出哦。

做者福利:

給你們推薦一個架構技術交流羣:714827309 ,裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析 ,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系。還能領取免費的學習資源,相信對於已經工做 和遇到技術瓶頸的碼友,在這個羣裏會有你須要的內容。 點擊連接加入羣聊【JAVA高級架構技術交流】:jq.qq.com/?_wv=1027&a…


相關文章
相關標籤/搜索