kafka之協調者

一、消費者加入消費組

1、加入組請求的業務邏輯主要步驟如下:

   (1)、消費者加入消費組之前,需要做一些準備工作,比如同步提交一次偏移量,執行監聽器的回調。

   (2)、消費者創建“加入組請求”,包括消費者的元數據作爲請求的數據內容。

   (3)、消費者發送“加入組請求”,採用組合模式返回一個新的異步請求對象,並定義回調處理器。

   (4)、客戶端通過輪詢,確保組合模式返回的異步請求必須完成,這是一個阻塞的方法。

     (5)、異步請求完成後,執行回調方法,將分區設置到消費者的訂閱狀態,並重置心跳定時任務。

涉及的方法ensureActiveGroup()包含有3個子流程:消費者準備加入消費組,發送"加入組請求"並定義響應處理器,消費者完成加入消費組。

2、“加入組請求”對象的變量有: 消費組名稱(groupId) 、消費者成員編號(memberId)、協議類型(protocolType)、元數據(metadata)。

3、分區方式:範圍(協議名稱是range)、循環(協議名稱是roundrobin)。

4、subscriptions 表示每個消費者的訂閱信息,通過讓每個消費者都發送向己的訂閱信息給協調者,協調者就可以收集到所有消費者訂閱的主題。metadata 是集羣的元數據,它記錄了每個主題的相關信息,包括主題的分區數。

注意: subscriptions 是訂閱信息,消費者訂閱了哪些主題。Assignor是分區分配器,它會執行分區分配的算法, Assignnment 是分配結果,是執行分配分區後的結果。

5、消費者分區分配的過程,具體步驟如下:

    (1)消費者發送訂閱信息給協調者。

    (2)協調者收集所有的消費者,以及它們對應的訂閱信息。

    (3)協調者執行任務分配算法,即具體如何將不同的分區分配給不同的消費者。

    (4)分配結果確定後,協調者將分區返回給消費者,消費者分配到分區開始t作。

改進後的具體步驟如下:

    (1)消費者發送訂閱信息給協調者。

    (2)協調者收集所有的消費者,以及它們對應的訂閱信息。

    (3)協調者將所有的消費者成員列表及其訂閱信息發送給主消費者。

    (4)主消費者執行具體的分區分配算法。

    (5)主消費者將分配結果同步回協調者。

    (6)協調者收到主消費者的分配結果,將分區返回給每個消費者。

6、消費者獲取協調者的分配結果的具體步驟如下:

     (1) 每個消費者都發送“加入組請求”給協調者節點。

     (2)協調者收到所有消費者發送的“加入組請求”,返回“ 加入組響應”給每個消費者,還會將執行分區分配算法需要的數據(比如消費者成員列表)傳給主消費者。

    (3)主消費者執行完分區分配算法後,將“分配結果”通過“同步組請求” 的方式發送給協調者節點。其他消費者也會發送“ 同步組請求”給協調者,但是它們的請求中並沒有“分配結果”數據。

    (4) 每個消費者從“ 同步組響應”的結果數據中獲取到分配給它們的分區。

7、關於加入組、同步組、加入組響應處理器、同步組響應處理器的一些步驟如下:

    ( I )每個消費者都向協調者發送“加入組請求”,申請加入消費組。

    (2)協調者接收每個消費者的“加入組請求”,收集消費組的消費者成員列表。

    (3)協調者選舉一個消費者客戶端作爲主消費者。

    (4 )協調者向發送“加入組請求”的每個消費者返回響應結果,其中包含所有消費者成員列表。

    (5 )步驟(3 )的主消費者會做額外的分區分配算法,並在計算完成後發送同步組請求給協調者。

    (6 )普通消費者收到包含成員列表的“加入組響應”結果不做計算,立即發送同步組請求給協調者。

    (7)不管是主消費者還是普通消費者,發送同步組請求的目的都是向協調者申請分區。

    (8)協調者收到主消費者在步驟( 5 )的分配結果,向每個發送同步組請求的消費者返回分區。

8、“加入組請求”和“同步組請求"的相關特點

     (1)、客戶端收到服務端返回的晌應結果後,纔會調用回調處理器的回調方法。

   (2)、使用組合模式返回的異步請求對象,只有調用其完成方法才表示異步請求已經完成。

      (3)、“加入組請求”先於“同步組請求”發送給協調者。

