Kafka是一個開源的,分佈式的,高吞吐量的消息系統。隨着Kafka的版本迭代,日趨成熟。你們對它的使用也逐步從日誌系統衍生到其餘關鍵業務領域。特別是其超高吞吐量的特性,在互聯網領域,使用愈來愈普遍,生態系統也越來的完善。同時,其設計思路也是其餘消息中間件重要的設計參考。算法
Kafka原先的開發初衷是構建一個處理海量日誌的框架,基於高吞吐量爲第一原則,因此它對消息的可靠性以及消息的持久化機制考慮的並非特別的完善。0.8版本後,陸續加入了一些複製、應答和故障轉移等相關機制之後,纔可讓咱們在其餘關鍵性業務中使用。多線程
Kafka的運行架構以下圖,各組件之間經過TCP協議通訊:架構
主題,或者說是一類消息。相似於RabbitMQ中的queue。能夠理解爲一個隊列。負載均衡
一個Kafka服務稱之爲Broker。Kafka能夠集羣部署,每個Kafka部署就是一個Broker。框架
生產者和消費者。通常消息系統都有生產者和消費者的概念。生產者產生消息,即把消息放入Topic中,而消費者則從Topic中獲取消息處理。一個生產者能夠向多個Topic發送消息,一個消費者也能夠同時從幾個Topic接收消息。一樣的,一個Topic也能夠被多個消費者來接收消息。分佈式
分區,或者說分組。分組是Kafka提高吞吐量的一個關鍵設計。這樣可讓消費者多線程並行接收消息。建立Topic時可指定Parition數量。一個Topic能夠分爲多個Partition,也能夠只有一個Partition。每個Partition是一個有序的,不可變的消息序列。每個消息在各自的Partition中有惟一的ID。這些ID是有序的。稱之爲offset,offset在不一樣的Partition中是能夠重複的,可是在一個Partition中是不可能重複的。越大的offset的消息是最新的。Kafka只保證在每一個Partition中的消息是有序的,就會帶來一個問題,即若是一個Consumer在不一樣的Partition中獲取消息,那麼消息的順序也許是和Producer發送到Kafka中的消息的順序是不一致的。這個在後續會討論。線程
若是是多Partition,生產者在把消息放到Topic中時,能夠決定放到哪個Patition。這個可使用簡單的輪訓方法,也可使用一些Hash算法。設計
一個Topic的多個Partition能夠分佈式部署在不一樣的Server上,一個Kafka集羣。配置項爲:num.partitions,默認是1。每個Partition也能夠在Broker上覆制多分,用來作容錯。詳細信息見下面建立Topic一節。日誌
顧名思義,定義了一組消費者。通常來講消息中間件都有兩種模式:隊列模式和發佈訂閱模式。隊列模式及每個消息都會給其中一個消費者,而發佈訂閱模式則是每一個消息都廣播給全部的消費者。Kafka就是使用了Consumer Group來實現了這兩種模式。中間件
若是全部的消費者都是同一個Consumer Group的話,就是隊列模式,每一個消息都會負載均衡的分配到全部的消費者。
若是全部的消息者都在不一樣的Consumer Group的話,就是發佈訂閱模式,每一個消費者都會獲得這個消息。
下圖是一個Topic,配置了4個Patition,分佈在2個Broker上。因爲有2個Consumer Group,Group A和Group B均可以獲得P0-P3的全部消息,是一個訂閱發佈模式。兩個Group中的Consumer則負載均衡的接收了這個Topic的消息。若是Group中的Consumer的總線程數量超過了Partition的數量,則會出現空閒狀態。
Kafka的運行依賴於Zookeeper。Topic、Consumer、Patition、Broker等註冊信息都存儲在ZooKeeper中。
Kafka能夠經過配置時間和大小來持久化全部的消息,不論是否被消費(消費者收掉)。舉例來講,若是消息保留被配置爲1天,那麼,消息就會在磁盤保留一天的時間,也就是說,一天之內,任意消費這個消息。一天之後,這個消息就會被刪除。保留多少時間就取決於業務和磁盤的大小。
Kafka主要有兩種方式:時間和大小。在Broker中的配置參數爲:
log.retention.bytes:最多保留的文件字節大小。默認-1。
log.retention.hours:最多保留的時間,小時。優先級最低。默認168。
log.retention.minutes:最多保留的時間,分鐘。若是爲空,則看log.retention.hours。默認null。
log.retention.ms:最多保留的時間,毫秒。若是爲空,則看log.retention.minutes。默認null。
經過命令建立topic:
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic haoxy1
partitions:這個topic的partition的數量。
replication-factor:每一個partition的副本個數。任意將每個分區複製到n個broker上。
這個命令就是建立一個topic:haoxy1,只有1個partition,而且這個分區會部署在一個broker,可是具體哪一個broker能夠經過以下命令查看:
bin/kafka-topics.sh --describ --zookeeper localhost:2181 --topic haoxy1
展現以下:
第一行的摘要信息。
第二行開始是詳細信息,因此是縮進的格式,若是這個topic有10個Partition,那麼就有10行。
Leader:每個分區都有一個broker爲Leader,它負責該分區內的全部讀寫操做,其餘Leader被動的複製Leader broker。若是Leader broker 掛了,那麼其餘broker中的一個將自動成爲該分區的新Leader。本例子只有1個複製,Leader的Partition在Broker1上面。
Replicas:副本在Broker1上面。
Isr:當前有效的副本在Broker1上面。
再來建立一個多副本的Topic:
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 2 --partitions 5 --topic haoxy2
如圖:
由於我有3個Broker:0,1,2。每個Partition都有2個Replicas。分別在2個Broker上。