Kafka是什么
在流式計算中,Kafka一般用來緩存數據,Storm通過消費Kafka的數據進行計算。
1)Apache Kafka是一個開源消息系統,由Scala寫成。是由Apache軟件基金會開發的一個開源消息系統項目。
2)Kafka最初是由LinkedIn公司開發,並於 2011年初開源。2012年10月從Apache Incubator畢業。該項目的目標是為處理實時數據提供一個統一、高通量、低等待的平台。
3)Kafka是一個分布式消息隊列。Kafka對消息保存時根據Topic進行歸類,發送消息者稱為Producer,消息接受者稱為Consumer,此外kafka集群有多個kafka實例組成,每個實例(server)成為broker。
4)無論是kafka集群,還是producer和consumer都依賴於zookeeper集群保存一些meta信息,來保證系統可用性。
Kafk內部實現原理
(1)點對點模式(一對一,消費者主動拉取數據,消息收到后消息清除)
點對點模型通常是一個基於拉取或者輪詢的消息傳送模型,這種模型從隊列中請求信息,而不是將消息推送到客戶端。這個模型的特點是發送到隊列的消息被一個且只有一個接收者接收處理,即使有多個消息監聽者也是如此。
(2)發布/訂閱模式(一對多,數據生產后,推送給所有訂閱者)
發布訂閱模型則是一個基於推送的消息傳送模型。發布訂閱模型可以有多種不同的訂閱者,臨時訂閱者只在主動監聽主題時才接收消息,而持久訂閱者則監聽主題的所有消息,即使當前訂閱者不可用,處於離線狀態。
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分布式模型
Kafka每個主題的多個分區日志分布式地存儲在Kafka集群上,同時為了故障容錯,每個分區都會以副本的方式復制到多個消息代理節點上。其中一個節點會作為主副本(Leader),其他節點作為備份副本(Follower,也叫作從副本)。主副本會負責所有的客戶端讀寫操作,備份副本僅僅從主副本同步數據。當主副本出現故障時,備份副本中的一個副本會被選擇為新的主副本。因為每個分區的副本中只有主副本接受讀寫,所以每個服務器端都會作為某些分區的主副本,以及另外一些分區的備份副本,這樣Kafka集群的所有服務端整體上對客戶端是負載均衡的。
Kafka的生產者和消費者相對於服務器端而言都是客戶端。
Kafka生產者客戶端發布消息到服務端的指定主題,會指定消息所屬的分區。生產者發布消息時根據消息是否有鍵,采用不同的分區策略。消息沒有鍵時,通過輪詢方式進行客戶端負載均衡;消息有鍵時,根據分區語義(例如hash)確保相同鍵的消息總是發送到同一分區。
Kafka的消費者通過訂閱主題來消費消息,並且每個消費者都會設置一個消費組名稱。因為生產者發布到主題的每一條消息都只會發送給消費者組的一個消費者。所以,如果要實現傳統消息系統的“隊列”模型,可以讓每個消費者都擁有相同的消費組名稱,這樣消息就會負責均衡到所有的消費者;如果要實現“發布-訂閱”模型,則每個消費者的消費者組名稱都不相同,這樣每條消息就會廣播給所有的消費者。
分區是消費者現場模型的最小並行單位。如下圖(圖1)所示,生產者發布消息到一台服務器的3個分區時,只有一個消費者消費所有的3個分區。在下圖(圖2)中,3個分區分布在3台服務器上,同時有3個消費者分別消費不同的分區。假設每個服務器的吞吐量時300MB,在下圖(圖1)中分攤到每個分區只有100MB,而在下圖(圖2)中,集群整體的吞吐量有900MB。可以看到,增加服務器節點會提升集群的性能,增加消費者數量會提升處理性能。
同一個消費組下多個消費者互相協調消費工作,Kafka會將所有的分區平均地分配給所有的消費者實例,這樣每個消費者都可以分配到數量均等的分區。Kafka的消費組管理協議會動態地維護消費組的成員列表,當一個新消費者加入消費者組,或者有消費者離開消費組,都會觸發再平衡操作。
Kafka的消費者消費消息時,只保證在一個分區內的消息的完全有序性,並不保證同一個主題匯中多個分區的消息順序。而且,消費者讀取一個分區消息的順序和生產者寫入到這個分區的順序是一致的。比如,生產者寫入“hello”和“Kafka”兩條消息到分區P1,則消費者讀取到的順序也一定是“hello”和“Kafka”。如果業務上需要保證所有消息完全一致,只能通過設置一個分區完成,但這種做法的缺點是最多只能有一個消費者進行消費。一般來說,只需要保證每個分區的有序性,再對消息假設鍵來保證相同鍵的所有消息落入同一分區,就可以滿足絕大多數的應用。