閆燕飛:Kafka的高性能揭祕及優化

歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~前端

本文首發在雲+社區,未經許可,不得轉載。後端

你們下午好,我是來自騰訊雲基礎架構部ckafka團隊的高級工程師閆燕飛。今天在這裏首先爲你們先分享一下開源Kafka在高性能上面的一些關鍵點,而後我會分享一下咱們騰訊雲ckafka對社區Kafka所作的一些優化點,最後我會介紹一下我對Kafka社區將來的展望。緩存

Kafka高性能揭祕

在這裏首先我會介紹一下整個Kafka的架構,讓你們對Kafka有一個較爲宏觀的瞭解,緊接着我會在更加詳細的介紹一下Kafka的存儲方式以及具體消息存儲格式。固然爲了方便你們對kafka的高性能有個直觀的理解,最後我也會給出其性能數據。性能優化

整體架構

咱們能夠看到Kafka整個集羣裏面僅僅包含了Broker,zookeeper兩個組件。服務器

Broker是整個Kafka集羣的核心引擎,負責消息的存儲轉發,並對外提供服務。咱們能夠看到,Kafka集羣能夠很是簡單的經過增刪Broker,實現整個集羣的擴縮容。Kafka對外提供服務的基本單位是Topic,那麼實現Topic級別的平行擴展能力,也就實現了應用級的平行擴展能力。爲了實現應用級的平行擴展能力,Kafka採用了對Topic進行分區的作法,經過對Topic進行分區讓不一樣的分區落在不一樣的Broker上,從而利用到更多Broker的能力,最終實現了應用級的水平擴展。微信

Zookeeper則在整個集羣中則主要負責存儲一些配置信息、Broker信息、Topic信息等等元數據,而且承擔了一部分協調選主的功能,能夠將其理解爲Kafka集羣的配置管理中心。講到這裏,你們會以爲在Kafka集羣中,能夠簡單的經過Broker動態的增刪實現集羣擴縮容,但在整個集羣中卻僅僅存在一個Zookeeper,那麼Zookeeper會不會成爲整個集羣的瓶頸點,從而制約了整個集羣的平行擴展能力?的確,在Kafka一些較老版本,Kafka的生產者及消費者都須要與Zookeeper進行通訊交互,進行元數據拉取、消費分組協調、以及消費分組offset提交與保存等等。這樣形成的一個問題,就是全部的客戶端都要直接與ZooKeeper進行通信交互,對其形成了很是大的壓力,影響了系統的穩定性,最終影響整Kafka集羣的平行擴展能力。但從0.9(含)版本以後,Kafka團隊對整個Kafka進行了優化中,經過增長了一些協議,而且增長了協調模塊。當前Kafka已經作到了客戶端的生產及消費不須要與Zookeeper進行任何通信交互,故Zookeeper當前僅僅充當了配置管理中心,壓力很是的小,不會成爲集羣的瓶頸點進而制約集羣的水平擴展能力。網絡

你們也能夠看到生產者及消費者是直接與Broker進行交互實現生產消費功能,Kafka在設計上並未採用傳統系統中經過增長一層代理實現系統的平行擴展能力。Kafka在設計中經過內部路由協議,實現了生產者與消費者能夠直接與Broker進行路由協商,從而實現了客戶端直接與Broker進行生產消費,而不須要藉助第三方代理。無代理的方式不只會減小整個數據鏈路的長度,下降延遲,也能夠提升整個系統的穩定性,並且也會節省大量的成本。多線程

總結下Kafka的整體架構體現了以下幾個主要的優點。其一,Kafka集羣能夠經過增刪Broker實集羣級的水平擴展。其二,經過對Topic進行分區,實現了應用級別的無限平行擴展能。其三,經過優良通信協議,實現了生產系統直接與後端的Broker進行通信,節省了代理,不只減小了數據鏈路長度下降了延遲,並且極大的下降了成本。架構

