<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          消息中間件相關(guān)的面試題

          共 3601字,需瀏覽 8分鐘

           ·

          2021-09-19 09:38


          點(diǎn)擊上方 藍(lán)字 關(guān)注我們!



          2021 最新 Java 編程資料免費(fèi)領(lǐng)!Java 視頻教程,Java Web 項(xiàng)目教程,互聯(lián)網(wǎng)Java 面試真題 / 算法題,簡(jiǎn)歷模板,Linux 服務(wù)器等等,點(diǎn)擊領(lǐng)取!

          來源:cnblogs.com/starluke/p/12558952.html

          • 一、順序讀寫
          • 二、Page Cache
          • 三、零拷貝
          • 四、分區(qū)分段+索引
          • 五、批量讀寫
          • 六、批量壓縮

          Kafka是大數(shù)據(jù)領(lǐng)域無處不在的消息中間件,目前廣泛使用在企業(yè)內(nèi)部的實(shí)時(shí)數(shù)據(jù)管道,并幫助企業(yè)構(gòu)建自己的流計(jì)算應(yīng)用程序。

          Kafka雖然是基于磁盤做的數(shù)據(jù)存儲(chǔ),但卻具有高性能、高吞吐、低延時(shí)的特點(diǎn),其吞吐量動(dòng)輒幾萬、幾十上百萬。

          但是很多使用過Kafka的人,經(jīng)常會(huì)被問到這樣一個(gè)問題,Kafka為什么速度快,吞吐量大;大部分被問的人都是一下子就懵了,或者是只知道一些簡(jiǎn)單的點(diǎn),本文就簡(jiǎn)單的介紹一下Kafka為什么吞吐量大,速度快。

          一、順序讀寫

          眾所周知Kafka是將消息記錄持久化到本地磁盤中的,一般人會(huì)認(rèn)為磁盤讀寫性能差,可能會(huì)對(duì)Kafka性能如何保證提出質(zhì)疑。實(shí)際上不管是內(nèi)存還是磁盤,快或慢關(guān)鍵在于尋址的方式,磁盤分為順序讀寫與隨機(jī)讀寫,內(nèi)存也一樣分為順序讀寫與隨機(jī)讀寫?;诖疟P的隨機(jī)讀寫確實(shí)很慢,但磁盤的順序讀寫性能卻很高,一般而言要高出磁盤隨機(jī)讀寫三個(gè)數(shù)量級(jí),一些情況下磁盤順序讀寫性能甚至要高于內(nèi)存隨機(jī)讀寫。

          這里給出著名學(xué)術(shù)期刊 ACM Queue 上的性能對(duì)比圖:

          圖片

          磁盤的順序讀寫是磁盤使用模式中最有規(guī)律的,并且操作系統(tǒng)也對(duì)這種模式做了大量?jī)?yōu)化,Kafka就是使用了磁盤順序讀寫來提升的性能。Kafka的message是不斷追加到本地磁盤文件末尾的,而不是隨機(jī)的寫入,這使得Kafka寫入吞吐量得到了顯著提升 。

          圖片

          上圖就展示了Kafka是如何寫入數(shù)據(jù)的, 每一個(gè)Partition其實(shí)都是一個(gè)文件 ,收到消息后Kafka會(huì)把數(shù)據(jù)插入到文件末尾(虛框部分)。

          這種方法有一個(gè)缺陷—— 沒有辦法刪除數(shù)據(jù) ,所以Kafka是不會(huì)刪除數(shù)據(jù)的,它會(huì)把所有的數(shù)據(jù)都保留下來,每個(gè)消費(fèi)者(Consumer)對(duì)每個(gè)Topic都有一個(gè)offset用來表示 讀取到了第幾條數(shù)據(jù) 。

          圖片

          兩個(gè)消費(fèi)者,Consumer1有兩個(gè)offset分別對(duì)應(yīng)Partition0、Partition1(假設(shè)每一個(gè)Topic一個(gè)Partition);Consumer2有一個(gè)offset對(duì)應(yīng)Partition2。這個(gè)offset是由客戶端SDK負(fù)責(zé)保存的,Kafka的Broker完全無視這個(gè)東西的存在;一般情況下SDK會(huì)把它保存到zookeeper里面。(所以需要給Consumer提供zookeeper的地址)。

          如果不刪除硬盤肯定會(huì)被撐滿,所以Kakfa提供了兩種策略來刪除數(shù)據(jù)。一是基于時(shí)間,二是基于partition文件大小。具體配置可以參看它的配置文檔。


          二、Page Cache

          為了優(yōu)化讀寫性能,Kafka利用了操作系統(tǒng)本身的Page Cache,就是利用操作系統(tǒng)自身的內(nèi)存而不是JVM空間內(nèi)存。這樣做的好處有:

          • 避免Object消耗:如果是使用 Java 堆,Java對(duì)象的內(nèi)存消耗比較大,通常是所存儲(chǔ)數(shù)據(jù)的兩倍甚至更多。
          • 避免GC問題:隨著JVM中數(shù)據(jù)不斷增多,垃圾回收將會(huì)變得復(fù)雜與緩慢,使用系統(tǒng)緩存就不會(huì)存在GC問題

          相比于使用JVM或in-memory cache等數(shù)據(jù)結(jié)構(gòu),利用操作系統(tǒng)的Page Cache更加簡(jiǎn)單可靠。

          首先,操作系統(tǒng)層面的緩存利用率會(huì)更高,因?yàn)榇鎯?chǔ)的都是緊湊的字節(jié)結(jié)構(gòu)而不是獨(dú)立的對(duì)象。

          其次,操作系統(tǒng)本身也對(duì)于Page Cache做了大量?jī)?yōu)化,提供了 write-behind、read-ahead以及flush等多種機(jī)制。

          再者,即使服務(wù)進(jìn)程重啟,系統(tǒng)緩存依然不會(huì)消失,避免了in-process cache重建緩存的過程。

          通過操作系統(tǒng)的Page Cache,Kafka的讀寫操作基本上是基于內(nèi)存的,讀寫速度得到了極大的提升。

          三、零拷貝

          linux操作系統(tǒng) “零拷貝” 機(jī)制使用了sendfile方法, 允許操作系統(tǒng)將數(shù)據(jù)從Page Cache 直接發(fā)送到網(wǎng)絡(luò),只需要最后一步的copy操作將數(shù)據(jù)復(fù)制到 NIC 緩沖區(qū), 這樣避免重新復(fù)制數(shù)據(jù) 。示意圖如下:

          圖片

          通過這種 “零拷貝” 的機(jī)制,Page Cache 結(jié)合 sendfile 方法,Kafka消費(fèi)端的性能也大幅提升。這也是為什么有時(shí)候消費(fèi)端在不斷消費(fèi)數(shù)據(jù)時(shí),我們并沒有看到磁盤io比較高,此刻正是操作系統(tǒng)緩存在提供數(shù)據(jù)。

          當(dāng)Kafka客戶端從服務(wù)器讀取數(shù)據(jù)時(shí),如果不使用零拷貝技術(shù),那么大致需要經(jīng)歷這樣的一個(gè)過程:

          1. 操作系統(tǒng)將數(shù)據(jù)從磁盤上讀入到內(nèi)核空間的讀緩沖區(qū)中。
          2. 應(yīng)用程序(也就是Kafka)從內(nèi)核空間的讀緩沖區(qū)將數(shù)據(jù)拷貝到用戶空間的緩沖區(qū)中。
          3. 應(yīng)用程序?qū)?shù)據(jù)從用戶空間的緩沖區(qū)再寫回到內(nèi)核空間的socket緩沖區(qū)中。
          4. 操作系統(tǒng)將socket緩沖區(qū)中的數(shù)據(jù)拷貝到NIC緩沖區(qū)中,然后通過網(wǎng)絡(luò)發(fā)送給客戶端。
          no zero cop

          從圖中可以看到,數(shù)據(jù)在內(nèi)核空間和用戶空間之間穿梭了兩次,那么能否避免這個(gè)多余的過程呢?當(dāng)然可以,Kafka使用了零拷貝技術(shù),也就是直接將數(shù)據(jù)從內(nèi)核空間的讀緩沖區(qū)直接拷貝到內(nèi)核空間的socket緩沖區(qū),然后再寫入到NIC緩沖區(qū),避免了在內(nèi)核空間和用戶空間之間穿梭。

          zero copy

          可見,這里的零拷貝并非指一次拷貝都沒有,而是避免了在內(nèi)核空間和用戶空間之間的拷貝。如果真是一次拷貝都沒有,那么數(shù)據(jù)發(fā)給客戶端就沒了不是?不過,光是省下了這一步就可以帶來性能上的極大提升。

          四、分區(qū)分段+索引

          Kafka的message是按topic分類存儲(chǔ)的,topic中的數(shù)據(jù)又是按照一個(gè)一個(gè)的partition即分區(qū)存儲(chǔ)到不同broker節(jié)點(diǎn)。每個(gè)partition對(duì)應(yīng)了操作系統(tǒng)上的一個(gè)文件夾,partition實(shí)際上又是按照segment分段存儲(chǔ)的。這也非常符合分布式系統(tǒng)分區(qū)分桶的設(shè)計(jì)思想。

          通過這種分區(qū)分段的設(shè)計(jì),Kafka的message消息實(shí)際上是分布式存儲(chǔ)在一個(gè)一個(gè)小的segment中的,每次文件操作也是直接操作的segment。為了進(jìn)一步的查詢優(yōu)化,Kafka又默認(rèn)為分段后的數(shù)據(jù)文件建立了索引文件,就是文件系統(tǒng)上的.index文件。這種分區(qū)分段+索引的設(shè)計(jì),不僅提升了數(shù)據(jù)讀取的效率,同時(shí)也提高了數(shù)據(jù)操作的并行度。

          五、批量讀寫

          Kafka數(shù)據(jù)讀寫也是批量的而不是單條的。

          除了利用底層的技術(shù)外,Kafka還在應(yīng)用程序?qū)用嫣峁┝艘恍┦侄蝸硖嵘阅堋W蠲黠@的就是使用批次。在向Kafka寫入數(shù)據(jù)時(shí),可以啟用批次寫入,這樣可以避免在網(wǎng)絡(luò)上頻繁傳輸單個(gè)消息帶來的延遲和帶寬開銷。假設(shè)網(wǎng)絡(luò)帶寬為10MB/S,一次性傳輸10MB的消息比傳輸1KB的消息10000萬次顯然要快得多。

          六、批量壓縮

          在很多情況下,系統(tǒng)的瓶頸不是CPU或磁盤,而是網(wǎng)絡(luò)IO,對(duì)于需要在廣域網(wǎng)上的數(shù)據(jù)中心之間發(fā)送消息的數(shù)據(jù)流水線尤其如此。進(jìn)行數(shù)據(jù)壓縮會(huì)消耗少量的CPU資源,不過對(duì)于kafka而言,網(wǎng)絡(luò)IO更應(yīng)該需要考慮。

          1. 如果每個(gè)消息都?jí)嚎s,但是壓縮率相對(duì)很低,所以Kafka使用了批量壓縮,即將多個(gè)消息一起壓縮而不是單個(gè)消息壓縮
          2. Kafka允許使用遞歸的消息集合,批量的消息可以通過壓縮的形式傳輸并且在日志中也可以保持壓縮格式,直到被消費(fèi)者解壓縮
          3. Kafka支持多種壓縮協(xié)議,包括Gzip和Snappy壓縮協(xié)議

          Kafka速度的秘訣在于,它把所有的消息都變成一個(gè)批量的文件,并且進(jìn)行合理的批量壓縮,減少網(wǎng)絡(luò)IO損耗,通過mmap提高I/O速度,寫入數(shù)據(jù)的時(shí)候由于單個(gè) Partition 是末尾添加所以速度最優(yōu);讀取數(shù)據(jù)的時(shí)候配合sendfile直接暴力輸出

          往期推薦

          SpringBoot+Redis 如何防止瞬間幾千次的重復(fù)提交?

          放棄 CTO 頭銜說:寫代碼才最快樂。這才是我真正喜歡的事情。

          熱議:最近互聯(lián)網(wǎng)是不是開始內(nèi)卷了?

          面試最后一環(huán)節(jié),如何向面試官提問?

          7 種 Spring Boot 注入 Bean 的方式


          END



          若覺得文章對(duì)你有幫助,隨手轉(zhuǎn)發(fā)分享,也是我們繼續(xù)更新的動(dòng)力。


          長(zhǎng)按二維碼,掃掃關(guān)注哦

          ?「C語言中文網(wǎng)」官方公眾號(hào),關(guān)注手機(jī)閱讀教程 ?



          學(xué)習(xí)資料包括: Java,算法,數(shù)據(jù)庫(kù),Linux,簡(jiǎn)歷,運(yùn)維 等編程分類,在不斷更新中哦


          點(diǎn)擊“閱讀原文”,馬上免費(fèi)領(lǐng)取!
          ??????
          瀏覽 58
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线播放 亚洲 | 亚洲无码在线看片 | 国产高清无码在线不卡视频 | 日韩欧美天堂 | 国产一区二区精品 |