1. 程式人生 > >大資料(二十九):kafka簡介、架構、原理

大資料(二十九):kafka簡介、架構、原理

一、kafka是什麼

在流式計算中,kafka一般用來快取資料,storm通過消費kafka的資料進行計算。

1.Apache kafka是一個開源的訊息系統,由scala寫成,是由Apache軟體基金會開發的一個開源訊息系統專案。

2.kafka最初始由Linkedin公司開發,並於2011年初開源。2012年10月從Apache incubator畢業。該專案的目標是為處理實時資料提供一個統一、高通量、低等待的平臺。

3.kafka是一個分散式訊息佇列。kafa對訊息儲存時根據Topic進行歸類,傳送訊息者為Producer,訊息接收者為Consumer,此外kafka叢集有多個kafka例項組成,每個例項(server)稱為broker。

4.無論是kafa叢集,還是producer和Consumer都依賴於zookeeper叢集儲存一些meta資訊,來保證系統可用性。

二、訊息佇列內部實現原理

1.點對點模式(一對一,消費者主動拉取資料,訊息收到後訊息清除)

        點對點模型通常是一個基於拉取或者輪詢的訊息傳送模型,這種模型從佇列中請求資訊,而不是將訊息推送到客戶端。這個模型的特點是傳送到佇列的訊息被一個且只有一個接收者接收處理,即使有多個訊息監聽者也是如此。

2.釋出/訂閱模式(一對多,資料生產後,推送給所有訂閱者)

        釋出訂閱模型則是一個基於推送的訊息傳送模型。釋出訂閱模型可以有多種不同的訂閱者,臨時訂閱者只在主動監聽主題時才接收訊息,而持久訂閱者則監聽主題的所有訊息,即使當前訂閱者不可用,處於離線狀態。

三、為什麼需要訊息佇列

1.解耦

        允許獨立的擴充套件或修改兩邊的處理過程,只要確保它們遵守統一的介面約束。

2.冗餘

        訊息佇列把資料進行持久化直到他們已經完全處理,通過這一方式規避了資料丟失防線。許多訊息佇列採用的“插入-獲取-刪除”正規化中,在把一個訊息從訊息佇列中刪除之前,需要處理系統明確的指出該訊息已經被處理完畢,從而確保資料被安全的儲存直到使用完畢。

3.擴充套件性

        因為訊息佇列解耦了處理過程,所以增大訊息入隊和處理頻率是很容易的事情,只要另外增加處理過程即可。

4.靈活性和峰值處理能力

        在訪問量劇增的情況下,應用仍然需要繼續發揮作用,但只有的突發流量並不常見。如果為了處理這類峰值訪問的標準來投入資源隨時待命無疑是巨大的浪費。使用訊息佇列能夠使關節元件頂住突發訪問的壓力,而不會因為突發的超負荷的請求而全面崩潰。

5.可恢復性

        體統的一部分元件失效時,不會影響到整個系統。訊息佇列降低了程序間的耦合度,所以即使一個處理訊息的程序掛掉,加入佇列中的訊息仍然可以在系統恢復後被處理。

6.順序保證

        在大多數的場景下,資料處理的順序都很重要。大部分訊息佇列本生就是排序的,並且保證資料會按照特定的順序來處理。(kafka保證一個partition內部的訊息的有序性)。

7.緩衝

        有助於控制和優化資料流經過系統的速度,解決生產訊息和消費訊息的處理速度不一致的情況。

8.非同步通訊

        有些時候,使用者並不想立即處理訊息。訊息佇列提供了非同步處理機制,允許使用者把一個訊息放入佇列,但並不立即處理它。想向佇列中放入多少訊息就放多少,然後在需要的時候再去處理它們。

四、kafka架構

1.Producer:訊息生產者,向kafka broker發訊息的客戶端。

2.Consumer:訊息消費者,想kafka broker獲取訊息的客戶端。

3.Topic:可以理解為佇列

4.Consumer Group(CG):這是kafka用來實現一個topic訊息的廣播(發給所有的Consumer)和單播(發給任意一個Consumer)的手段。一個topic可以有多個CG。topic的訊息會複製給Consumer。如果需要實現廣播,只要每個Consumer有一個獨立的CG就可以了。要實現單播只要所有的Consumer在同一個CG中。用CG還可以將Consumer進行自由的分組而不需要多次傳送訊息到不同的topic。