9、消費者發送“加入組請求”給協調者,到獲取到分區列表的過程:

     (1 )、消費者發送“加入組請求”,得到一個“加入組”的異步請求。

     (2 )、消費者獲得“加入組響應”結果,表示協調者已經收集到所有發送了“加入組請求”的消費者。

     (3 )、主消費者會執行分區分配任務,返回結果是消費組中所有消費者及其對應的分區列表。

     (4)、每個消費者都會發送“同步組請求”,得到一個“同步組”的異步請求。

    (5)、每個消費者獲得“同步組響應”結果,表示分配給當前消費者的分區列表。

    (6 )、完成“同步組”的異步請求,並通過模式完成“加入組”的異步請求。

    (7 )、消費者獲取“加入組”異步請求的結果,這個數據表示的就是分配給消費者的分區。

10、消費者加入組之前需要執行兩個操作:

      (1 )禁用向動提交任務,因爲在加入組過程中不會拉取和消費新消息,所以沒必要提交偏移量。

      (2)執行一次同步提交偏移盤,這個操作是阻塞的,確保提交偏移量能夠成功完成。

在加入組之後,也要執行下面幾個操作。

     (1 )更新訂閱狀態的needsFetchCommittedOffsets變量,表示需要刷新分區的提交偏移量。

     (2)更新訂閱狀態的分配結果,爲每個分區新創建分區狀態,這個對象用來記錄分區的最新狀態。

    (3 )啓動消費者的向動提交任務。

11、觸發再平衡操作事件:

     (1)、消費者訂閱的主題集合中任意一個主題的分區數量發生變化。

     (2)、創建或刪除一個主題。

     (3)、消費組中已經存在的一個消費者成員掛掉了。

     (4)、一個新的消費者成員加入已經存在的消費組中。

12、KafkaConsumer具有提供輪詢方法和偏移量的方法,與偏移量相關的方法如下:

     (1)、同步和異步提交偏移量: commitsync(offsets) 、commitAsync(offtsets )

     (2)、獲取分區的拉取和提交偏移量: position(partition)、committed(partitiion) 。

     (3)、定位到指定的位置,更新拉取偏移量: seek(partition,position)。

“加入組和同步組”的請求和晌應對象:

二、協調者處理請求

1、KaafkaApis 是處理客戶端各種請求的人口,但具體的請求處理則交給不同的服務類去實現。比如:

    (1)、服務端處理協調者相關的請求,交給消費組的協調者(GroupCoordinator);

    (2)、處理日誌存儲相關的請求,交給副本管理器(ReplicaManager);

       (3)、處理控制器相關的請求,交給控制器(KafkaController)

2、協調者是同一個消費組下所有消費者的協調節點。一個消費組有多個消費者,而消費組只是一個邏輯概念。具體涉及消費組相關的業務邏輯操作時必須有具體的實現類才能完成, 協調者就充當了這樣的管理員角色。協調者會通過元數據的方式管理消費’組下的所有消費者。由於沒有限制協調者只能作爲一個消費組的協調節點,協調者可以同時管理多個消費組,所以元數據有兩種:消費組的元數據、消費者的元數據。其中,消費組的元數據包括了所有消費者的元數。

注意: 協調者處理“加入組請求”和“同步組請求”,不需妥爲每種請求都定義一個“成員元數據” 。協調者只用了一個統一的“成員元數據”表示“這個消費者在加入組過程中, 在服務端保存的相關狀態數據” 。

3、協調者在處理“加入組請求”和“同步組請求”之前都需要優先做下噸的一些條件檢查:

     (1)、協調者不可用,通常是協調者被關閉了。

     (2)、消費者客戶端傳遞的消費組編號無效,比如沒有設置消費組編號。

     (3)、消費者連接錯了協調者,這個協調者不是消費組的協調者。

     (4)、協調者正在加載,通常是協調者自身在進行遷移。

     (5)、消費者客戶端設置的會話超時時間無效。

     (6)、協調者還沒有消費組,但消費者的成員編號卻不是“未知編號” 。

     (7)、協調者有消費組,消費者的成員編號不是“未知編號”,但是不在消費組中。

條件檢查過後, handleJoinGrouup()方法最終會調用doJoinGroup() 方法來允許消費者加入消費組,有下面兩種情況:

       (1)、消費組爲空井且成員編號爲“未知編號”,允許加入。第一個消費者第一次加入組會執行一次。

     (2)、消費組不爲空,如果成員編號是“未知編號”,允許加入;如果成員變量不是“未知編號”,必須保證已經在消費組中才允許加入。

注意:協調者在發送“加入組響應”之前就更新消費組狀態爲“等待同步”。另外,協調者往每個消費者發送響應結果之後,就立即針對該消費者啓動服務端的心跳監控。

