Kafka基本原理

學(xué)習(xí)來源:

1.簡(jiǎn)介

Apache Kafka由著名職業(yè)社交公司LinkedIn開發(fā),最初是被設(shè)計(jì)用來解決LinkedIn公司內(nèi)部海量日志傳輸?shù)葐栴}。Kafka使用Scala語言編寫,于2011年開源并進(jìn)入Apache孵化器,2012年10月正式畢業(yè),現(xiàn)在為Apache頂級(jí)項(xiàng)目。

Kafka是一個(gè)分布式數(shù)據(jù)流平臺(tái),可以運(yùn)行在單臺(tái)或者多臺(tái)服務(wù)器上部署形成集群。它提供了發(fā)布和訂閱功能,使用者可以發(fā)送數(shù)據(jù)到Kafka中,也可以從Kafka中讀取數(shù)據(jù)(以便進(jìn)行后續(xù)的處理)。Kafka具有高吞吐、低延遲、高容錯(cuò)等特點(diǎn)。設(shè)計(jì)內(nèi)在就是分布式的,分區(qū)的和可復(fù)制的提交日志服務(wù)。

2.架構(gòu)組件

  • Broker 節(jié)點(diǎn)
    Kafka集群包含一個(gè)或多個(gè)服務(wù)器,這種服務(wù)器被稱為broker

  • Topic 主題
    每條發(fā)布到Kafka集群的消息都有一個(gè)類別,這個(gè)類別被稱為Topic。(物理上不同Topic的消息分開存儲(chǔ),邏輯上一個(gè)Topic的消息雖然保存于一個(gè)或多個(gè)broker上但用戶只需指定消息的Topic即可生產(chǎn)或消費(fèi)數(shù)據(jù)而不必關(guān)心數(shù)據(jù)存于何處)

  • Partition 分區(qū)
    Partition是物理上的概念,每個(gè)Topic包含一個(gè)或多個(gè)Partition.

  • Producer 生產(chǎn)者
    負(fù)責(zé)發(fā)布消息到Kafka broker

  • Consumer 消費(fèi)者
    消息消費(fèi)者,向Kafka broker讀取消息的客戶端。

  • Consumer Group 消費(fèi)組
    每個(gè)Consumer屬于一個(gè)特定的Consumer Group(可為每個(gè)Consumer指定group name,若不指定group name則屬于默認(rèn)的group)。

  • 消息(Record):
    實(shí)際寫入Kafka中并可以被讀取的消息記錄。每個(gè)record包含了key、value和timestamp。

  • Segment:消息的聚合單位,包括一定的消息數(shù)量。

組件關(guān)系圖-多生產(chǎn)者多消費(fèi)者

圖-2
partion與replication,borker關(guān)系

一個(gè)topic,可以有partion
每個(gè)partition都是一個(gè)有序并且不可變的消息記錄集合。當(dāng)新的數(shù)據(jù)寫入時(shí),就被追加到partition的末尾。在每個(gè)partition中,每條消息都會(huì)被分配一個(gè)順序的唯一標(biāo)識(shí),這個(gè)標(biāo)識(shí)被稱為offset,即偏移量。注意,Kafka只保證在同一個(gè)partition內(nèi)部消息是有序的,在不同partition之間,并不能保證消息有序。
不同的Partition是給到不同的消費(fèi)者的,所以我們也可以定制查詢讓特定的消息進(jìn)入特定的Partition。
produce發(fā)送的消息分發(fā)到不同的partition中,consumer接受數(shù)據(jù)的時(shí)候是按照group來接受,kafka確保每個(gè)partition只能同一個(gè)group中的同一個(gè)consumer消費(fèi),如果想要重復(fù)消費(fèi),那么需要其他的組來消費(fèi)。Zookeerper中保存這每個(gè)topic下的每個(gè)partition在每個(gè)group中消費(fèi)的offset

跨borker的replicate(將follower視為replication);
leader掛掉,會(huì)重新選舉leader。
同一個(gè)broker中的partion可以既有l(wèi)eader,也有follower

  • 生產(chǎn)部分:
    kafka以topic來進(jìn)行消息管理,每個(gè)topic包含多個(gè)partition,每個(gè)partition對(duì)應(yīng)一個(gè)邏輯log,有多個(gè)segment組成。
  • 消費(fèi)部分:
    每個(gè)消費(fèi)者實(shí)例可以消費(fèi)多個(gè)分區(qū),但是每個(gè)分區(qū)最多只能被消費(fèi)者組中的一個(gè)實(shí)例消費(fèi)。

復(fù)制(Replication)過程:

1)一個(gè)partition的復(fù)制個(gè)數(shù)(replication factor)包括這個(gè)partition的leader本身。
2)所有對(duì)partition的讀和寫都通過leader。
3)Followers通過pull獲取leader上log(message和offset)
4)如果一個(gè)follower掛掉、卡住或者同步太慢,leader會(huì)把這個(gè)follower從”in sync replicas“(ISR)列表中刪除。
5)當(dāng)所有的”in sync replicas“的follower把一個(gè)消息寫入到自己的log中時(shí),這個(gè)消息才被認(rèn)為是”committed“的。
6)如果針對(duì)某個(gè)partition的所有復(fù)制節(jié)點(diǎn)都掛了,Kafka選擇最先復(fù)活的那個(gè)節(jié)點(diǎn)作為leader(這個(gè)節(jié)點(diǎn)不一定在ISR里)。