至此,我想你們對Kafka已經有一個較爲宏觀瞭解。咱們知道系統整體架構,決定了整個系統的能力上限。但系統中關鍵組件的性能,則是決定了相同能力下集羣中服務器數量。服務器數量的增長,不只僅會增長成本,並且會帶來更多的運維壓力及影響系統的穩定性。因此下面我將會介紹下Kafka核心引擎Broker的系統架構。併發

Broker架構

咱們能夠看Broker是一個典型的Reactor模型,其主要包含一個網絡線程池,負責處理網絡請求進行網絡的收發以及打包解包,而後把請求經過請求隊列推送給核心處理模塊,由其負責真正的業務邏輯處理(Kafka會把全部消息落地存儲,故主要是些文件I/0操做)。咱們能夠看到kafka採用多線程方式,能夠充分利用現代系統的多核優點。其次,其採用隊列方式實現了網絡處理模塊及核心處理模塊的異步解耦,實現了網絡處理和文件I/O並行處理,極大的提升了整個系統的效率。

講到這裏,你們對Kafka架構已經有一個宏觀的理解。上面咱們也提到,Kafka會把全部的消息都落地存儲。那麼爲何Kafka並未像傳統的消息隊列那樣很是害怕磁盤,勁量緩存而不觸碰磁盤?Kafka爲何選擇了將全部消息都落地存儲?下面我將經過講解其存儲組織方式及存儲格式,爲你們進行一一揭祕。

存儲的組織方式

這個就是當前Kafka的存儲組織方式,咱們能夠看到Topic,其實只是邏輯概念,並不對應任何物理實體,爲了實現Topic的水平擴展,Kafka會對其進行分區。Partition則以目錄形式進行展示,同時Partition中具體的數據還未進行分片存儲。這樣在生產時,就能快速的找到最新的分配直接追加到文件末尾,能夠看到Kafka在生產中充分利用了磁盤的順序寫,極大的提升了生產的吞吐能力。同時進行分片存儲,還有一個好處就是咱們能夠很是方便的經過刪除老的分片實現過時消息的刪除。同時爲了方便消費,Kafka在分片的命名上也採用了必定的技巧,分片的命名採用了其包含的第一條消息的offset進行格式化這樣,在消費數據時,能夠很是方便的經過二分查找定位到消息所在的文件分片。同時爲了實現分片內快速定位,Kafka也會對每一個數據分片創建兩個稀疏索引文件,經過索引文件,採用二分查找能夠很是快速的定位了指定消息在數據分片中的位置,進而進行消費。經過講解咱們能夠看到Kafka的整個生產消費其實都是順序讀寫,充分利用了磁盤順序讀寫能力。其次,Kafka的消費,採用了二級二分查找,其查找性能僅僅依賴一個分片的索引大小,不會受整個系統數據量的影響。

Kafka處理的最基本單位是消息,那麼Kafka的消息具體是什麼格式?落地存儲的消息又具體是什麼格式?不用說這些都將極大的影響系統的性能,因此下面我也將會詳細的介紹下Kafka的消息格式。

消息格式

