學(xué)習(xí)來源:
1.簡介
Apache Kafka由著名職業(yè)社交公司LinkedIn開發(fā),最初是被設(shè)計用來解決LinkedIn公司內(nèi)部海量日志傳輸?shù)葐栴}。Kafka使用Scala語言編寫,于2011年開源并進入Apache孵化器,2012年10月正式畢業(yè),現(xiàn)在為Apache頂級項目。
Kafka是一個分布式數(shù)據(jù)流平臺,可以運行在單臺或者多臺服務(wù)器上部署形成集群。它提供了發(fā)布和訂閱功能,使用者可以發(fā)送數(shù)據(jù)到Kafka中,也可以從Kafka中讀取數(shù)據(jù)(以便進行后續(xù)的處理)。Kafka具有高吞吐、低延遲、高容錯等特點。設(shè)計內(nèi)在就是分布式的,分區(qū)的和可復(fù)制的提交日志服務(wù)。
2.架構(gòu)組件
Broker 節(jié)點
Kafka集群包含一個或多個服務(wù)器,這種服務(wù)器被稱為brokerTopic 主題
每條發(fā)布到Kafka集群的消息都有一個類別,這個類別被稱為Topic。(物理上不同Topic的消息分開存儲,邏輯上一個Topic的消息雖然保存于一個或多個broker上但用戶只需指定消息的Topic即可生產(chǎn)或消費數(shù)據(jù)而不必關(guān)心數(shù)據(jù)存于何處)Partition 分區(qū)
Partition是物理上的概念,每個Topic包含一個或多個Partition.Producer 生產(chǎn)者
負責(zé)發(fā)布消息到Kafka brokerConsumer 消費者
消息消費者,向Kafka broker讀取消息的客戶端。Consumer Group 消費組
每個Consumer屬于一個特定的Consumer Group(可為每個Consumer指定group name,若不指定group name則屬于默認(rèn)的group)。消息(Record):
實際寫入Kafka中并可以被讀取的消息記錄。每個record包含了key、value和timestamp。Segment:消息的聚合單位,包括一定的消息數(shù)量。



一個topic,可以有partion
每個partition都是一個有序并且不可變的消息記錄集合。當(dāng)新的數(shù)據(jù)寫入時,就被追加到partition的末尾。在每個partition中,每條消息都會被分配一個順序的唯一標(biāo)識,這個標(biāo)識被稱為offset,即偏移量。注意,Kafka只保證在同一個partition內(nèi)部消息是有序的,在不同partition之間,并不能保證消息有序。
不同的Partition是給到不同的消費者的,所以我們也可以定制查詢讓特定的消息進入特定的Partition。
produce發(fā)送的消息分發(fā)到不同的partition中,consumer接受數(shù)據(jù)的時候是按照group來接受,kafka確保每個partition只能同一個group中的同一個consumer消費,如果想要重復(fù)消費,那么需要其他的組來消費。Zookeerper中保存這每個topic下的每個partition在每個group中消費的offset
跨borker的replicate(將follower視為replication);
leader掛掉,會重新選舉leader。
同一個broker中的partion可以既有l(wèi)eader,也有follower
- 生產(chǎn)部分:
kafka以topic來進行消息管理,每個topic包含多個partition,每個partition對應(yīng)一個邏輯log,有多個segment組成。 - 消費部分:
每個消費者實例可以消費多個分區(qū),但是每個分區(qū)最多只能被消費者組中的一個實例消費。
復(fù)制(Replication)過程:
1)一個partition的復(fù)制個數(shù)(replication factor)包括這個partition的leader本身。
2)所有對partition的讀和寫都通過leader。
3)Followers通過pull獲取leader上log(message和offset)
4)如果一個follower掛掉、卡住或者同步太慢,leader會把這個follower從”in sync replicas“(ISR)列表中刪除。
5)當(dāng)所有的”in sync replicas“的follower把一個消息寫入到自己的log中時,這個消息才被認(rèn)為是”committed“的。
6)如果針對某個partition的所有復(fù)制節(jié)點都掛了,Kafka選擇最先復(fù)活的那個節(jié)點作為leader(這個節(jié)點不一定在ISR里)。
Consumers and Consumer Groups
1)consumer注冊到zookeeper
2)屬于同一個group的consumer(group id一樣)平均分配partition,每個partition只會被一個consumer消費。
3)當(dāng)broker或同一個group的其他consumer的狀態(tài)發(fā)生變化的時候,consumer rebalance就會發(fā)生。
3.基本原理
3.1 生產(chǎn)者
生產(chǎn)者可以將數(shù)據(jù)寫入到選定的主題。生產(chǎn)者負責(zé)決定要將哪條記錄寫入到那個分區(qū)當(dāng)中??梢允褂幂喸兎绞?,即每次取一小段時間的數(shù)據(jù)寫入某個partition,下一小段的時間寫入下一個partition;也可以使用一些分區(qū)函數(shù)(比如哈希),根據(jù)record的key值將記錄寫入不同的分區(qū)。
3.2 消費者
多個消費者實例可以組成一個消費者組,并用一個標(biāo)簽來標(biāo)識這個消費者組。一個消費者組中的不同消費者實例可以運行在不同的進程甚至不同的服務(wù)器上。
如果所有的消費者實例都在同一個消費者組中,那么消息記錄會被很好的均衡的發(fā)送到每個消費者實例。

