kafka生產者消息如何分區 和 壓縮算法

一、 生產者消息如何分區

kafka的消息組織結構是: topic(主題)--partition(分區)--record(消息),topic下的每條record只會保存在某一個partition中。

分區的主要作用,就是提供負載均衡的能力,分區是部署在不同節點的機器上,通過加節點來提升系統的吞吐量。

在考慮系統的分區策略時,一般有,將消息數據均勻地分配到各個分區上,或者,按具體業務規則實現某種順序分佈在分區上。

如何設定分區策略:

配置producer端的參數:partitioner.class

比如:kafkaProps.put("partitioner.class", "com.yjp.producer.MyPartitioner");

MyPartitioner實現org.apache.kafka.clients.producer.Partitioner 接口的 int partition(params...)方法,partition入參可以參考javadoc

 

具體分區策略如下:

輪詢策略:即順序分配,也是生產者api默認提供的分區策略, 如果未指定 partitioner.class參數,或者設定org.apache.kafka.clients.producer.internals.DefaultPartitioner即指定該策略。

返回分區位置的代碼:

List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return Utils.toPositive(Utils.murmur2(keyBytes)) % partitions.size();

 

隨機策略:即隨意放在任意一個分區上。

代碼:

List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return ThreadLocalRandom.current().nextInt(partitions.size());

 

按key分區策略:kafka允許爲每條消息定義key,key是有着實際業務含義的字符串,該策略可以保證擁有同一種key的所有消息可以進入到相同的分區裏。

代碼:

List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return Math.abs(key.hashCode()) % partitions.size();

 

其他分區策略,比如按ip地址

代碼:

List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return partitions.stream().filter(p -> your filter).map(PartitionInfo::partition).findFirst().get();

另外,創建topic時可以指定partition放在哪些broker上,可以解決異地kafka集羣的問題。

 

二、消息壓縮算法

消息壓縮,優勢是節省帶寬資源和broker磁盤存儲的空間,缺點是犧牲了cpu資源

理論上的做法是 producer壓縮,broker保持,consumer解壓縮(kafka會把具體的壓縮算法封裝到消息集合中)

但是現在的kafka版本在broker端會解壓縮,主要是對消息執行CRC校驗。未來可能會把校驗放到producer端,然後把校驗值傳到broker端。

如何壓縮?

Properties props = new Properties();
props.put("compression.type", "gzip");  //開啓GZIP壓縮
Producer<String, String> producer = new KafkaProducer<Integer, String>(props);


除GZIP以外,還有幾種壓縮算法,Snappy、LZ4和zstd, 他們分別在cpu消耗,壓縮比,壓縮和解壓縮時間方面各有千秋,比如zstd有很好的壓縮比,但是在壓縮和解壓縮時間上就中規中矩。所以具體要根據實際生產需求決定選用哪一種。

 

 

 

 

 

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