爲方便你們理解,這裏我就以C代碼的形式進行消息格式展現。Kafka消息實際上是採用的簡單的二進制編碼,網絡字節序存儲,故能夠很是高效的進行編解碼操做。同時,咱們能夠看到整個Kafka消息頭部很是的緊湊,僅僅只有30個字節左右,並且還包含了crc校驗碼用於對消息進行相關的校驗。同時在Kafka中最爲精妙的是,該消息的格式在生產系統端、網絡傳輸中、Broker端,包括最終的文件存儲中,都保持了消息格式的一致性。因此使得消息在整個系統的傳輸中,不須要有任何轉碼,效率奇高。固然爲了提升整個系統的吞吐,Kafka這邊實現了消息的批量生產消費。批量消息在Kafka中表現形式爲,以二進制形式在內存中一個個排列起來。同時爲了提升系統網絡及磁盤的利用率,Kafka仍是實現了消息壓縮,右邊這個流程圖則詳細的說明了消息壓縮的流程。能夠看到,首先咱們把整個批量消息以一個總體進行壓縮,生成一個新的二進制串。而後,把該值打包到一個新的消息的value字段中。能夠看到Kafka很是巧妙的經過消息嵌套方式實現了消息的批量壓縮,提升了總體壓縮效率。同時該方式也保證了消息的格式的一致性。保持消息一致性就有如下好處:其一,咱們在整個消息流轉中僅僅須要生產者進行一次壓縮後,將該壓縮消息發送到Broker端後,Broker端僅須要一次解壓操做,用以進行消息校驗,並進行消息offset設置,後就能直接把消息直接存儲在文件中,不須要有Broker進行一次很是消耗性能的壓縮操做。因此說即便採用的消息壓縮,對於Broker端的消耗也很是低。同時因爲保持了壓縮消息格式的一致性,當有消費請求時,Broker不用進行任何解壓及壓縮操做,能夠直接將消息以壓縮的方式發送給消費者,由消費者負責解壓,這樣的話Broker在整個消費中也就不須要任何的解壓及壓縮的操做,能夠極大的提升Broker端的性能。能夠看到Kafka經過這種方式,很是簡單的實現了端到端的數據壓縮,把計算資源消耗分攤到生產系統和消費系統中。

Kafka高性能

因爲時間緣由,講到這裏Kafka高性能的關鍵點也基本都涵蓋了,固然Kafka團隊爲了其高性能仍是有不少巧妙的設計,這裏因爲時間緣由就不在一一贅述,固然這頁PPT中則詳細的列舉了其高性能的關鍵點,你們下面有興趣能夠本身對着這些關鍵點本身仔細琢磨。

講了這麼多Kafka高性能的關鍵點,但到底其有着什麼樣的性能?爲使你們對整個Kafka的性能有一個較爲直觀的認識,下面我也將給你們提出相關的性能測試數據。固然任何性能測試若是沒有前置的測試條件則都是在空說,因此在給出數據前,先給一下測試的配置條件.1、測試場景是一個Broker單topic,多個partition。2、機器硬件配置是32核 64G內存,萬兆網卡,同時掛載12塊2T SATA盤,而且對SATA盤作了軟RAID10。3、Broker版本上咱們選擇是0.10.2.0。Broker配置方面,咱們選擇的是每10萬條消息或兩秒進行一次刷盤。4、咱們使用社區Kafka的原生壓測工具,並同時開啓140客戶進行壓測,用於模擬必定的併發。固然我後面全部壓測數據都是基於這個統一的配置,後面介紹時我就再也不相信敘述測試條件了。

經過下面的表格,咱們能夠看到Kafka在小包的狀況下輕鬆達到百萬級別的qps,並且即便在1K的大包狀況下也達到了幾十萬級別的qps,能夠說整個Kafka性能仍是很是強悍的。但同時咱們也發現Kafka Broker在測試中,的CPU使用率,尤爲是磁盤I/O使用率並不高,說明社區Kafka仍是有必定的優化空間。因此下面我就介紹一下咱們CKafka對社區Kafka的一些優化點。

Kafka性能優化

在這個章節裏面,首先我會帶領你們進一步的深刻了解一下整個 Broker端的架構,經過進一步瞭解他的架構,找出它可能的瓶頸點,而後在針對瓶頸點進行優化優化。緊接着我將會挑出幾個具體的優化點進行詳細的介紹。

當前架構剖析

