目录
1.生产者消息分区器
消息属性
- Key:消息的键,可以是任何可序列化为字节的类型。如果未指定(null),则使用轮询等策略选择分区。
- Value:消息的值,同样可以是任何可序列化的类型,且可以为空。
- Compression Type:消息的压缩类型,可以提高存储和传输效率。可选的压缩类型包括zstd, lz4, snappy, gzip等。
- Headers:消息头,用于存储额外的元数据,可用于消息路径跟踪或其他业务逻辑。
- Partition + Offset:消息发送到Topic后,Broker将为消息分配一个分区编号和偏移量(Offset),这是消息在日志中的唯一位置。
- Timestamp:消息的时间戳,可以是创建时间或业务时间,用于追踪消息的时序。
分区策略
-
无Key时的分区:如果消息没有指定Key(即Key为null),生产者将使用轮询(RoundRobin)策略将消息平均分配到所有分区。这保证了负载均衡。
-
有Key时的分区:如果消息包含Key,生产者将使用Key的哈希值来选择分区。默认情况下,这是通过Key的散列值对分区数取模来完成的。
-
自定义分区算法:如果需要更复杂的分区逻辑,可以实现
Partitioner
接口并指定partition()
方法。例如,基于Key的特定规则(如股票代码的开头数字)将消息分配到特定的分区。
示例:自定义分区算法
假设有一个Topic有2个分区,并且生产者实现了以下自定义分区算法:
- 在上海的用户信息(user_id以"0"开头)发送到Partition-0。
- 在杭州的用户信息(user_id以"1"开头)发送到Partition-1。
public class CustomPartitioner implements Partitioner {
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
int numPartitions = partitions.size();
// 假设 key 是 String 类型
String userId = (String) key;