?

Kafka分布式消息隊列的高性能研究

2019-01-06 02:19劉邦余華平
電腦知識與技術 2019年32期
關鍵詞:高性能

劉邦 余華平

摘要:消息代理的使用有多種原因(將處理與數據生成器分離,緩沖未處理的消息等)。Kafka作為一個分布式消息隊列,可以替代更傳統的消息代理,與大多數消息傳遞系統相比,具有更好的吞吐量,內置分區,高性能,復制和容錯功能,這使其成為大規模消息處理應用程序的理想解決方案。Kafka對外使用topic的概念,生產者往topic里寫消息,消費者從各個top-ic中讀取消息。每個topic是由多個partition組成,雖然partition中的消息是有序的,但是多個partition是無序的,需要保證消息的有序讀寫,并且提高Kafka的性能。

關鍵詞:Kafka;topic;partition;高性能;分布式消息隊列

中圖分類號:TP391 文獻標識碼:A

文章編號:1009-3044(2019132-0004-03

1概述

大數據階段為了分析用戶的行為,我們將各類日志信息收集并保存到hadoop上做離線的處理,與此同時,我們將日志信息置于檢索系統中,方便高效定位問題所在。核心上,該問題是集成數據的問題,但是一個系統并不能解決所有的問題,邏輯上我們用不同的系統處理不同的業務數據,例如歸類、查找、分析、緩存等。系統中產生的數據冗余沒有問題,但是將不同系統中的數據進行同步時,就會產生一系列問題。Kafka處理數據冗余的做法是提供一個分布式消息隊列,讓數據生產者向隊列的末尾添加數據,然后消費者依次從隊列里面讀取數據,這樣保證數據以合適的形式出現在合適的地方。

2Kafka架構組件及數據流程

2.1Kafka架構組件

每條發布到Kafka集群的消息都有一個類別,這個類別被稱為Topic。我們在具體操作中為每類的數據信息創建一個topic,生產者(producer)即數據的發布者,該角色將消息發布到Kafka的topic中,消費者(consumer)可以從broker中讀取數據,消費者可以消費多個topic中的數據。Producers和consumers進行操作時,可同時在多個topic中讀寫數據。Kafka集群包含一個或多個服務器,服務器節點稱為broker,它的職責是負責持久化和備份具體的kafka消息。

topic:消息存放的目錄即主題

Producer:生產消息到topic的一方

Consumer:訂閱topic消費消息的一方

Broker:Kafka的服務實例就是一個broker

2.1.1Kafka中的topic和partition

在Kafka中,Topic是一個存儲消息的邏輯概念,可以認為是一個消息集合。每條發送到Kafka集群的消息都有一個類別。我們在操作中產生的不同類型的數據,都能將其分類為不同的topic。一把情況下,一個topic會有多個消息的訂閱者,當producer發布消息到某個topic時,訂閱了該topic的consumer都可以接收到producer寫入的新消息。Kafka為每個topic維護了分布式的分區(Partition)日志文件,所有的partition在Kafka存儲的層面都是Append Log。所有發布到該parti-tion的消息都將會置于Log日志文件的尾部,在partition中按照時間順序,每條消息均會分配一個單調遞增的順序編號,這也是我們的位移offset。系統中Offset默認是一個Long型的數字。我們可以通過該offset確定一條在該分區下的唯一消息。在分區中保證了消息的有序性,但是在topic中,信息的有序性沒有得到保證。

2.2 Kafka數據流程

使用Kafka作為消息中間件,我們需要涉及包括Kafka集群,分布式協調中心(Zookeeperl,生產者,消費者在內的四個部分對象,它們協同工作,讓消息高吞吐高可靠的存儲和流通。生產者往topic中寫數據,消費者從中讀數據,每當新增一條消息時,kafka就會在對應的文件append寫,用這種方式處理消息,確保kafka的性能非常高。

2.3Kafka消費模型

消息由生產者發送到Kafka集群后,會被消費者消費。一般來說我們的消費模型有兩種:一種是推送模型(Push);另一種是拉取模型(pull)。

在推送模型(Push)的消息系統中,是由消息代理記錄消息的消費狀態。消息代理將消息推送到consumer后,然后標記該消息為已經被消費狀態,但是這種方式有個缺點,它無法很好地保證消息消費的處理語義。例如,當我們已經把消息發送給consumer之后,由于網絡原因或者消費進程宕機等原因,消費者沒有收到該消息,如果此時我們在消費代理中將該消息標記為已消費,那將會出現該消息永久丟失的情況。如果我們采用producer收到消息后回復這種方法,消息代理需要自己記錄消息的消費狀態,這種方法不合適。如果我們采用推送模型,消費代理將會完全控制消息消費的速率,如果consumer發生突發情況,形成阻塞,就會出現一系列問題?;谶@種情況,Kafka采取拉取模型(Poll),由自己控制消費速度及進度,consumer可以按照任意的offset進行消費。例如,消費者可以對已經消費過的消息進行重新處理,或者是消費近期的消息等。

3 Kafka高性能的實現

3.1分區

kafka是個分布式集群的系統,整個系統可以包含多個bro-ker,也就是多個服務器實例。每個主題topic會有多個分區,kafka將分區均勻地分配到整個集群中,當生產者向對應主題傳遞消息,消息通過負載均衡機制傳遞到不同的分區以減輕單個服務器實例的壓力。一個Consumer Group中可以有多個consumer,多個consumer可以同時消費不同分區的消息,大大地提高了消費者的并行消費能力。但是一個分區中的消息只能被一個Consumer Group中的一個consumer消費。如圖3所示。

3.2網絡傳輸上減少開銷

3.2.1批量發送

在發送消息的時候,kafka不會直接將少量數據發送出去,否則每次發送少量的數據會增加網絡傳輸頻率,降低網絡傳輸效率。kafka會先將消息緩存在內存中,當超過一個的大小或者超過一定的時間,那么會將這些消息進行批量發送。

3.2.2端到端壓縮

網絡傳輸時數據量小時也可以減小網絡負載,kafaka會將這些批量的數據進行壓縮,將一批消息打包后進行壓縮,發送broker服務器后,最終這些數據還是提供給消費者用,所以數據在服務器上還是保持壓縮狀態,不會進行解壓,而且頻繁的壓縮和解壓也會降低性能,最終還是以壓縮的方式傳遞到消費者的手上。

3.3順序讀寫

kafka是個可持久化的日志服務,它將數據以數據日志的形式進行追加,最后持久化在磁盤中。katka消息存儲時依賴于文件系統,我們普遍認為磁盤的性能比不上內存性能,但是kafka卻將磁盤性能發揮得淋漓盡致。在一個由6個7200rpm的SATA硬盤組成的RAID-5磁盤陣列上,線性寫入(linearwrite)的速度大約是300MB/秒,但隨即寫入卻只有50k/秒??梢姶疟P的線性和隨機讀寫的速度差距甚大。為了利用數據的局部相關性,操作系統從磁盤中讀取數據以數據塊為單位,將一個數據塊讀入內存中,如果有相鄰的數據,就不用再去磁盤中讀取。在某些情況下,順序磁盤訪問能比隨機內存訪問還要快。同時在寫數據的時候也是將一整塊數據塊寫人磁盤中,大大提升了10效率。

現代操作系統樂于將更多的空閑內存來當作磁盤緩存。當我們在程序中對數據進行緩存時,可能這些數據已經緩存在了操作系統的緩存頁中。我們將緩存的操作邏輯交給操作系統,那么比我們自己維護來得更加高效。所以使用磁盤的方式進行線性地讀取數據也有很高的效率。

kafka將消息追加到日志文件中,正是利用了磁盤的順序讀寫,來提高讀寫效率。我們平時操作磁盤可能會用Btree這種數據結構,但是運算的時間復雜度為0(10gN),持久化隊列利用追加日志的方式構建,生產者將消息追加到日志尾部,消費者讀取頭部的消息,兩者互不干擾,也不需要加鎖,提高了性能,同時時間復雜度為O(1)。

3.4零拷貝

kafka將數據以日志的形式保存在磁盤中。當消費者向服務器請求數據,那么需要從文件傳輸到socket中。那么從文件到sueker需要以下這些步驟:

①調用read陷入內核模式,操作系統將數據從磁盤讀到內核緩沖區;

②然后從內核態切換到用戶態,應用程序將數據從內核空間讀取到用戶空間的緩沖區;

③然后應用程序將數據寫帶內核空間的socket緩沖區;

④最后操作系統將socket緩沖區的數據拷貝到網卡接口緩沖區并發出去。

從上面可見,當我們將數據從文件傳輸到socket最后發送出去經過了好幾次拷貝,同時還有好幾次的用戶態和內核態的切換,我們知道用戶態和內核態的切換也是很耗時的,那么多次拷貝對性能的影響更是雪上加霜。

從上面的過程來看,可以看出沒必要從內核空間的緩沖區拷貝到用戶空間。所以零拷貝技術正是改進了這項缺點,零拷貝將文件內容從磁盤通過DMA引擎復制到內核緩沖區,而且沒有把數據復制到socket緩沖區,只是將數據位置和長度信息的描述符復制到了socket緩存區,然后直接將數據傳輸到網絡接口,最后發送。這樣大大減小了拷貝的次數,提高了效率,kafka正是調用linux系統給出的sendfile系統調用來使用零拷貝。

3.5優秀的文件存儲機制

之前說過一個主題可以有多個分區,假設只有一個服務器broker,那么多個分區必然是存在一個服務器上。kafka將一個分區以一個目錄的方式存儲,目錄的命名為topicname-分區下標,例如有個topic叫作hello,有3個分區,那么就有三個文件夾分別為hello-0,hello-1,hello-2。在一個分區文件夾中,又分為多個段文件。段文件又由一個index索引文件和一個log實質的數據日志文件構成。文件的命名規則為日志文件中第一個消息的offset值一1,offset可以理解為消息id,例如一個000…0015354.10g這個文件中消息最小的offset為15353。

log數據文件由消息和偏移量構成,而索引文件中的索引用的是稀疏索引。稀疏索引減少的索引文件的大小,索引文件中存著消息的物理偏移量。

4總結

Kafka中生產者及消費者是直接與broker進行交互實現生產消費功能,Kalka在設計上并未采用傳統系統中通過增加一層代理實現系統的平行擴展能力。Kafka在設計中通過內部路由協議,實現了生產者與消費者可以直接與broker進行路由協商,從而實現了客戶端直接與broker進行生產消費,而不需要借助第三方代理。無代理的方式不僅會減少整個數據鏈路的長度,降低延遲,也可以提高整個系統的穩定性,而且也會節省大量的成本。

在優化其性能方面,采用分區、網絡傳輸減少開銷、順序讀寫、零拷貝、優秀的文件存儲機制等方式,提高Kafka性能,另外我們也可以通過進一步了解Kafka的架構,找出它可能的瓶頸點,然后在針對瓶頸點進行優化優化,根據實際的需求,我們可以做出對應的優化,提高其性能。

猜你喜歡
高性能
高性能3000N針栓式推力室設計
高性能海工結構鋼API2W的研發
高性能纖維的可織性研究進展
一種高性能CMOS溫度傳感器
基于高性能再生劑的大比例RAP廠拌熱再生技術
高性能輕型國V柴油機的開發
一款高性能BGO探測器的研發
高性能砼在橋梁中的應用
精美絕倫,那些超高性能的飛馳藝術品
SATA推出全新高性能噴槍SATAjet 5000 B
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合