4、協調者處理“同步組請求”時, 將發送“同步組響應結果”給消費者的邏輯,作爲一個回調方法傳給了“延遲存儲”對象(

DelayedStore) 。“延遲存儲”由消息集和回調方法組成,協調者會先存儲完“消費組分配結果” 代表的消息、集,然後才調用回調方法。即,協調者將“消費組分配結果”保存到內部主題之後, 纔會發送“同步組響應”給每個消費者。協調者保存“消費組分配結果”和保存生產者發送的消息一樣,都落到了副本管理器的追加消息流程上。服務端處理生產者消息的回調方法是發送響應給生產者,協調者保存完“消費組分配結果”後的回調方法是將“同步組響應”返回給消費者。

5、消費組的狀態機轉換。有4種狀態: “穩定”“準備再平衡”“等待同步”“離開” 。在創建延遲操作對象之前,會更新消費組狀態爲“準備再平衡”;當延遲操作對象完成後,會更新消費組狀態爲“穩定”。

三、延遲的加入組操作

1、“延遲操作”,表示協調者會延遲發送“加入組響應”給消費者。但協調者不會爲每個消費者的“ 加入組請求”都創建一個“ 延遲操作”,而是僅當消費組狀態從“穩定”轉變爲“準備再平衡”,才創建一個“延遲操作”對象。

2、消費組元數據管理“消費者成員元數據” 的列表,爲了保證列表操作(增加、刪除、修改)的線程安全,需妥在“消費組元數據”對象上進行代碼塊的同步。另外,doJoinGroup()方法依次調用了addMemberAAndRebalance() 、maybePrepareRebalannce() 方法。maybePrepareRebalannce()方法也加了代碼塊同步,這裏的加鎖同步因爲是在同一個線程內,所以是一個可重入鎖。

3、延遲操作相關的結論

      (1)、延遲操作需要指定一個超時時間,表示在指定時間內沒有完成時會被強制完成。

      (2)、延遲操作加入到延遲緩存中,會指定一個鍵。比如,和消費組相關的延遲加入,鍵是消費組編號。

      (3)、服務端創建延遲操作後,通常會有“嘗試完成延遲操作”的動作(延遲操作如果能夠儘早完成是最好的) 。嘗試完成延遲操作的外部事件會有多種情況,而且因爲延遲操作有依賴條件,所以任何可能改變依賴條件的事件,都應該執行“嘗試完成延遲操作” 。比如,協調者因爲依賴了“等待消費者發送加入組請求”這個條件纔會創建“延遲的加入組”對象。如果有消費者發送了加入組請求,就應該嘗試完成“延遲的加入組”對象。

      (4)、當外部事件嘗試完成延遲操作時,怎麼判斷延遲操作能不能完成?不同的延遲操作類型因爲依賴條件不同,應該自定義可以完成延遲操作的條件判斷。

4、延遲操作對象相關的方法:

   (1)、tryComplete()嘗試完成,如果不能完成,返回false ,表示延遲操作還不能完成。

     (2)、onnComplete()延遲操作完成時的回調方法,完成有兩種:正常主動完成和超時被動完成。

     (3)、onExpiration()延遲操作超時的回調方法,如果之前一直調用嘗試完成都不能完成,在指定的坦時時間過去後就會強制完成。調用用這個回調方法, 一定會再調用onnComplete()方法。

5、延遲緩存的相關方法:

(1) 、tryCompleteElseWatch(operatoin,key)嘗試完成延遲的操作,如果不能完成就以指定的鍵監控這個延遲操作。創建完延遲操作對象後,可以立即嘗試完成,不一定只能由其他事件嘗試完成。

(2)、checkAndComplete(key ) 。檢查並嘗試完成指定鍵的延遲操作,在上一個方法中,如果延遲操作沒有完成,會被加入到延遲緩存中。

6、延遲操作需要根據狀態數據判斷是否可以完成:

   (1)、“延遲心跳操作”的狀態數據有: 消費組元數據、消費者元數據。消費者元數據會被協調者用來判斷這個消費者是否及時發送了心跳。消費組元數據會用在:當消費者沒有及時發送心跳,需要將對應的消費者元數據從消費組元數據中移除時。另外,消費組元數據對象還會用在加鎖同步代碼塊上。

(2)、“延遲加入操作”的狀態數據有:消費組元數據。因爲協調者判斷延遲加入操作是否能夠完成的依據是: 消費’組中的所有消費者成員是否都發送或重新發送了“加入組請求” 。

