Kafka是分佈式發佈-訂閱消息系統。它最初由LinkedIn公司開發,以後成爲Apache項目的一部分。Kafka是一個分佈式的,可劃分的,冗餘備份的持久性的日誌服務。它主要用於處理活躍的流式數據。html
在大數據系統中,經常會碰到一個問題,整個大數據是由各個子系統組成,數據須要在各個子系統中高性能,低延遲的不停流轉。傳統的企業消息系統並非很是適合大規模的數據處理。爲了已在同時搞定在線應用(消息)和離線應用(數據文件,日誌)Kafka就出現了。Kafka能夠起到兩個做用:linux
下降系統組網複雜度。git
下降編程複雜度,各個子系統不在是相互協商接口,各個子系統相似插口插在插座上,Kafka承擔高速數據總線的做用。github
同時爲發佈和訂閱提供高吞吐量。據瞭解,Kafka每秒能夠生產約25萬消息(50 MB),每秒處理55萬消息(110 MB)。算法
可進行持久化操做。將消息持久化到磁盤,所以可用於批量消費,例如ETL,以及實時應用程序。經過將數據持久化到硬盤以及replication防止數據丟失。apache
分佈式系統,易於向外擴展。全部的producer、broker和consumer都會有多個,均爲分佈式的。無需停機便可擴展機器。編程
消息被處理的狀態是在consumer端維護,而不是由server端維護。當失敗時能自動平衡。vim
支持online和offline的場景。segmentfault
Kafka的總體架構很是簡單,是顯式分佈式架構,producer、broker(kafka)和consumer均可以有多個。Producer,consumer實現Kafka註冊的接口,數據從producer發送到broker,broker承擔一箇中間緩存和分發的做用。broker分發註冊到系統中的consumer。broker的做用相似於緩存,即活躍的數據和離線處理系統之間的緩存。客戶端和服務器端的通訊,是基於簡單,高性能,且與編程語言無關的TCP協議。緩存
Topic:特指Kafka處理的消息源(feeds of messages)的不一樣分類。
Partition:Topic物理上的分組,一個topic能夠分爲多個partition,每一個partition是一個有序的隊列。partition中的每條消息都會被分配一個有序的id(offset)。
Message:消息,是通訊的基本單位,每一個producer能夠向一個topic(主題)發佈一些消息。
Producers:消息和數據生產者,向Kafka的一個topic發佈消息的過程叫作producers。
Consumers:消息和數據消費者,訂閱topics並處理其發佈的消息的過程叫作consumers。
Broker:緩存代理,Kafa集羣中的一臺或多臺服務器統稱爲broker。
Producer根據指定的partition方法(round-robin、hash等),將消息發佈到指定topic的partition裏面
kafka集羣接收到Producer發過來的消息後,將其持久化到硬盤,並保留消息指定時長(可配置),而不關注消息是否被消費。
Consumer從kafka集羣pull數據,並控制獲取消息的offset
高吞吐是kafka須要實現的核心目標之一,爲此kafka作了如下一些設計:
數據磁盤持久化:消息不在內存中cache,直接寫入到磁盤,充分利用磁盤的順序讀寫性能
zero-copy:減小IO操做步驟
數據批量發送
數據壓縮
Topic劃分爲多個partition,提升parallelism
producer根據用戶指定的算法,將消息發送到指定的partition
存在多個partiiton,每一個partition有本身的replica,每一個replica分佈在不一樣的Broker節點上
多個partition須要選取出lead partition,lead partition負責讀寫,並由zookeeper負責fail over
經過zookeeper管理broker與consumer的動態加入與離開
因爲kafka broker會持久化數據,broker沒有內存壓力,所以,consumer很是適合採起pull的方式消費數據,具備如下幾點好處:
簡化kafka設計
consumer根據消費能力自主控制消息拉取速度
consumer根據自身狀況自主選擇消費模式,例如批量,重複消費,從尾端開始消費等
當須要增長broker結點時,新增的broker會向zookeeper註冊,而producer及consumer會根據註冊在zookeeper上的watcher感知這些變化,並及時做出調整。
kafka和JMS實現(activeMQ)不一樣的是:即便消息被消費,消息仍然不會被當即刪除.日誌文件將會根據broker中的配置要求,保留必定的時間以後刪除;好比log文件保留2天,那麼兩天後,文件會被清除,不管其中的消息是否被消費.kafka經過這種簡單的手段,來釋放磁盤空間.此外,kafka的性能並不會由於日誌文件的太多而低下,因此即便保留較多的log文件,也不不會有問題.
kafka中consumer負責維護消息的消費記錄,而broker則不關心這些,這種設計不只提升了consumer端的靈活性,也適度的減輕了broker端設計的複雜度;這是和衆多JMS prodiver的區別.此外,kafka中消息ACK的設計也和JMS有很大不一樣,kafka中的消息時批量(一般以消息的條數或者chunk的尺寸爲單位)發送給consumer,當消息消費成功後,向zookeeper提交消息的offset,而不會向broker交付ACK.或許你已經意識到,這種"寬鬆"的設計,將會有"丟失"消息/"消息重發"的危險.
比起大多數的消息系統來講,Kafka有更好的吞吐量,內置的分區,冗餘及容錯性,這讓Kafka成爲了一個很好的大規模消息處理應用的解決方案。消息系統通常吞吐量相對較低,可是須要更小的端到端延時,並嚐嚐依賴於Kafka提供的強大的持久性保障。在這個領域,Kafka足以媲美傳統消息系統,如ActiveMR或RabbitMQ。
Kafka的另外一個應用場景是跟蹤用戶瀏覽頁面、搜索及其餘行爲,以發佈-訂閱的模式實時記錄到對應的topic裏。那麼這些結果被訂閱者拿到後,就能夠作進一步的實時處理,或實時監控,或放到hadoop/離線數據倉庫裏處理。
做爲操做記錄的監控模塊來使用,即聚集記錄一些操做信息,能夠理解爲運維性質的數據監控吧。
日誌收集方面,其實開源產品有不少,包括Scribe、Apache Flume。不少人使用Kafka代替日誌聚合(log aggregation)。日誌聚合通常來講是從服務器上收集日誌文件,而後放到一個集中的位置(文件服務器或HDFS)進行處理。然而Kafka忽略掉文件的細節,將其更清晰地抽象成一個個日誌或事件的消息流。這就讓Kafka處理過程延遲更低,更容易支持多數據源和分佈式數據處理。比起以日誌爲中心的系統好比Scribe或者Flume來講,Kafka提供一樣高效的性能和由於複製致使的更高的耐用性保證,以及更低的端到端延遲。
這個場景可能比較多,也很好理解。保存收集流數據,以提供以後對接的Storm或其餘流式計算框架進行處理。不少用戶會將那些從原始topic來的數據進行階段性處理,彙總,擴充或者以其餘的方式轉換到新的topic下再繼續後面的處理。例如一個文章推薦的處理流程,多是先從RSS數據源中抓取文章的內容,而後將其丟入一個叫作「文章」的topic中;後續操做多是須要對這個內容進行清理,好比回覆正常數據或者刪除重複數據,最後再將內容匹配的結果返還給用戶。這就在一個獨立的topic以外,產生了一系列的實時數據處理的流程。Strom和Samza是很是著名的實現這種類型數據轉換的框架。
事件源是一種應用程序設計的方式,該方式的狀態轉移被記錄爲按時間順序排序的記錄序列。Kafka能夠存儲大量的日誌數據,這使得它成爲一個對這種方式的應用來講絕佳的後臺。好比動態彙總(News feed)。
Kafka能夠爲一種外部的持久性日誌的分佈式系統提供服務。這種日誌能夠在節點間備份數據,併爲故障節點數據回覆提供一種從新同步的機制。Kafka中日誌壓縮功能爲這種用法提供了條件。在這種用法中,Kafka相似於Apache BookKeeper項目。
傳統的數據發送須要發送4次上下文切換,採用sendfile系統調用以後,數據直接在內核態交換,系統上下文切換減小爲2次。根據測試結果,能夠提升60%的數據發送性能。Zero-Copy詳細的技術細節能夠參考:https://www.ibm.com/developerworks/linux/library/j-zerocopy/
kafka以topic來進行消息管理,每一個topic包含多個part(ition),每一個part對應一個邏輯log,有多個segment組成。每一個segment中存儲多條消息(見下圖),消息id由其邏輯位置決定,即從消息id可直接定位到消息的存儲位置,避免id到位置的額外映射。每一個part在內存中對應一個index,記錄每一個segment中的第一條消息偏移。發佈者發到某個topic的消息會被均勻的分佈到多個part上(隨機或根據用戶指定的回調函數進行分佈),broker收到發佈消息往對應part的最後一個segment上添加該消息,當某個segment上的消息條數達到配置值或消息發佈時間超過閾值時,segment上的消息會被flush到磁盤,只有flush到磁盤上的消息訂閱者才能訂閱到,segment達到必定的大小後將不會再往該segment寫數據,broker會建立新的segment。
即全部的producer、broker和consumer都會有多個,均爲分佈式的。Producer和broker之間沒有負載均衡機制。broker和consumer之間利用zookeeper進行負載均衡。全部broker和consumer都會在zookeeper中進行註冊,且zookeeper會保存他們的一些元數據信息。若是某個broker和consumer發生了變化,全部其餘的broker和consumer都會獲得通知。
[1] Kafka的一些特色 http://blog.segmentfault.com/mongo/1190000000385620
[2] Apache kafka原理與特性(0.8V) http://shift-alt-ctrl.iteye.com/blog/1930345
[3] Flafka: Apache Flume Meets Apache Kafka for Event Processing
http://blog.cloudera.com/blog/2014/11/flafka-apache-flume-meets-apache-kafka-for-event-processing/
[4] Kafka文件存儲機制那些事 http://tech.meituan.com/kafka-fs-design-theory.html
[5] Kafka深度解析 http://www.jasongj.com/2015/01/02/Kafka%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/
Kafka剖析(一):高擴展、高吞吐的分佈式消息系統初探
[6] Apache kafka 工做原理介紹
http://www.ibm.com/developerworks/cn/opensource/os-cn-kafka/index.html
[7] Kafka設計解析(四):Kafka Consumer解析
http://www.infoq.com/cn/articles/kafka-analysis-part-4
[8] kafka入門:簡介、使用場景、設計原理、主要配置及集羣搭建(轉)
http://www.cnblogs.com/likehua/p/3999538.html
[9] Apache kafka原理與特性(0.8V)
http://shift-alt-ctrl.iteye.com/blog/1930345
[10] Kafka 高性能吞吐揭祕
[11] Kafka源碼分析 ISR
http://zqhxuyuan.github.io/2016/01/14/2016-01-14-Kafka-ISR/#
[12] Kafka設計與原理