在這裏爲了方便你們理解,咱們用一次真實的請求,通過的路徑,來講明Broker各個模塊是怎麼交互的。首先,當一個生產啓動,他須要去和Broker進行鏈接,Broker端會有一個Accept線程模塊進行鏈接監聽用於創建新的鏈接,在鏈接創建後Accept會將網絡鏈接輪詢轉發給給網絡接收發送處理線程池中的一個線程處理,至此鏈接接入已經完成。下面將進入數據請求,這時候生產者發送的生產請求數據,將直接由網絡收發處理線程進行處理,每當網絡線程收到一個完整的包,並進完成解包操做後,就會將請求推送到請求隊列,由後端核心處理線程進行真正的邏輯處理。後端核心I/O處理線程會競爭的從請求隊列中拉取到生產請求任務後,首先,其會對相應的消息進行解析,建立相應的消息對象,而後消息對象進行一些合法性校驗,並設置相應的offset,當完成這些後會將消息寫入文件。固然寫入完成後會檢測未刷盤的消息個數是否達到刷盤要求,若是達到刷盤要求,該線程還會主動進行刷盤操做,最後把這個處理結果經過每一個網絡處理線程的應答隊列,返回給對應的網絡處理線程,最後由網絡線程進行打包並把結果返回給生產端,至此一個生產流程就以完成。

在這個流程中,咱們能夠發現:1、在整個Kafka的架構中,僅僅只有一個請求隊列,並且該隊列還未進行任何無鎖化優化,這樣會致使網絡處理線程池以及核心I/O處理線程產生激烈的鎖競爭,從而有可能影響整個系統的併發性,進而影響到系統的性能。因此這個是咱們應該想到一個優化點。其二,咱們剛纔講到Kafka選擇直接在覈心處線程中直接進行磁盤刷盤,這樣會致使堵塞整個核心流程,進而影響整個系統的性能。這也是咱們今天發現的須要優化的第二個一個優化點。其三,就是咱們發如今生產消息中會生成大量的消息對象,用於進行消息的合法性的校驗。產生大量的消息對象,會對jvm的GC產生較大的影響,可能會成爲系統性能的瓶頸點。固然咱們ckafka對社區kafka還作了不少其它方面的優化,這裏有因爲時間關係,主要集中這三點進行介紹。

鎖優化

咱們初版的鎖優化,經過架構圖能夠看到,實際上是很是簡單的。咱們直接把broker端僅有的一個請求隊列,替換成一個無鎖請求隊列,固然咱們也對全部的應答隊列進行了無鎖隊列的替換優化。通過這一輪優化,咱們具體到達成一個什麼效果?這個就是當前無鎖隊列的優化結果。經過對比咱們能夠發現,通過無鎖隊列優化後,相對於社區版本Kafka,整個性能基本上保持了一致。但按照咱們以前的分析,按理說應該會有較大的性能提高才對,但爲啥沒有達到預期效果?

爲一探究竟,咱們又對 Broker進行了更爲詳細的統計分析。經過統計分析後,咱們統計了請求次數,經過下面的統計圖表,咱們發現無論是社區Kafka,仍是咱們優化的版本,即便在百萬qps的消息狀況下,生產請求個數都很是的少,都是在10w級別如下。講到這裏咱們明白了,正是因爲開源Kafka這邊採用了批量發送的方式,合併了大量的生產請求,使的整個Broker端的請求次數急劇的減小,請求量的減小就使得網絡處理線程及核心處理線程間的鎖爭用減小,在當前請求量級的狀況下鎖爭用不太會成爲真個系統的瓶頸點,因此咱們的無鎖隊列沒有達到理想的效果也是正常的。講到這裏,能夠說咱們第一個優化實際上是不太成功的,可是優化道路老是漫長曲折的,一次不成功也正常也不會嚇到咱們,咱們ckafka會持續不但的在優化道路上前行。

文件刷盤優化

