1 Kafka
1.1 Kafka簡介
Kafka是一種分布式的,基於發布/訂閱的消息系統。原本開發自LinkedIn,用於將用戶的行為、網站的活動(網頁游覽,搜索或其他用戶的操作信息)發布記錄到不同的話題中心,這些消息數據可實時處理,實時監測,也可加載到Hadoop或離線處理數據倉庫供后續大數據發掘。
Kafka主要設計目標如下:
1) 以時間復雜度為O(1)的方式提供消息持久化能力,即使對TB級以上數據也能保證常數時間復雜度的訪問性能。
2) 高吞吐率。即使在非常廉價的商用機器上也能做到單機支持每秒100K條以上消息的傳輸。
3) 支持Kafka Server間的消息分區,及分布式消費,同時保證每個Partition內的消息順序傳輸。
4) 支持離線數據處理和實時數據處理。
5) Scale out:支持在線水平擴展。
1.2 Kafka架構
1.2.1 Broker
Kafka集群包含一個或多個服務器,這種服務器被稱為broker。
1.2.2 Topic
每條發布到Kafka集群的消息都有一個類別,這個類別被稱為Topic。(物理上不同Topic的消息分開存儲,邏輯上一個Topic的消息雖然保存於一個或多個broker上但用戶只需指定消息的Topic即可生產或消費數據而不必關心數據存儲位置)
1.2.3 Partition
Parition是物理上的概念,每個Topic包含一個或多個Partition.
1.2.4 Producer
負責發布消息到Kafka broker。
1.2.5 Consumer
消息消費者,向Kafka broker讀取消息的客戶端。
1.2.6 Consumer Group
每個Consumer屬於一個特定的Consumer Group(可為每個Consumer指定group name,若不指定group name則屬於默認的group)。
1.3 Kafka消息隊列和消息主題實現
Kafka約定 同一Topic的一條消息只能被同一個Consumer Group內的一個Consumer消費,但多個Consumer Group可同時消費這一消息。
這是Kafka用來實現一個Topic消息的廣播(發給所有的Consumer)和單播(發給某一個Consumer)的手段。一個Topic可以對應多個Consumer Group。如果需要實現廣播(消息主題),只要每個Consumer有一個獨立的Group就可以了。要實現單播(消息隊列)只要所有的Consumer在同一個Group里。用Consumer Group還可以將Consumer進行自由的分組而不需要多次發送消息到不同的Topic。
實際上,Kafka的設計理念之一就是同時提供離線處理和實時處理。根據這一特性,可以使用Storm這種實時流處理系統對消息進行實時在線處理,同時使用Hadoop這種批處理系統進行離線處理,還可以同時將數據實時備份到另一個數據中心,只需要保證這三個操作所使用的Consumer屬於不同的Consumer Group即可。
2 常用MQ組件
2.1 ActiveMQ
ActiveMQ是Apache所提供的一個開源的消息系統,完全采用Java來實現,因此,它能很好地支持J2EE提出的JMS(Java Message Service,即Java消息服務)規范。JMS是一組Java應用程序接口,它提供消息的創建、發送、讀取等一系列服務。JMS提供了一組公共應用程序接口和響應的語法,類似於Java數據庫的統一訪問接口JDBC,它是一種與廠商無關的API,使得Java程序能夠與不同廠商的消息組件很好地進行通信。
JMS支持兩種消息發送和接收模型。一種稱為P2P(Ponit to Point)模型,即采用點對點的方式發送消息。P2P模型是基於隊列的,消息生產者發送消息到隊列,消息消費者從隊列中接收消息,隊列的存在使得消息的異步傳輸稱為可能,P2P模型在點對點的情況下進行消息傳遞時采用。
另一種稱為Pub/Sub(Publish/Subscribe,即發布-訂閱)模型,發布-訂閱模型定義了如何向一個內容節點發布和訂閱消息,這個內容節點稱為topic(主題)。主題可以認為是消息傳遞的中介,消息發布這將消息發布到某個主題,而消息訂閱者則從主題訂閱消息。主題使得消息的訂閱者與消息的發布者互相保持獨立,不需要進行接觸即可保證消息的傳遞,發布-訂閱模型在消息的一對多廣播時采用。
3 Kafka和常規MQ技術比對
Kafka通過zookeeper、raft等實現了分布式一致性,可用來構建可分布式擴展的消息系統,其具有非常高的數據吞吐量,這是其他傳統MQ所無法比擬的。當項目應用場景數據量吞吐量較大、低延遲時,可采用Kafka;反之,當數據量吞吐量較小時,可采用諸如ActiveMQ等傳統消息中間件。
4 Push vs Poll 技術比對
作為一個消息系統,Kafka遵循了傳統的方式,選擇由Producer向broker push消息並由Consumer從broker pull消息。而傳統的MQ消息中間件如AMQ等,采用了Push模式。事實上,push模式和pull模式各有優劣。
push模式很難適應消費速率不同的消費者,因為消息發送速率是由broker決定的。push模式的目標是盡可能以最快速度傳遞消息,但是這樣很容易造成Consumer來不及處理消息,典型的表現就是拒絕服務以及網絡擁塞。而pull模式則可以根據Consumer的消費能力以適當的速率消費消息。
對於Kafka而言,pull模式更合適。pull模式可簡化broker的設計,Consumer可自主控制消費消息的速率,同時Consumer可以自己控制消費方式——即可批量消費也可逐條消費,同時還能選擇不同的提交方式從而實現不同的傳輸語義。