7、第一個消費者發送“加入組請求”給協調者,具體的處理步驟:

    (1)協調者處理第一個消費者的“加入組請求”,會創建消費者成員元數據,並加入消費組元數據。

    (2)消費組初始爲“穩定”狀態,開始再平衡操作,將狀態改爲“準備再平衡” 。

    (3)創建一個“延遲的加入組”對象,並立即通過“延遲緩存”嘗試完成剛創建的延遲操作。

    (4)由於消費組中所有消費者成員(目前只有第一個消費者) 的值對象不爲空, notYetRejoinedMembers()方法沒有收集到任何元素,返回值爲空,滿足“完成延遲操作”的條件。

    (5)因爲可以完成延遲的操作,所以強制完成方法會調用延遲操作對象的onCompleteJoiin()方法。

    (6)延遲操作對象在完成時的回調方法,會首先將消費組狀態更新爲“等待同步” 。

    (7)返回“加入組響應”給所有的消費者(這裏還是隻有第一個消費者) 。

 四、消費組狀態機

1、協調者保存的消費組元數據中記錄了消費組的狀態機, 消費組狀態機的轉換主要發生在“加入組請求”和“同步組請求”的處理過程中。除此之外,協調者處理“離開消費組請求”“遷移消費組請求”“心跳請求” “提交偏移量請求”也會更新消費組的狀態、機,或者依賴消費組的狀態進行不同的處理。

消費者要加入消費組, 需要依次發送“加入組請求”和“同步組請求”給協調者。消費者加入組的過程叫作再平衡,因爲協調者處理這兩種請求會更新消費組狀態,所以再平衡操作跟消費組狀態也息息相關。

2、監昕器回調方法和再平衡操作的執行順序如下:

   (1)消費者準備加入組,調用“消費者再平衡監昕器”的onPartitionsRevoked()方法。

   (2)消費者發送“加入組請求” , 協調者開始處理消費者的“加入組請求”,執行再平衡操作。

   (3) 消費者完成加入組,調用“消費者再平衡監昕器”的onPartitionsAssiignned()方法。

3、一個消費者加入消費組的步驟:

    (1)消費者發送“加入組請求”,消費組的狀態從初始的“穩定”更改爲“準備再平衡”,這個過程會創建一個延遲的操作,並檢查能否完成延遲操作。

    (2)因爲只有一個消費者,所以延遲操作可以完成,消費組狀態從“準備再平衡”改爲“等待同步” 。

    (3)當前的狀態是“等待同步”,表示協調者等待消費者發送“同步組請求” 。當協調者收到主消費者發送的“同步組請求”後,會返回“同步組響應”給消費者,消費組狀態從“ 等待同步”改爲“穩定” 。

4、協調者處理這種消費者重新發送的“加入組請求”時,因爲消費組狀態已經是“穩定”,所以它會立即返回“加入組響應”給消費者。具體步驟如下:

     (1)3個消費者發送“加入組請求”給協調者,消費組狀態從“準備再平衡”到“等待同步” 。

     (2)協調者返回“加入組響應”給3個消費者,前兩個消費者收到“加入組響應”,第三個沒收到響應。

     (3)第二個消費者是普通消費者,它發送“同步組請求”,協調者處理時只是設置對應的回調方法。

    (4)第一個消費者是主消費者,它完成分區分配,發送“同步組請求”給協調者,消費組狀態改爲“穩定” 。

    (5)協調者返回“同步組響應”給兩個消費者,因爲只有前兩個消費者的回調方法不爲空。

    (6)第三個消費者沒收到“加入組響應",它重新發送“加入組請求”

    (7)協調者處理第三個消費者的“加入組請求”,消費組狀態是“穩定”,立即返回“加入組響應” 。

    (8)第三個消費者因爲不是主消費者,它收到“加入組響應”,會立即發送“同步組請求” 。

    (9)協調者處理第三個消費者的“同步組請求”,消費組狀態是“穩定”,立即返回“同步組響應“

5、主消費者沒有收到“加入組響應”的過程:

    (!) 3 個消費者發送“加入組請求”給協調者,消費組狀態從“準備再平衡”到“等待同步” 。

    (2)協調者返回“加入組響應”給3個消費者,前兩個消費者收到“加入組響應",第三個沒收到。

    (3)前兩個消費者都是普通消費者,它發送“同步組請求”,協調者處理時只是設置對應的回調方法。

    (4) 主消費者沒有收到“加入組響應”,重新發送“加入組請求” 。

    (5)協調者處理主消費者的“加入組請求”,消費組狀態是“等待同步”, 立即返回“加入組響應” 。

    (6)主消費者收到“加入組響應”,執行分區分配丁. 作,併發送“同步組請求” 。

    (7)協調者處理主消費者的“同步組請求”,返回響應給所有消費者,更新消費組狀態爲“穩定” 。