下面咱們進行第二個優化點的介紹,異步刷盤優化。在異步刷盤優化方面,咱們ckafka專門增長了一組刷盤線程,專門用於磁盤刷盤,這樣當核心線程發現須要有刷盤須要時,直接生成一個刷盤任務,並將刷盤任務經過無鎖隊列推送給刷盤線程,由其進行刷盤便可。這樣的話咱們就能夠實如今刷盤時不堵塞核心處理線程處理,會極大的提升一個系統的性能。固然通過這一輪的話後咱們到底有沒有效果?具體咱們看一下下面的性能對比數據。

通過異步刷盤優化後,咱們能夠看到,優化後的吞吐在小包狀況下,較社區版本有4到5倍的性能提高,同時即便是在大包狀況下也有一倍左右的性能提高(隨着包的增大及partition的增多優化後的提高會成降低趨勢)。同時咱們能夠發如今咱們異步刷盤優化的測試過程當中,整個系統的I/O使用率已經很是搞了,基本都在90%以上了,能夠說如今整個系統的瓶頸點應該就是磁盤I/O了,同時超過90%的I/O使用率,說明咱們已經榨乾了系統磁盤的性能,也表示咱們後續的吞吐量優化空間已經不大了。那麼這樣是否是說咱們整個Kafka就沒有任何的優化空間了?其實對於系統的優化則不只僅是包含了吞吐量的提高,咱們還能夠從相同吞吐量下資源使用率方面進行相關的優化,因此ckafka對社區Kafka的優化並未止步於當前,因此咱們進一步進行了下一個GC方面的優化。咱們指望經過該優化不只能有吞吐方面的提高,更重要的是指望在相似的場景下,能夠更好的減小資源的使用率,進一步縮減成本。

GC優化

在GC優化方面,主要是社區Kafka在對生產消息進行校驗時會針對每條消息生成一個消息對象,致使產生大量的消息對象,ckafka經過優化,採用直接在ByteBuffer二進制數據上進行消息校驗,這樣在整個消息校驗中就不會生成任何消息對象,減小大量的消息對象的生成,則會下降對jvm GC的壓力,進而提升系統的性能。經過對比優化先後的性能數據,咱們能夠看到它起到必定效果的。咱們能夠看到優化後整個GC的耗時佔比的已經低於2.5%,能夠說GC已經不會成爲系統的瓶頸點了。咱們看一下社區開源Kakfa這邊的GC耗時,在較多的partition較小的消息下,直接能夠達到10%的消耗。經過咱們的GC優化後,能夠看到整個GC耗時方面的話,有1.5%到7%的性能的提升。一樣咱們能夠看到,在吞吐量差很少的狀況下,咱們整個系CPU消耗較交社區版的CPU有關5%到10%的下降,因此能夠確定的說GC優化有效的下降了系統CPU資源的消耗,起到必定的效果。最後咱們發現整個GC優化先後系統中I/O基本上已經達到頂點,已經成爲系統的瓶頸點,因此GC優化就和前面預測的一致並未有吞吐量大幅的提高,主要集中在下降系統資源的消耗,對於前端客戶端來講則是必定幅度上下降系統的延遲。

至此因爲時間緣由,Kafka的性能優化的介紹已經完畢。但爲了更加方便你們直觀的理解,這一頁PPT則貼出了最終的優化對比效果。咱們來看看最終優化後的效果,能夠看出咱們最終完整版優化,在小包狀況下有4到5倍的性能提高,即便在1K的大包狀況下,也有一倍左右的性能提高(固然隨着partition的增長及消息大小的增長,優化效果呈必定的降低趨勢)。同時咱們能夠發現整個系統的I/O已是成爲系統的瓶頸點。也爲咱們後面系統硬件選擇方面提供一個參考,可能咱們後面會經過掛載更多的磁盤,進一步提升系統的吞吐壓榨系統的性能,進一步平衡CPU及磁盤的配比消耗,固然經過選擇更合適的硬件作到CPU、磁盤、網絡之間合適的配比實現資源利用的更大化。