Consumers and Consumer Groups

1)consumer注冊(cè)到zookeeper
2)屬于同一個(gè)group的consumer(group id一樣)平均分配partition,每個(gè)partition只會(huì)被一個(gè)consumer消費(fèi)。
3)當(dāng)broker或同一個(gè)group的其他consumer的狀態(tài)發(fā)生變化的時(shí)候,consumer rebalance就會(huì)發(fā)生。

3.基本原理

3.1 生產(chǎn)者

生產(chǎn)者可以將數(shù)據(jù)寫入到選定的主題。生產(chǎn)者負(fù)責(zé)決定要將哪條記錄寫入到那個(gè)分區(qū)當(dāng)中。可以使用輪詢方式,即每次取一小段時(shí)間的數(shù)據(jù)寫入某個(gè)partition,下一小段的時(shí)間寫入下一個(gè)partition;也可以使用一些分區(qū)函數(shù)(比如哈希),根據(jù)record的key值將記錄寫入不同的分區(qū)。

3.2 消費(fèi)者

多個(gè)消費(fèi)者實(shí)例可以組成一個(gè)消費(fèi)者組,并用一個(gè)標(biāo)簽來標(biāo)識(shí)這個(gè)消費(fèi)者組。一個(gè)消費(fèi)者組中的不同消費(fèi)者實(shí)例可以運(yùn)行在不同的進(jìn)程甚至不同的服務(wù)器上。

如果所有的消費(fèi)者實(shí)例都在同一個(gè)消費(fèi)者組中,那么消息記錄會(huì)被很好的均衡的發(fā)送到每個(gè)消費(fèi)者實(shí)例。

來自官網(wǎng)

如上圖所示,一個(gè)兩個(gè)節(jié)點(diǎn)的Kafka集群上擁有一個(gè)四個(gè)partition(P0-P3)的topic。有兩個(gè)消費(fèi)者組都在消費(fèi)這個(gè)topic中的數(shù)據(jù),消費(fèi)者組A有兩個(gè)消費(fèi)者實(shí)例,消費(fèi)者組B有四個(gè)消費(fèi)者實(shí)例。
從圖中我們可以看到,在同一個(gè)消費(fèi)者組中,每個(gè)消費(fèi)者實(shí)例可以消費(fèi)多個(gè)分區(qū),但是每個(gè)分區(qū)最多只能被消費(fèi)者組中的一個(gè)實(shí)例消費(fèi)。也就是說,如果有一個(gè)4個(gè)分區(qū)的主題,那么消費(fèi)者組中最多只能有4個(gè)消費(fèi)者實(shí)例去消費(fèi),多出來的都不會(huì)被分配到分區(qū)。其實(shí)這也很好理解,如果允許兩個(gè)消費(fèi)者實(shí)例同時(shí)消費(fèi)同一個(gè)分區(qū),那么就無法記錄這個(gè)分區(qū)被這個(gè)消費(fèi)者組消費(fèi)的offset了。如果在消費(fèi)者組中動(dòng)態(tài)的上線或下線消費(fèi)者,那么Kafka集群會(huì)自動(dòng)調(diào)整分區(qū)與消費(fèi)者實(shí)例間的對(duì)應(yīng)關(guān)系

3.3 kafka儲(chǔ)存策略

kafka以topic來進(jìn)行消息管理,每個(gè)topic包含多個(gè)partition,每個(gè)partition對(duì)應(yīng)一個(gè)邏輯log,有多個(gè)segment組成。

每個(gè)segment中存儲(chǔ)多條消息,消息id由其邏輯位置決定,即從消息id可直接定位到消息的存儲(chǔ)位置,避免id到位置的額外映射。(每個(gè)part在內(nèi)存中對(duì)應(yīng)一個(gè)index,記錄每個(gè)segment中的第一條消息偏移)

發(fā)布者發(fā)到某個(gè)topic的消息會(huì)被均勻的分布到多個(gè)partition上(或根據(jù)用戶指定的路由規(guī)則進(jìn)行分布),broker收到發(fā)布消息往對(duì)應(yīng)partition的最后一個(gè)segment上添加該消息,當(dāng)某個(gè)segment上的消息條數(shù)達(dá)到配置值或消息發(fā)布時(shí)間超過閾值時(shí),segment上的消息會(huì)被flush到磁盤,只有flush到磁盤上的消息訂閱者才能訂閱到,segment達(dá)到一定的大小后將不會(huì)再往該segment寫數(shù)據(jù),broker會(huì)創(chuàng)建新的segment

3.4 kafka刪除策略

1.N天前的刪除。
2.保留最近的n GB數(shù)據(jù)。

3.5 broker

