經過發佈-訂閱模型,各個子模塊之間作到解耦。各個子模塊只須要知道本身須要往中間件——Kafka 裏取值仍是存值便可。簡單的抽象模型以下圖所示:前端
Kafka 的出現,作到了子系統之間的解耦合。所以,它也被稱爲「分佈式日誌提交系統」或者「分佈式流處理系統」。下面是 Kafka 的一些基本概念:數據庫
Kafka 處理的數據單元叫作「消息」,一種相似於數據庫中「行」或者「記錄」的概念。這些數據單元,對於 Kafka 而言,並無特殊意義,都是字節數組。可是,每一個消息能夠擁有描述性的元數據——Key,這些 Key 一般用來表示消息應該存放的分區。爲了效率,Kafka 裏的消息都是批處理的,同一批(Batch)的消息主題和分區相同,這樣的設計有助於減小單消息在網絡傳輸帶來的開銷。固然,這種處理方式,也是一種在吞吐量和網絡時延裏的折中方案。後端
爲了讓消息具有更加的可讀性,Kafka 使用模式(Schema)來管理數據類型,如 JSON、XML 等等。爲了向後兼容,或者作到可拓展性,選擇合適的 Schema 很是重要。數組
Kafka 裏的消息按主題分類。鑑於 Kafka 裏的消息是按追加、從頭至尾讀取的方式,使用分區能夠大大提升 Kafka 的讀取效率,也提供了系統的可拓展性。消息寫入分區的方式入下圖所示:安全
一個主題的消息,在相似於 Kafka 這樣的系統中,被稱爲——「流」。服務器
Kafka 有兩個重要的概念:生產者和消費者;兩個高級的客戶端(Kafka 使用者)接口:集成 Kafka 的 Kafka Connect API 和操做 Kafka 的 Kafka Stream 接口。網絡
生產者:建立消息的主體。能夠經過不一樣的 Key 把消息發往不一樣的主題中去,還能夠根據用戶自定義的行爲發送日誌。
消費者:讀取消息的主體。消費者追蹤每一個分區的 offset 的值,決定從哪裏讀取消息。Zookeeper 或者 Kafka 能夠存儲 offset 的值。共同消費一個主題的消費者,被稱爲「消費組」。消費組中的消費者和主題中的分區的隊列關係,被稱爲「消費者全部權」。使用以下圖所示的消費組,可使 Kafka 更便於水平拓展:分佈式
中間人:單個的 Kafka 服務器叫作「中間人」(Broker)。一個 Kafka 中間人,接收生產者發來的消費,分配偏移量,並存儲入物理空間中去;同時,中間人還接收消費者的請求,把物理空間裏的消息響應回去。
集羣:一組協同工做的中間人叫作集羣。在一個集羣中,會有一箇中間人充當集羣控制器的角色,該控制器負責監控中間人的狀態。在集羣中,獨佔分區的中間人叫作該分區的「頭頭」(Leader)。多箇中間人共享分區,可使消息進行「主從複製」。當一箇中間人掛掉,其它的中間人可接管頭頭的角色。固然前提是,接管頭頭角色的中間人以前能夠和前頭頭聯通。下圖是一個集羣裏,不一樣中間人間複製消息的圖示:微服務
Kafka 還有一個重要的概念:保質期(Retention),表示消息在 Kafka 服務器裏能夠保留的時長。Kafka 能夠根據不一樣的策略,配置服務器裏消息的保質期。如:根據消息的大小(達到特定大小後失效)、根據時間(指定時間後過時)配置。工具
隨着業務的拓展,以下需求一般會被提出:
舉個例子,不一樣集羣間能夠經過 MirrorMaker 工具進行數據複製。簡而言之,就是經過該工具,從一個集羣消費消息,而後向另一個集羣生產消息。下面是一個經過 MirrorMaker 進行集羣中消息複製的圖例:
雖然有不少發佈/訂閱式的系統,可是選擇 Kafka 是出於如下緣由。
Kafka 能夠無縫接入多個生產者。多個消費者能夠消費同一個主題內的消息,而無需知道該主題內的消息來自哪一個生產者。一個簡單的例子就是:多個微服務往同一個主題中投放消息,而後該主題的消息「聚合」了多個應用。
Kafka 多消費者模型,表現爲多個消費者互不干擾地消費同一主題內的消息。這也是 Kafka 和其它消息隊列不一樣的地方。
Kafka 中的消息會被寫入磁盤,得益於 Kafka 靈活的消息過時策略,磁盤中的消息的有效期是可配置的。鑑於此,Kafka 不會有丟消息的危險。即使應用重啓,它仍可以藉助 Kafka 從結束的地方從新開始。
Kafka 擁有靈活的拓展性配置,這意味着:用戶能夠根據需求拓展 Kafka 的 Broker 的數量來接收和處理任意數量的數據;多 Broker 能夠接管單 Broker 中的錯誤。
上述 多生產者/消費者
、可拓展性
、靈活的有效期配置
造就了 Kafka 的高性能。
基於 Kafka 的生產/消費模型,有一系列的生產和消費的技術。各類處理消息的技術,以統一的接口方式,構成了 Kafka 的生態系統。Kafka 生態系統以下圖所示:
Kafka 能夠記錄用戶訪問前端應用的活動日誌,這也是 LinkedIn 開發 Kafka 的初衷。Kafka 蒐集的用戶點擊鼠標的事件、瀏覽頁面的事件、更改我的主頁的事件,都可以用做後端程序處理,使其變成有價值的產物。
能夠向 Kafka 中發送系統的運行日誌,經過分析這些日誌,能夠對系統的各個指標進行評估。同時,Kafka 記錄的日誌可供其它的日誌分析系統消費。
Kafka 能夠向其它應用發送中間件的消息,如:數據庫有改動,能夠將改動的信息發往應用程序。
Kafka 提供的對數據的流式操做,和 Hadoop 的 Map/Reduce 模型相似,能夠作到數據的實時處理。
Kafka 設計的初衷是處理不一樣類型的數據,實現一個簡單、結構化的高性能系統,以實時地分析用戶行爲和監控系統狀態。
—— Jeff Weiner LinkedIn CEO
LinkedIn 內部最初策劃的系統監控平臺,在監控常規的項目上,如:CPU 利用率、系統性能上難以讓人滿意。開發人員沒法靈活地監控本身的系統狀態,大多狀況下還有系統錯誤。並且,時間間隔長、須要人爲介入也是一個大的問題。
同時,LinkedIn 還建立了一個經過前端向後臺傳輸 XML 文件,讓後臺處理 XML 文件以達到分析用戶行爲的監控應用。該應用一樣很差用:更改 XML 的格式,須要先後臺同時更改;對用戶行爲的分析不是實時的。
系統監控平臺和用戶活動分析平臺不能共用同樣的數據模型,可是兩者之間卻有相同點。即:接收特定格式的數據 --> 返回處理結果。在使用開源解決方案——RocketMQ 也沒法真正解決現有問題後,LinkedIn 決定本身開發一個程序。
由 Jay kreps 主導的開發團隊但願構建一個能同時知足監控系統和追蹤系統的消息系統,最初的目標是:
最終,開發出來的 Kafka 在接口上和典型的消息系統的 發佈/訂閱 一致,但在存儲層上,更像一個日誌聚合系統。藉助 Apache Avro 進行消息序列化,Kafka 可以作到大規模的消息處理。
Kafka 在 2010 年終的時候,發佈到了 GitHub 上,2011 年 7 月進入 Apache 孵化器,2012 年 10 月從 Apache 孵化器畢業,併成爲 Apache 的頂級項目。此後,Kafka 一直在開源社區和 LinkedIn 內部工程師的優化下強壯發展,並逐漸成爲大數據處理的必要工具。