下面我講一下咱們在CKafka運營中所發現一些問題,以及咱們針對這些問題的優化點,同時咱們指望社區Kafka可以採納咱們ckafka在運營中發現並優化的一些關鍵點建議,讓kafka可以更好的適應生產條件。

其一,當前社區Kafka還沒法採用pipe方式進行消費,這樣就致使出現如下幾個問題:1、消費者的性能很是依賴於與Broker端的網絡延遲,當消費者與Broker存在跨城區的時候,因爲網絡延遲的增大,會致使整個消費性能很是低下,這樣就最終限制了Kafka的使用場景,使其不能很好的做用於跨城區數據同步,限制了其使用的場景。二,Kafka在副本複製的時複用了消費邏輯,一樣走的也是消費者邏輯,這樣也一樣致使其沒法使用pipe方式,最後致使了副本同步性能低下並且很是依賴於延遲,最終致使了整個Kafka集羣不太可能進行一些跨區域的部署,限制了Kafka部署的靈活性,並且同時在壓力較大的狀況下,容易出現副本拉取的速度跟不上生產的速度致使ISR抖動影響系統性能。針對這個問題,其實在第二點,咱們這邊已經作了優化,使得副本拉取已經能夠進行pipe方式,後面即便須要作一些跨城區部署,其整個副本同步性能是可以達到要求的。可是在這裏第一個問題咱們這裏沒法解決,由於咱們這邊生爲了兼容性社區版本Kafka,是讓客戶直接採用的是開源的SDK,致使了咱們這裏還無法沒辦法優化。在這裏我但願社區Kafka,能夠採納相關的建議,實現消費者pipe方式,使得整個消費性能不在依賴於網絡延遲,使得用戶的使用上沒有地域空間的一些限制。

其二,就是當前社區Kafka對消費爲了性能方面的考慮,他在設計中是不支持低版本的消費者直接去消費高版本生產增產的消息,而當前Kafka發展到如今已經有三個消息版本,這樣就致使了業務的在使用Kafka時,包括生產者及消費者的升級降級都是很是不友好的。固然這裏咱們在進行雲化的時候,咱們已經實現了對消息格式轉換,已經實現了不一樣版本消息混合存儲在同一個文件中,已經實現了任意版本的生產以及任意版本的消費。這裏咱們但願社區Kafka可否試試放開相關的支持,由於畢竟在生產系統中,業務使用時兼容性是最重要的考量標準之一。並且即便是咱們如今的實現存在消息高低版本的轉碼,其實CPU如今仍是有富餘的,也不是系統的瓶頸點,因此說我但願社區這邊可以採納

講到這裏,其實個人分享也基本上完了。而後這是個人我的微信,你們若是有什麼問題能夠加個人微信。固然,如今咱們的CKafka團隊也在大量的招人,你們有意向的話也能夠聯繫咱們。

Q/A

Q:這裏須要請教你一個問題,就是我看剛纔看到一部刷盤優化的時候,發現CPU也是隨着性能的提高上升了不少倍,這裏是否是主要是由於優化過程當中你又作了一次拷貝?

A:沒有,其實社區Kafka在內存拷貝方面仍是有一些優化的。唉,稍等一下,社區Kafka在整個消息流轉中,好比生產消息時,他從網絡層開始會生成一個ByteBuffer用於存儲消息包,然後這個ByteBuffer會在整個系統中不斷的扭轉,它是不會有新的拷貝的,除非有一些消息須要有不一樣方式的存儲時,須要有轉碼的要求,他纔會生成一個新的消息進行一次內存拷貝不然不會有屢次內存拷貝。而咱們這裏在作異步刷盤優化時,實際上是不會有任何多於的內存拷貝的,咱們的CPU使用有數倍的提升,主要仍是在與吞吐的提升,能夠看到咱們系統在小包狀況下有4 ~ 5倍的性能提高,這樣提高,會致使更多的網絡操做,更多的打包解包,更多的系統I/O固然最終就會致使更多的cpu,固然就會須要更多的CPU消耗。這麼多消耗的疊加固然照成CPU使用率數倍的提升也是很正常的。