與其它消息系統(tǒng)不同,Kafka broker是無狀態(tài)的。這意味著消費(fèi)者必須維護(hù)已消費(fèi)的狀態(tài)信息。這些信息由消費(fèi)者自己維護(hù),broker完全不管(有offset managerbroker管理)。

從代理刪除消息變得很棘手,因?yàn)榇聿⒉恢老M(fèi)者是否已經(jīng)使用了該消息。Kafka創(chuàng)新性地解決了這個(gè)問題,它將一個(gè)簡(jiǎn)單的基于時(shí)間的SLA應(yīng)用于保留策略。當(dāng)消息在代理中超過一定時(shí)間后,將會(huì)被自動(dòng)刪除。這種創(chuàng)新設(shè)計(jì)有很大的好處,消費(fèi)者可以故意倒回到老的偏移量再次消費(fèi)數(shù)據(jù)。這違反了隊(duì)列的常見約定,但被證明是許多消費(fèi)者的基本特征。

3.6 容錯(cuò) (Multi-tenancy)

每個(gè)topic的分區(qū)都可以分布在Kafka集群的不同服務(wù)器上。比如topic A有partition 0,1,2,分別分布在Broker 1,2,3上面。每個(gè)服務(wù)器都可以處理分布在它上面的分區(qū)的寫入和讀取操作。另外,每個(gè)分區(qū)也可以配置多個(gè)副本用來提高容錯(cuò)性。

每個(gè)partition有一個(gè)服務(wù)器充當(dāng)“l(fā)eader”,零至多個(gè)服務(wù)器充當(dāng)“follower”。Leader會(huì)處理針對(duì)于這個(gè)分區(qū)的所有讀寫操作,而follower只是被動(dòng)的從leader中復(fù)制數(shù)據(jù)。當(dāng)leader掛掉了,那么原有的follower會(huì)自動(dòng)選舉出一個(gè)新的leader。每臺(tái)服務(wù)器都會(huì)作為一些分區(qū)的leader,也會(huì)作為其他分區(qū)的follower,所以Kafka集群內(nèi)的負(fù)載會(huì)比較均衡。

如果所有的消費(fèi)者實(shí)例都在不同的消費(fèi)者組,那么每一條消息記錄會(huì)被廣播到每一個(gè)消費(fèi)者實(shí)例。

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í)間小于一個(gè)固定延遲的數(shù)據(jù)。

3.9 目標(biāo) && 應(yīng)用場(chǎng)景

    1. 高吞吐量來支持高容量的事件流處理
  • 2.支持從離線系統(tǒng)加載數(shù)據(jù)
    1. 低延遲的消息系統(tǒng)

3.10 Push vs Pull

1)producer push data to broker,consumer pull data from broker
2)consumer pull的優(yōu)點(diǎn):consumer自己控制消息的讀取速度和數(shù)量。
3)consumer pull的缺點(diǎn):如果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:有個(gè)”acks“配置可以控制接收的leader的在什么情況下就回應(yīng)producer消息寫入成功。

Consumer:

  • 讀取消息,寫log,處理消息。如果處理消息失敗,log已經(jīng)寫入,則無法再次處理失敗的消息,對(duì)應(yīng)”At most once“。

  • 讀取消息,處理消息,寫log。如果消息處理成功,寫log失敗,則消息會(huì)被處理兩次,對(duì)應(yīng)”At least once“。

  • 讀取消息,同時(shí)處理消息并把result和log同時(shí)寫入。這樣保證result和log同時(shí)更新或同時(shí)失敗,對(duì)應(yīng)”Exactly once“。

Kafka默認(rèn)保證at-least-once delivery,容許用戶實(shí)現(xiàn)at-most-once語義,exactly-once的實(shí)現(xiàn)取決于目的存儲(chǔ)系統(tǒng),kafka提供了讀取offset,實(shí)現(xiàn)也沒有問題。

3.12 Zookeeper協(xié)調(diào)控制

1)管理broker與consumer的動(dòng)態(tài)加入與離開。
2)觸發(fā)負(fù)載均衡,當(dāng)broker或consumer加入或離開時(shí)會(huì)觸發(fā)負(fù)載均衡算法,使得一個(gè)consumer group內(nèi)的多個(gè)consumer的訂閱負(fù)載平衡。
3)維護(hù)消費(fèi)關(guān)系及每個(gè)partition的消費(fèi)信息。

全系統(tǒng)分布式,即所有的Producer、Broker和Consumer都默認(rèn)有多個(gè),均為分布式的。Producer和Broker之間沒有負(fù)載均衡機(jī)制。Broker和Consumer 之間利用ZooKeeper進(jìn)行負(fù)載均衡。所有的Broker和Consumer都會(huì)在Zookeeper中進(jìn)行注冊(cè),且Zookeeper會(huì)保存他們的一些元數(shù)據(jù)信息。如果某個(gè)Broker和Consumer發(fā)生了變化,那么所有其他的Broker和Consumer都會(huì)得到通知。

kafka高并發(fā)原理

http://www.itdecent.cn/p/12d59d9951f3

  1. 寫高并發(fā):寫到緩存中,系統(tǒng)自動(dòng) 刷到磁盤。
    2.讀高并發(fā):零拷貝技術(shù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容