插曲:Kafka的運行流程總結和源碼前準備

前言

雖然這是一個源碼的預熱篇一樣這也是插曲篇的一個總結,咱們從一開始的集羣的各個角色,到集羣的設計,到網絡模型,到生產者,消費者都已經提了個遍。這一篇會把最後的一個內核提一下,而後對以往的概念三篇作一個總結,把流程梳理一下,增長記憶的同時,也讓後面的源碼變得更加輕鬆愉快,好的這是最後一次鴿了🤣。html

以往連接

概念①:插曲:大白話帶你認識Kafkajava

實踐的:插曲:Kafka的集羣部署實踐及運維相關bootstrap

概念②:插曲:Kafka的生產者原理及重要參數說明安全

概念③:插曲:Kafka的生產者案例和消費者原理解析服務器

沒啥的:插曲:Kafka源碼預熱篇--- Java NIO網絡

1、補完上一篇Kafka中沒提完的

Kafka的生產者案例和消費者原理解析中咱們提到kafka的內核裏還有個 LEO&HW 原理,如今補充回來。架構

1.1 LEO&HW更新原理

首先這裏有兩個Broker,也就是兩臺服務器,而後它們的分區中分別存儲了兩個p0的副本,一個是leader,一個是follower 負載均衡

此時生產者往leader partition發送數據,數據最終確定是要寫到磁盤上的。而後follower會從leader那裏去同步數據,follower上的數據也會寫到磁盤上框架

但是follower是先從leader那裏去同步再寫入磁盤的,因此它磁盤上面的數據確定會比leader的那塊少。運維

1.1.1 LEO是什麼

LEO(last end offset)就是該副本底層日誌文件上的數據的最大偏移量的下一個值,因此上圖中leader那裏的LEO就是5+1 = 6,follower的LEO是5。以此類推,當我知道了LEO爲10,我就知道該日誌文件已經保存了10條信息,位移範圍爲[0,9]

1.1.2 HW是什麼

HW(highwater mark)就是水位,它必定會小於LEO的值。這個值規定了消費者僅能消費HW以前的數據。

1.1.3 流程分析

follower在和leader同步數據的時候,同步過來的數據會帶上LEO的值,但是在實際狀況中有可能p0的副本可能不只僅只有2個。此時我畫多幾個follower(p0),它們也向leader partition同步數據,帶上本身的LEO。leader partition就會記錄這些follower同步過來的LEO,而後取最小的LEO值做爲HW值

這個作法是保證了若是leader partition宕機,集羣會從其它的follower partition裏面選舉出一個新的leader partition。這時候不管選舉了哪個節點做爲leader,都能保證存在此刻待消費的數據,保證數據的安全性。

那麼follower自身的HW的值如何肯定,那就是follower獲取數據時也帶上leader partition的HW的值,而後和自身的LEO值取一個較小的值做爲自身的HW值

如今你再回想一下以前提到的ISR,是否是就更加清楚了。follower若是超過10秒沒有到leader這裏同步數據,就會被踢出ISR。它的做用就是幫助咱們在leader宕機時快速再選出一個leader,由於在ISR列表中的follower都是和leader同步率高的,就算丟失數據也不會丟失太多。

並且咱們以前沒提到什麼狀況下follower能夠返回ISR中,如今解答,當follower的LEO值>=leader的HW值,就能夠回到ISR

但是按照剛剛的流程確實沒法避免丟失部分數據的狀況,固然也是有辦法來保證數據的完整的,我們留到源碼篇以後進行總結的時候再提。

1.1.4 以爲圖中字比較多很差看清楚的看這個

2、Kafka的流程梳理

在大白話篇中帶過你們畫,如今再來一遍。

首先來兩個Broker(這集羣好歹要超過1個服務器才能叫集羣吧),而後它們啓動的時候會往zookeeper集羣中註冊,這時候這兩臺服務器會搶佔一個名字叫controller的目錄,誰搶到了,誰就是controller。好比如今第一臺Broker搶到了。那它就是controller,它要監聽zookeeper中各個目錄的變化,管理整個集羣的元數據

此時咱們經過客戶端來用命令來建立一個主題,這時候會有一個主題的分區方案寫入到zookeeper的目錄中,而在controller監聽到這個目錄寫入了分區方案(其實就是一些元數據信息)以後,它也會更改本身的元數據信息。以後其餘的Broker也會向controller來同步元數據。保證整個集羣的Broker的元數據都是一致的

此時再好比咱們如今經過元數據信息得知有一個分區p0,leader partition在第一臺Broker,follower partition在第二臺Broker。

