Kafka是一個高性能,高可用,可持久化的,爲分佈式設計的消息中間件。與標準的,如ActiveMQ這樣的消息中間件不一樣,Kafka對消息的「僅僅發送一次」並不關注。
緩存
Kafka的設計初衷是提供一個統一的處理實時數據的平臺。和普通的消息中間件同樣,Kafka也分爲消息生產者,消息消費者和消息中介。安全
每一種消息的分類,叫主題(Topic)。一個消息中介能夠包含多個不一樣的主題。爲了分佈式設計,每一個主題又能夠分紅多個分區(Partition)。每一個分區都是一個順序寫入,且不可變的文件。每一個新的消息老是追加到文件尾部。每一個消息都有一個編號(Offset),消費者能夠經過這個編號選擇消費消息。以下圖:
服務器
因爲主題均可以分紅不一樣的分區,而每一個分區能夠分佈在不一樣的機器上,因此實現了分佈式功能。Kafka經過Zookeeper實現註冊中心,會將消息生產者,消費者,消息中介的元數據存儲到Zookeeper上。Kafka會自動將分區分配到不一樣的機器上。網絡
對於將哪些消息發送到哪些分區,Kafka默認使用輪詢調度的方式分配。可是也能夠根據本身的業務場景,定製化實現消息分區邏輯。
分佈式
每一個分區的消費都是按照順序的,可是跨分區的消息不保證順序性。Kafka爲消費者提供了GroupID的功能,同時只能有一個擁有一樣GroupID的消費者,消費一個分區。這個有點像ActiveMQ裏面的Exclusive Consumer功能。咱們都知道,消息中間件分爲Queue和Topic兩種模式。若是每一個消費者擁有一樣的GroupID,那麼這個主題就是被當作Queue方式消費,由於不會有消費者消費一樣的消息;若是每一個消費者擁有不一樣的GroupID,那麼這個主題就是被當作Topic方式消費,由於每一個消費者都會消費一遍這個消息。性能
消息生產者使用標準的推送(push)模型,將消息推送到消息中介。可是消息消費者不一樣,它使用拉取(pull)模型,主動的將消息從消息中介拉取到客戶端。這樣消息中介不須要維護消息的使用狀態。消息推送的優點是,消息的實時性高,一旦消息中介接收到消息,能夠立刻推送給消費者。而且方便維護消息的消費狀態。可是缺點也比較明顯,不能得知消費者的狀態,若是碰到消費者比發送者慢的狀況,很容易形成消費者的消息堆積,最終壓垮消費者。使用拉取模型,消費者能夠根據本身的狀態選擇什麼時間拉取多少消息,不會形成消費者的擁堵。而且爲了提高吞吐量,能夠一次批量拉取多條消息。spa
Kafka的消息中介不會存儲消息消費的狀態,而是把消息消費到哪裏的偏移量存到客戶端,而且同步到Zookeeper。能夠選擇批量同步,這樣作的優點是提高吞吐量,風險是若是消費者崩潰,未同步的偏移量會致使消息從新消費。這個就引出了消息傳遞的語意。系統能夠提供3種可能的消息傳遞保障方式:至多一次,至少一次和僅僅一次。至多一次是消息發送之後,不管消費者是否成功消費,消息都不會再從新發送。這個風險比較大,會丟消息。至少一次是,消息即便被消費,若是因爲網絡等緣由形成消費狀態沒有同步,那麼下次仍是會消費一樣的消息。這樣雖然不會丟失消息,可是會致使重複消費,這就須要業務程序實現冪等性,即不管消費多少次都是一樣的結果,這個對業務端的程序要求比較苛刻。最理想的方式固然是僅僅一次。這樣若是消費消息以後,再存儲消息已經被消費的狀態時出現異常,那麼被消費的數據會回滾,就當作消息沒有消費。這是消息系統最完美的保障,可是是以犧牲性能爲前提,因此使用僅僅一次的消費模型時須要確認,是否是真的有必要。ActiveMQ等JMS實現的消息中間件支持僅僅一次的消費模型,Kafka因爲設計理念不一樣,只支持至少一次,犧牲一致性換取性能。操作系統
說到性能,最後一點須要關注的就是Kafka的存儲方式。Kafka直接使用磁盤進行存儲,沒有使用緩存。因爲操做系統自己是有緩存功能的,會先將數據放入緩存,通過必定時間刷盤存入硬盤。若是再使用JVM緩存,就會形成有兩份緩存。Kafka最大限度的利用操做系統的緩存,因此若是想提高Kafka的性能,使用固態硬盤是個很好的手段。由於Kafka只是追加數據和順序讀,不會隨機讀寫,因此即便直接使用磁盤 效率也很高。若是想不丟消息,能夠修改Kafka的配置參數,每發送一條消息就同步一下磁盤,用下降性能的方式提升安全性。傳統的消息中間件通常是使用Btree的方式存儲消息,可是因爲Kafka不會有隨機讀,因此使用BTree並沒有意義。並且BTree只有在內存中查找數據才比較快,是Log(n)。若是在硬盤中查找,每一次尋道都須要必定時間,大約(10ms),屢次尋道會大幅下降效率。設計
Kafka會自動清理過時消息。不管消息是否被消費,建立時間2天(可設置)的消息將會被刪除。中間件
最後再說一下Kafka的消息高可用實現。Kafka使用複製備份機制存儲消息。Kafka收到消息以後會向主節點和從節點發送消息。主節點用於接收和被消費消息,從節點只用於同步消息。Kafka的主從節點不是以服務器爲粒度,而是以主題的分區爲粒度。這樣每臺服務器均可能有主分區和從分區。最大限度的利用機器資源,而不是隻有一臺服務器接收請求,其餘服務器等待。
總結一下,Kafka的優點是高性能,高可用。不足是消息可能會被消費屢次。