6、看消費組狀態爲“準備再平衡”的處理步驟:

      (1 )第一個消費者加入組,消費組狀態爲“等待同步”,第一個消費者同時作爲主消費者還在執行分區分配工作。

     (2)第二個消費者作爲新的消費者加入組,將消費組狀態改爲“準備再平衡”

     (3)第一個消費者執行完分區分配工作,會發送“同步組請求”給協調者。

     (4)協調者處理第一個消費者的“同步組請求”,由於消費組狀態是“準備再平衡”,它會返回“正在再平衡”的錯誤碼給第一個消費者。

    (5)第一個消費者收到錯誤的“同步組響應”,會重新發送“加入組請求:

7、消費者客戶端的工作如下:

    (1)、取消定時心跳任務,因爲離開組意昧着不被協調者官:理,就不需要向協調者發送心跳了。

      (2 )通過消費者的協調者對象(ConsumerCoordinnator)發送“離開組請求”給協調者。

      (3 )重置相關的信息,比如設置成員編號爲“未知編號”、重置rejoinNeeded變量爲false。

8、協調者等待“延遲操作”完成有一個時間限制,它會選擇消費組巾所有消費者會話超時時間的最大值,作爲“再平衡操作的超時時間”,也叫作“延遲操作的超時時間”。

“延遲的心跳”是消費者級別,超時時間是消費者自己的會話超時時間;

“延遲的加入組”是消費組級別,超時時間是所有消費者的最大會話超時時間。

9、消費組再平衡操作過程:

      (1 )消費者發送“加入組請求”時會指定會話的超時時間(簡稱“會話時間”)。

      (2 )協調者不能立即返回“加入組響應”給消費者,創建一個消費組級別的“延遲加入” 。

      (3 )“延遲加入”可以完成,協調者返回“加入組響應”給消費組中的每個消費者。

      (4)協調者爲每個消費者都創建一個“延遲心跳”,並監控每個消費者是否存活。

10、延遲操作有3個主要的方法:

        嘗試完成方法(返回布爾值,表示是有可以完成)、超時的回調方法、完成的回調方法。對於“延遲加入”,嘗試完成是判斷消費組成員中是否還有消費者沒有重新發送“加入組請求”,如果全部都發送了“加入組請求”,就認爲“延遲加入”可以完成。“延遲加入”完成時的回調方法會發送“加入組響應” 。“延遲心跳”的嘗試完成方法(tryCompleteHeartbeat())判斷條件是:消費者成員是否存活。

判斷消費者成員是否存活有下面的3 種條件,只要任何一個條件滿足,都認爲消費者是存活的。

       (1)、消費者成員的awai.ti.ngJoi.nCallback 回調方法不爲空。

       (2)、消費者成員的awai.ti.ngSyncCallback 回調方法不爲空。

      (3)、消費者成員最近的心跳時間加上會話超時時間大於下一次心跳的截止時間。

11、概念:

    (1)、加入組請求:協調者收集消費組的所有消費者,並選舉一個主消費者執行分區分配工作。

    (2)、同步組請求:主消費者完成分區分配,由協調者將分區的分配結果傳播給每個消費者。

    (3)、“ 準備再平衡” :新消費者加入組或者舊消費者離開組消費組都需要執行一次再平衡操作。

    (4)、“ 等待同步”:所有消費者都加入組,協調者返回“加入組響應”給每個消費者前,更改狀態爲“等待同步飛它表示協調者等待接收主消費者發送的包含消費組分配結果的“同步組請求” 。

    (5)、“ 穩定”:協調者返回帶有分區分配結果的“同步組響應”給每個消費者。

12、協調者除了管理消費者的負載均衡,並最終分配分區給每個消費者,還會接收每個消費者的心跳請求。協調者通過心跳監控消費者成員是否存活:如果消費者沒有在指定的截止時間內發送心跳,協調者認爲消費者失敗,將其從消費組中移除,這樣消費組就需要執行再平衡操作。另外,協調者在處理“加入組請求”和“同步組請求”過程中,爲了保證參與加入組的消費者及時響應,也會用心跳來監控消費者成員是否還存活。

 

--------------------  學習筆記  --------------------------

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章