此時生產者就該出來了,生產者須要往集羣發送消息前,要先把每一條消息封裝成ProducerRecord對象,這是生產者內部完成的。以後會經歷一個序列化的過程。接下來它須要過去集羣中拉取元數據(因此你們知道爲啥在 插曲:Kafka的生產者原理及重要參數說明 的 1-⑤-1 生產者代碼裏面爲啥要提供一個或多個broker的地址了吧),當時的代碼片斷以下

props.put("bootstrap.servers", "hadoop1:9092,hadoop2:9092,hadoop3:9092");
複製代碼

由於若是不提供服務器的地址,是無法獲取到元數據信息的。此時生產者的消息是不知道該發送給哪一個服務器的哪一個分區的。

此時生產者不着急把消息發送出去,而是先放到一個緩衝區。把消息放進緩衝區以後,與此同時會有一個獨立線程Sender去把消息分批次包裝成一個個Batch。整好一個個batch以後,就開始發送給對應的主機上面。此時通過 大白話篇 中加餐時間所提到的Kafka的三層網絡架構模型,寫到os cache,再繼續寫到磁盤上面。

以後寫磁盤的過程又要將 Kafka的生產者案例和消費者原理解析 中提到的日誌二分查找,和剛剛纔提完的ISR,LEO和HW。由於當leader寫入完成時,follower又要過去同步數據了。

此時消費者組也進來,這個消費者組會有一個它們的group.id號,根據這個能夠計算出哪個broker做爲它們的coodinator,肯定了coordinator以後,全部的consumer都會發送一個join group請求註冊。以後coordinator就會默認把第一個註冊上來的consumer選擇成爲leader consumer把整個Topic的狀況彙報給leader consumer。以後leader consumer就會根據負載均衡的思路制定消費方案,返回給coordinator,coordinator拿到方案以後再下發給全部的consumer,完成流程。

因此這樣就把咱們的插曲系列中提到的全部的知識點都連起來了,基本上囊括了全部必須知道的知識點。這麼大一件事情所有都是分開一篇一篇一個個小的知識點按部就班地闡述完整的。若是對Kafka感興趣的朋友,真的推薦把以前的那幾篇均可以讀一下,相信對你必定有所幫助。

回到源碼的那個事兒

源碼篇中Java NIO的基礎知識(看到沒有,基礎是重點字,不要求高級的)和scala是兩個條件,不過若是是對scala沒了解的朋友也不須要擔憂,它和Java十分相似。相信配合必定的解釋的話,必定也能夠看懂全部的套路。

3、簡單說說環境

Kafka的版本是0.10.1版本,最新的應該是2.2.x了。核心流程都沒太大變化,老版本相比新版本更加的穩定,老一點的版本代碼結構會更清晰,由於像這種開源的項目,不少人都會去提交一些patch,可是提交patch的人員不必定是最優秀的那一羣,會讓新的版本代碼看起來很混亂,學習起來就天然不太方便了

1.1 JDK1.7+(這個就不說了)

1.2 scala

Kafka一開始出來的時候其源碼是用scala寫的,可是後面producer端和consumer端的代碼用java重寫了,可是server端的源碼還一直用的scala寫的,因此咱們分析Kafka的源碼須要安裝scala的環境。

我使用的是2.11.8版本,下載好配置環境變量便可(經過度娘能夠完美完成,和Java的配置也很相像,這裏不展開了)。

IDEA須要安裝一個scala的插件,在Settings-plugins那裏,直接搜索scala便可。

1.3 gradle

Kafka的源碼沒有采用maven去管理,而是用的gradle,你們就把這個想成是一個相似於maven的代碼管理工具便可。安裝它的方式跟安裝maven同樣。

finally

將會講到的源碼

KafkaProducer:
    (難的,這個行了其它都是行的,並且源碼寫的很優秀,估計要分好幾篇慢慢來)
Server:
    (有了上面的Producer以後就不會很難了)
KafkaConsumer:
    (很是基礎,不太須要講,其實大數據的框架關於讀數據的部分都不算太難)
複製代碼

若是要一個一個類地去說明,那確定會很是亂套的,因此要藉助場景去闡述巧了,這個場景甚至還不須要我來寫。看見源碼裏面有個example包了嗎?大部分的大數據框架都是開源的,爲了推廣,首先官方文檔要寫的詳細,並且還得本身提供一些不錯的示例包才方便。從如今開始,講解基本依靠代碼註釋。

下一篇就從這裏開始。你們共勉,一塊兒努力

相關文章
相關標籤/搜索