干趴面试官系列 | 请你简述一下Kafka中的分区分配
歡迎跳轉到本文的原文鏈接:https://honeypps.com/mq/kafka-basic-knowledge-of-partition-assignors/
“請你簡述一下Kafka中的分區分配”,當面試官問你這個問題的時候,你會怎么回答?其實,這道題目里面就暗藏洶涌,因為Kafka中的分區分配在多處出現,而這個問題的表述方式是在潛意識里暗示你回答一種,這樣在你自認為很完美的回答完這個問題之后,面試官會冷不丁的來一句:還有呢?
當你回答完一個點的時候,面試官來一句還有呢,當你再補上一個的時候,他還是會來一句還有呢,就算你又補上第三個的時候,他還是會來一句還有呢?這個時候你會不會一臉懵逼?
今天就針對這個問題來告訴大家怎么樣回答才能嚴絲合縫地搶得先機。
在Kafka中,分區分配是一個很重要的概念,卻往往會被讀者忽視,它會影響Kafka整體的性能均衡。當遇到“分區分配”這個字眼的時候,一定要記住有三處地方,分別是生產者發送消息、消費者消費消息和創建主題。雖然這三處的對應操作都可以被稱之為“分區分配”,但是其實質上所包含的內容卻并不相同。
在面對開篇的問題的時候,不如一下就進行總結性的陳詞,說有三處,第一、第二、第三balabala,當真的讓你講完三處的時候,時間也就差不多了。。聰明的面試官看到你一上來就做了一個規劃總結,那他頂多也就讓你說說你最熟悉的一種,其實說不定內心已經確認你是對的人。
下面針對這三處做個講解。不過本文旨在羅列相關知識點,進行相關性的科普描述,讓讀者可以追根溯源,但并不陳述具體細節,因為細節很多,篇幅有限,如有需要請詳參老朽的《深入理解Kafka》。
生產者的分區分配
對于用戶而言,當調用send方法發送消息之后,消息就自然而然的發送到了broker中。其實在這一過程中,有可能還要經過攔截器、序列化器和分區器(Partitioner)的一系列作用之后才能被真正地發往broker。
producer.send(record);消息在發往broker之前是需要確定它所發往的分區的,如果消息ProducerRecord中指定了partition字段,那么就不需要分區器的作用,因為partition代表的就是所要發往的分區號。如果消息ProducerRecord中沒有指定partition字段,那么就需要依賴分區器,根據key這個字段來計算partition的值。分區器的作用就是為消息分配分區。
Kafka中提供的默認分區器是DefaultPartitioner,它實現了Partitioner接口(用戶可以實現這個接口來自定義分區器),其中的partition方法就是用來實現具體的分區分配邏輯:
public int partition(String topic, Object key, byte[] keyBytes,Object value, byte[] valueBytes, Cluster cluster);默認情況下,如果消息的key不為null,那么默認的分區器會對key進行哈希(采用MurmurHash2算法,具備高運算性能及低碰撞率),最終根據得到的哈希值來計算分區號,擁有相同key的消息會被寫入同一個分區。如果key為null,那么消息將會以輪詢的方式發往主題內的各個可用分區。
注意:如果key不為null,那么計算得到的分區號會是所有分區中的任意一個;如果key為null并且有可用分區,那么計算得到的分區號僅為可用分區中的任意一個,注意兩者之間的差別。
消費者的分區分配
在Kafka的默認規則中,每一個分區只能被同一個消費組中的一個消費者消費。消費者的分區分配是指為消費組中的消費者分配所訂閱主題中的分區。
 
如圖所示,某個主題中共有4個分區(Partition):P0、P1、P2、P3。有兩個消費組A和B都訂閱了這個主題,消費組A中有4個消費者(C0、C1、C2和C3),消費組B中有2個消費者(C4和C5)。按照Kafka默認的規則,最后的分配結果是消費組A中的每一個消費者分配到1個分區,消費組B中的每一個消費者分配到2個分區,兩個消費組之間互不影響。每個消費者只能消費所分配到的分區中的消息。
對于消費者的分區分配而言,Kafka自身提供了三種策略,分別為RangeAssignor、RoundRobinAssignor以及StickyAssignor,其中RangeAssignor為默認的分區分配策略,至于這三種策略具體代表什么含義,可以去查閱相關資料,比如《深入理解Kafka》,嘿嘿。當然也可以通過實現ParitionAssignor接口來自定義分區分配策略。
在消費組中如果有多個消費者,那么這些消費者又可能會采用不同的分配策略,那么最后怎么“拍板”使用哪一種具體的分配策略呢?
對于這里,我想留一道思考題給大家:在Kafka的默認規則中,每一個分區只能被同一個消費組中的一個消費者消費,那么這個規則可以被打破么?如果可以,怎么打破?打破的收益又是什么?
broker端的分區分配
生產者的分區分配是指為每條消息指定其所要發往的分區,消費者中的分區分配是指為消費者指定其可以消費消息的分區,而這里的分區分配是指為集群制定創建主題時的分區副本分配方案,即在哪個broker中創建哪些分區的副本。分區分配是否均衡會影響到Kafka整體的負載均衡,具體還會牽涉到優先副本等概念。
在創建主題時,如果使用了replica-assignment參數,那么就按照指定的方案來進行分區副本的創建;如果沒有使用replica-assignment參數,那么就需要按照內部的邏輯來計算分配方案了。使用kafka-topics.sh腳本創建主題時的內部分配邏輯按照機架信息劃分成兩種策略:未指定機架信息和指定機架信息。如果集群中所有的broker節點都沒有配置broker.rack參數,或者使用disable-rack-aware參數來創建主題,那么采用的就是未指定機架信息的分配策略,否則采用的就是指定機架信息的分配策略。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/mq/kafka-basic-knowledge-of-partition-assignors/
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
 
總結
以上是生活随笔為你收集整理的干趴面试官系列 | 请你简述一下Kafka中的分区分配的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Kafka科普系列 | 原来Kafka
- 下一篇: 周末随笔 | 问好一个问题,有的放矢