Q:我有個問題想問一下你剛纔以前PPT也有說就是說在系統量很大的狀況下,副本的拉取速率沒法跟上生產的速率,對這個的話咱們測試或者是說線上其實也會碰到副本拉取跟不上生產速度,並且會影響致使其它節點也跟不上,照成一種雪崩效應。而後我想問一下你這邊的解決辦法,你剛纔說有解決辦法,我想問一下大家這邊是採用哪一種解決辦法?

A: 社區Kafka副本拉取不上最主要的緣由,是由於採用了消費方式,但消費方式又不支持pipe方式消費。其實Kafka的副本拉取是同步方式,發送一個副本拉取請求後等到應答後再次發送一次同步拉取請求,沒法使用pipe流水線方式,這樣的同步方式Broker的網絡延遲會成爲整個副本同步的關鍵點,而且在壓力大的狀況下整個Kakfa的broker端出來延遲會達到秒及,這樣會致使整個副本拉取性能不足,不足的真正緣由就是拉取請求次數不夠,若是咱們採用pipe方式增大拉取請求次數,天然也就增大了副本同步的性能。

Q:大家還有沒有就是說更具體一點的解決方式?

主要是咱們這邊的話,副本的同步採用了一個新的協議,使的副本拉取請求能夠採用pipe方式增大請求次數進而提升副本同步速度。其實,社區Kafka副本拉取跟不上的真正緣由是應爲請求都是同步的,延遲正大致使請求量減小,請求量的減小最終致使副本性能降低致使沒法跟上,因此咱們所要作的就是加大副本同步請求個數,就能夠從根本上解決問題,咱們這裏採用的就是pipe方式,用於增大請求次數解決副本沒法跟上的問題。這實際上是最核心的,也是最簡單一個解決方案了。

Q: 請問一下就是說我剛纔看到有一個異步落盤的優化,問一下就是說你這裏公佈的數據都是沒有時延信息的,我不知道就是說這個有話會不會致使業務時延增長。

A: 由於測試中客戶端比較多,統計上加上時延就會致使更加的雜亂,故這裏統計數據並未有展現出來,其實咱們測試統計中採用異步刷盤後這個時延效果其實更好。由於採用異步刷盤後在整個請求中不會堵塞任何核心流程,只用把刷盤任務推送到隊列,就能夠直接返回給前端客戶端了。可是若是你不使用異步刷盤直接在覈心流程中進行刷盤的話,會堵塞核心流程的,並且每次刷盤耗時實際上是很是大的,常常會到達400毫秒左右的延遲,因此延遲會更大。採用異步刷盤後,通過咱們測試,即便在七八百MB的最高吞吐下,咱們這邊整個延遲是保持得很是好,整個測試的平均延遲是在15毫秒到30毫秒之間。然而在社區Kafka環境下,其延遲實際上是在200毫秒左右。

Q: 我就問,若是異步落盤的時候,它到期還沒刷到盤,這個不須要等到刷盤完成後才返回給客戶嗎?會不會致使未刷盤時消息丟失?