如上圖所示,一個兩個節(jié)點的Kafka集群上擁有一個四個partition(P0-P3)的topic。有兩個消費者組都在消費這個topic中的數(shù)據(jù),消費者組A有兩個消費者實例,消費者組B有四個消費者實例。
從圖中我們可以看到,在同一個消費者組中,每個消費者實例可以消費多個分區(qū),但是每個分區(qū)最多只能被消費者組中的一個實例消費。也就是說,如果有一個4個分區(qū)的主題,那么消費者組中最多只能有4個消費者實例去消費,多出來的都不會被分配到分區(qū)。其實這也很好理解,如果允許兩個消費者實例同時消費同一個分區(qū),那么就無法記錄這個分區(qū)被這個消費者組消費的offset了。如果在消費者組中動態(tài)的上線或下線消費者,那么Kafka集群會自動調(diào)整分區(qū)與消費者實例間的對應(yīng)關(guān)系。
3.3 kafka儲存策略
kafka以topic來進行消息管理,每個topic包含多個partition,每個partition對應(yīng)一個邏輯log,有多個segment組成。
每個segment中存儲多條消息,消息id由其邏輯位置決定,即從消息id可直接定位到消息的存儲位置,避免id到位置的額外映射。(每個part在內(nèi)存中對應(yīng)一個index,記錄每個segment中的第一條消息偏移)
發(fā)布者發(fā)到某個topic的消息會被均勻的分布到多個partition上(或根據(jù)用戶指定的路由規(guī)則進行分布),broker收到發(fā)布消息往對應(yīng)partition的最后一個segment上添加該消息,當(dāng)某個segment上的消息條數(shù)達到配置值或消息發(fā)布時間超過閾值時,segment上的消息會被flush到磁盤,只有flush到磁盤上的消息訂閱者才能訂閱到,segment達到一定的大小后將不會再往該segment寫數(shù)據(jù),broker會創(chuàng)建新的segment。
3.4 kafka刪除策略
1.N天前的刪除。
2.保留最近的n GB數(shù)據(jù)。
3.5 broker
與其它消息系統(tǒng)不同,Kafka broker是無狀態(tài)的。這意味著消費者必須維護已消費的狀態(tài)信息。這些信息由消費者自己維護,broker完全不管(有offset managerbroker管理)。
從代理刪除消息變得很棘手,因為代理并不知道消費者是否已經(jīng)使用了該消息。Kafka創(chuàng)新性地解決了這個問題,它將一個簡單的基于時間的SLA應(yīng)用于保留策略。當(dāng)消息在代理中超過一定時間后,將會被自動刪除。這種創(chuàng)新設(shè)計有很大的好處,消費者可以故意倒回到老的偏移量再次消費數(shù)據(jù)。這違反了隊列的常見約定,但被證明是許多消費者的基本特征。
3.6 容錯 (Multi-tenancy)
每個topic的分區(qū)都可以分布在Kafka集群的不同服務(wù)器上。比如topic A有partition 0,1,2,分別分布在Broker 1,2,3上面。每個服務(wù)器都可以處理分布在它上面的分區(qū)的寫入和讀取操作。另外,每個分區(qū)也可以配置多個副本用來提高容錯性。
每個partition有一個服務(wù)器充當(dāng)“l(fā)eader”,零至多個服務(wù)器充當(dāng)“follower”。Leader會處理針對于這個分區(qū)的所有讀寫操作,而follower只是被動的從leader中復(fù)制數(shù)據(jù)。當(dāng)leader掛掉了,那么原有的follower會自動選舉出一個新的leader。每臺服務(wù)器都會作為一些分區(qū)的leader,也會作為其他分區(qū)的follower,所以Kafka集群內(nèi)的負載會比較均衡。
如果所有的消費者實例都在不同的消費者組,那么每一條消息記錄會被廣播到每一個消費者實例。
3.7 持久化
依賴文件系統(tǒng)(持久化到本地),數(shù)據(jù)持久化到log
3.8 效率
解決”small IO problem“:
使用”message set“組合消息。
server使用"chunks of messages"寫到log。consumer一次獲取大的消息塊。解決”byte copying“:
在producer、broker和consumer之間使用統(tǒng)一的binary message format。
使用系統(tǒng)的pagecache。
使用sendfile傳輸log,避免拷貝。端到端的批量壓縮(End-to-end Batch Compression),Kafka支持GZIP和Snappy壓縮協(xié)議。
異步批量發(fā)送
批量發(fā)送:配置不多于固定消息數(shù)目一起發(fā)送并且等待時間小于一個固定延遲的數(shù)據(jù)。
3.9 目標(biāo) && 應(yīng)用場景
- 高吞吐量來支持高容量的事件流處理
- 2.支持從離線系統(tǒng)加載數(shù)據(jù)
- 低延遲的消息系統(tǒng)
3.10 Push vs Pull
1)producer push data to broker,consumer pull data from broker
2)consumer pull的優(yōu)點:consumer自己控制消息的讀取速度和數(shù)量。
3)consumer pull的缺點:如果broker沒有數(shù)據(jù),則可能要pull多次忙等待,Kafka可以配置consumer long pull一直等到有數(shù)據(jù)。
3.11 三種消息發(fā)送語義(Message Delivery Semantics)
- At most once—Messages may be lost but are never redelivered.
- At least once—Messages are never lost but may be redelivered.
- Exactly once—this is what people actually want, each message is delivered once and only once.
Producer:有個”acks“配置可以控制接收的leader的在什么情況下就回應(yīng)producer消息寫入成功。
Consumer:
讀取消息,寫log,處理消息。如果處理消息失敗,log已經(jīng)寫入,則無法再次處理失敗的消息,對應(yīng)”At most once“。
讀取消息,處理消息,寫log。如果消息處理成功,寫log失敗,則消息會被處理兩次,對應(yīng)”At least once“。
讀取消息,同時處理消息并把result和log同時寫入。這樣保證result和log同時更新或同時失敗,對應(yīng)”Exactly once“。
Kafka默認(rèn)保證at-least-once delivery,容許用戶實現(xiàn)at-most-once語義,exactly-once的實現(xiàn)取決于目的存儲系統(tǒng),kafka提供了讀取offset,實現(xiàn)也沒有問題。
3.12 Zookeeper協(xié)調(diào)控制
1)管理broker與consumer的動態(tài)加入與離開。
2)觸發(fā)負載均衡,當(dāng)broker或consumer加入或離開時會觸發(fā)負載均衡算法,使得一個consumer group內(nèi)的多個consumer的訂閱負載平衡。
3)維護消費關(guān)系及每個partition的消費信息。
全系統(tǒng)分布式,即所有的Producer、Broker和Consumer都默認(rèn)有多個,均為分布式的。Producer和Broker之間沒有負載均衡機制。Broker和Consumer 之間利用ZooKeeper進行負載均衡。所有的Broker和Consumer都會在Zookeeper中進行注冊,且Zookeeper會保存他們的一些元數(shù)據(jù)信息。如果某個Broker和Consumer發(fā)生了變化,那么所有其他的Broker和Consumer都會得到通知。
kafka高并發(fā)原理
http://www.itdecent.cn/p/12d59d9951f3
- 寫高并發(fā):寫到緩存中,系統(tǒng)自動 刷到磁盤。
2.讀高并發(fā):零拷貝技術(shù)