5.Broker:一臺kafka伺服器就是一個broker。一個叢集由多個broker組成。一個broker可以容納多個topic。

6.Partition:為了實現擴充套件性,一個非常大的topic可以分佈到多個Broker(即伺服器)上,一個topic可以分為多個Partition,每個partition是一個有序佇列。Partition中的每條訊息都會被分配一個有序的id(offset)。kafka只保證按一個partition中順序將訊息發給Consumer,不保證一個topic的整體(多個partition)的順序。

7.Offset:kafka的村塾檔案都是按照offset.kafka來命名,用offset做名字的好處就是方便查詢。比如想找到2049的位置,只要找到2048.kafka的檔案即可。the first offset是 00000000000.kafka

五、分散式模型

        Kafka每個主題(Topic)的多個分割槽日誌分散式儲存在Kafka叢集上,同時為了故障容錯,每個分割槽都會以副本的方式複製到多個訊息代理節點上。其中一個節點會作為主副本(leader),其他節點作為備份副本(Follower,備份副本)。主副本會負責所有客戶端讀寫操作,備份副本僅僅從主副本同步資料。當主副本出現故障時,備份副本中的一個副本會被選擇為新的主副本。因為每個分割槽的副本只有一個主副本接收讀寫,所以每個伺服器都會作為某些分割槽的主副本,以及另外一些分割槽的備份副本,這樣kafka叢集的所有服務端整體上對客戶端是負載均衡的。

        kafka的生產者和消費者相對於伺服器端而言都是客戶端。

        kafka生產者客戶端釋出訊息到服務端的指定主題,會指定訊息所屬的分割槽。生產者釋出訊息時根據訊息是否有鍵,來採取不同的分割槽策略。訊息沒有鍵時,通過輪詢方式進行客戶端負載均衡;訊息有鍵時,根據分割槽語義保證相同鍵的訊息總是傳送到同一個分割槽。

        Kafka的消費者通過訂閱主題來消費訊息,並且每個消費者都會設定一個消費組名稱。因為生產者釋出到主題的每一條訊息都只會傳送給消費者組的一個消費者。所以,如果要實現傳統訊息系統的“佇列”模型,可以讓每個消費者都擁有相同的消費組名稱,這樣訊息就會負責均衡到所有的消費者;如果要實現“釋出-訂閱”模型,則每個消費者的消費者組名稱都不相同,這樣每條訊息就會廣播給所有的消費者。

        分割槽是消費者現場模型的最小並行單位。如下圖(圖1)所示,生產者釋出訊息到一臺伺服器的3個分割槽時,只有一個消費者消費所有的3個分割槽。在下圖(圖2)中,3個分割槽分佈在3臺伺服器上,同時有3個消費者分別消費不同的分割槽。假設每個伺服器的吞吐量時300MB,在下圖(圖1)中分攤到每個分割槽只有100MB,而在下圖(圖2)中,叢集整體的吞吐量有900MB。可以看到,增加伺服器節點會提升叢集的效能,增加消費者數量會提升處理效能。

        同一個消費組下多個消費者互相協調消費工作,Kafka會將所有的分割槽平均地分配給所有的消費者例項,這樣每個消費者都可以分配到數量均等的分割槽。Kafka的消費組管理協議會動態地維護消費組的成員列表,當一個新消費者加入消費者組,或者有消費者離開消費組,都會觸發再平衡操作。

        Kafka的消費者消費訊息時,只保證在一個分割槽內的訊息的完全有序性,並不保證同一個主題匯中多個分割槽的訊息順序。而且,消費者讀取一個分割槽訊息的順序和生產者寫入到這個分割槽的順序是一致的。比如,生產者寫入“hello”和“Kafka”兩條訊息到分割槽P1,則消費者讀取到的順序也一定是“hello”和“Kafka”。如果業務上需要保證所有訊息完全一致,只能通過設定一個分割槽完成,但這種做法的缺點是最多隻能有一個消費者進行消費。一般來說,只需要保證每個分割槽的有序性,再對訊息假設鍵來保證相同鍵的所有訊息落入同一分割槽,就可以滿足絕大多數的應用。