A: 這個其實和Kafka的應用場景有關了,當前社區Kafka也不是每條消息都刷盤,其實刷盤也是經過配置一個消息間隔數或間隔時間進行的,這樣其實社區Kafka這邊在系統掉電的狀況下,是還真的無法保證這個消息不丟失。Kafka應用場景通常也不是在用在徹底不須要消息丟失的場景,而是主要用於一些日誌採集等實時性要求比較高,吞吐要求比較高的場景,Kafka這裏爲了吞吐這邊其實仍是選擇了犧牲必定的消息的可靠性的。固然針對咱們這個異步刷盤,當前的第一步優化比較簡單,咱們直接把任務推送到刷盤人羣隊列,就返回給客戶端成功,的確會致使一部分消息在系統掉電下致使丟失。當前爲了切合Kafka的應用場景,採用了優先吞吐的方式,固然,咱們後面還會根據須要看看,是否須要實現真正刷盤後在返回給用戶成功。其實實現這個也比較簡單,咱們選擇掛起生產請求,直到刷盤線程真正刷盤後,在返回給客戶成功便可。但這樣的話你剛纔也說了可能會致使的延遲增大,由於你必需要等它真正的刷盤完成,這個可能須要你本身根據應用形態採用而不一樣的方式,實現一個高吞吐及高可靠的一個取捨了。

Q:你好,問個問題就是兩個問題,第一個問題是關於數落盤的,由於剛纔也提到說Kafka裏面的數據不必定是可靠的,而後想問一下騰訊在這邊對數據可靠性是有作了什麼優化和方案這樣。

A:一方面,從硬件方面,其實咱們這裏全部的存儲磁盤,都採用了RAID10的方式,這樣即便有少許的磁盤的損壞,對咱們來講的話是不會有數據丟失的風險的。另外一方面,ckafka和社區kafka同樣均可以經過多副本的方式,加上必定合理的配置,能夠保證在機器損壞時,數據不丟失。再次,在實現上咱們ckafka也作到了定時定量進行主動刷盤能夠下降機器因爲意外掉電致使的數據丟失。因此相對應社區kafka ckafka從硬件及軟件上都有更高的數據可靠性保證。

Q:而後第二個問題,剛纔說到說跨城區的副本同步就有個問題,如今騰訊這邊的部署是跨城區部署的嗎?

A:當前ckafka的部署採用的是同城區,同zone部署的,可是咱們ckafka是能夠實現跨城區部署的,當前沒提供這種部署方式,最主要的緣由是當前使用社區Kafka sdk的消費者性能強依賴於與Broker之間網絡延遲。若是咱們進行跨地域部署的話,那麼客戶端的消費性能是得不到保障的,由於不通地域之間的網絡延遲每每都在幾十毫秒,甚至上百毫秒,這樣使得整個消費性能降低很是嚴重沒法知足業務的需求。固然若是社區Kafka SDK可以採用咱們上面的建議實現消費者pipe方式消費,那麼進行跨地域部署將不會有任何問題。

Q:OK帶來另一個問題,就是我覺的若是真的出現意外狀況,好比像天津大爆炸案,致使整個騰訊的天津機房都炸掉了,大家這裏的話有沒有考慮過這種遷移計劃?

A:其實咱們ckafka是在各個地域都部署的有相關的集羣,用戶能夠經過在不一樣地域購買不一樣的實例,一方面實現就近接入,另外一方面實現異地容災,保證程序的可用性。固然用戶也能夠經過,咱們提供的Kafka的一些同步工具,進行數據在不一樣地域間同步,用於實現地域級別的容災。

Q:對於業務來講,若是他使用同步工具那麼會不會對業務照成更大的成本?業務是否須要改造相關的程序用以實現跨城區訪問?

A:對業務使用方來講,能夠直接使用一些開源的工具及方法,用戶是不須要有任何的更改就能實現跨地域訪問,社區Kafka的生態及工具仍是比較完善的你們能夠多去社區上逛逛總能找到適合本身的工具。

問答
Kafka的基於關鍵/值對的消息傳遞的目的是什麼?
相關閱讀
饒軍:Apache Kafka的過去,如今,和將來
楊原:騰訊雲Kafka自動化運營實踐
陳新宇:CKafka在人臉識別PASS中的應用


更多相關資料,請戳:

kafka-高性能揭祕及優化.pdf


此文已由做者受權騰訊雲+社區發佈,原文連接:https://cloud.tencent.com/developer/article/1114834?fromSource=waitui

相關文章
相關標籤/搜索