目錄
生產者的分區寫入策略
輪詢策略
隨機策略
按key分配策略
亂序分區
自定義分區策略
實現步驟:
消費者組Rebalance機制
Rebalance觸發時機
Rebalance的不良影響
消費者分區分配策略
Range范圍分配策略
RoundRobin輪詢策略
Stricky粘性分配策略
生產者的分區寫入策略
- 輪詢策略
- 隨機策略
- 按key寫入策略
- 自定義分區策略
輪詢策略
默認的策略,也是使用最多的策略,可以最大限度保證所有的消息平均分配到每一個分區。
如果在生產消息的時候,key為null,則使用輪詢算法均衡的分配分區。
隨機策略
隨機策略,就是隨機的將每條消息隨機的分配到每個分區。
按key分配策略
按key分配策略,有可能會出現數據傾斜,例如:某個key包含了大量的數據,因為key的值所有的數據都分配到了一個分區,造成分區的消息數量遠遠大于其他分區。
亂序分區
????????????????輪詢和隨機策略都會導致一個問題,就是生產到kafka的數據都是亂序存儲的,而按照key存儲的也是一定程度上的有序,也是局部有序,但又有可能導致數據傾斜,所以要結合實際情況取舍。
-
在Kafka中生產者是有寫入策略,如果topic有多個分區,就會將數據分散在不同的partition中存儲
-
當partition數量大于1的時候,數據(消息)會打散分布在不同的partition中
-
如果只有一個分區,消息是有序的
自定義分區策略
實現步驟:
1.自定義分區器
public class KeyWithRandomPartitioner implements Partitioner {private Random r;@Overridepublic void configure(Map<String, ?> configs) {r = new Random();}@Overridepublic int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {// cluster.partitionCountForTopic 表示獲取指定topic的分區數量return r.nextInt(1000) % cluster.partitionCountForTopic(topic);}@Overridepublic void close() {}
}
2.在kafka生產者配置中,自定義使用自定義分區器的類名
props.put(ProducerConfig.PARTITIONER_CLASS_CONFIG, KeyWithRandomPartitioner.class.getName());
消費者組Rebalance機制
????????Kafka的Rebalance稱之為再平衡,是kafka確保Consumer group下所有consumer如何達成一致,分配訂閱的topic的每個分區的機制。
Rebalance觸發時機
1.消費者組中consumer的個數發生變化。
例如:有新的consumer加入到消費者組,或者是某個consumer停止了。
2.訂閱的topic的個數發生變化
消費者可以訂閱多個主題,假設當前的消費者組訂閱了三個主題,但有一個主題突然被刪除了,此時也需要發生再均衡。
3.訂閱的topic分區數發生變化
Rebalance的不良影響
- 發生Rebalance時,consumer group下的所有consumer都會協調在一起共同參與,Kafka使用分配策略盡可能達到最公平的分配
- Rebalance過程會對consumer group產生非常嚴重的影響,Rebalance的過程中所有的消費者都將停止工作,直到Rebalance完成
消費者分區分配策略
Range范圍分配策略
Range范圍分配策略是Kafka默認的分配策略,它可以確保每個消費者消費的分區數量是均衡的。
注意:Rangle范圍分配策略是針對每個Topic的。
配置
算法公式
n = 分區數量 / 消費者數量
m = 分區數量 % 消費者數量
前m個消費者消費n+1個
剩余消費者消費n個
RoundRobin輪詢策略
RoundRobin輪詢策略是將消費者以及消費者的所訂閱的所有topic的所有partitions按照字典序排序(topic和分區的hashcode進行排序)。然后通過輪詢方式逐個將分區以此分配給每個消費者。
配置
配置消費者的partition.assignment.strategy為org.apache.kafka.clients.consumer.RoundRobinAssignor
Stricky粘性分配策略
從Kafka 0.11x開始,引入此類分配策略,主要目的:
- 分區分配盡可能均勻
- 在發生rebalance的時候,分區的分配盡可能與上一次分配保持相同
沒有發生rebalance時,Striky粘性分配策略和RoundRobin分配策略類似。
上面如果consumer2崩潰了,此時需要進行rebalance。如果是Range分配和輪詢分配都會重新進行分配,例如:
通過上圖,我們發現,consumer0和consumer1原來消費的分區大多發生了改變。接下來我們再來看下粘性分配策略。
????????我們發現,Striky粘性分配策略,保留rebalance之前的分配結果。這樣,只是將原先consumer2負責的兩個分區再均勻分配給consumer0、consumer1。這樣可以明顯減少系統資源的浪費,例如:之前consumer0、consumer1之前正在消費某幾個分區,但由于rebalance發生,導致consumer0、consumer1需要重新消費之前正在處理的分區,導致不必要的系統開銷。(例如:某個事務正在進行就必須要取消了)????????