Kafka生产者消息分区策略详解
创作时间:
作者:
@小白创作中心
Kafka生产者消息分区策略详解
引用
CSDN
1.
https://blog.csdn.net/J080624/article/details/141959107
Kafka中Topic是对数据逻辑上的分类,而Partition才是数据真正存储的物理位置。所以在生产数据时,如果只是指定Topic的名称,其实Kafka是不知道将数据发送到哪一个Broker节点的。我们可以在构建数据传递Topic参数的同时,也可以指定数据存储的分区编号。
指定分区传递数据是没有任何问题的。Kafka会进行基本简单的校验,比如是否为空,是否小于0之类的。但是你的分区是否存在就无法判断了,所以需要从Kafka中获取集群元数据信息,此时会因为长时间获取不到元数据信息而出现超时异常。所以如果不能确定分区编号范围的情况,不指定分区还是一个不错的选择。
如果不指定分区,Kafka会根据集群元数据中的主题分区来通过算法来计算分区编号并设定:
- 如果指定了分区,直接使用
- 如果指定了自己的分区器,通过分区器计算分区编号,如果有效,直接使用
- 如果指定了数据Key,且使用Key选择分区的场合,采用
murmur2非加密散列算法(类似于hash)计算数据Key序列化后的值的散列值,然后对主题分区数量模运算取余
,最后的结果就是分区编号 - 如果未指定数据Key,或不使用Key选择分区,那么Kafka会采用优化后的粘性分区策略进行分区选择:
- 没有分区数据加载状态信息时,会从分区列表中随机选择一个分区。
- 如果存在分区数据加载状态信息时,
- 根据分区数据队列加载状态,通过随机数获取一个权重值。
- 根据这个权重值在队列加载状态中进行二分查找法,查找权重值的索引值。
- 将这个索引值加1就是当前设定的分区。
增加数据后,会根据当前粘性分区中生产的数据量进行判断,是不是需要切换其他的分区。判断标准就是大于等于
批次大小(16K)的2倍
,或
大于一个批次大小(16K)且需要切换
。如果满足条件,下一条数据就会放置到其他分区。
在某些场合中,指定的数据我们是需要根据自身的业务逻辑发往指定的分区的。所以需要自己定义分区编号规则,而不是采用Kafka自动设置。Kafka早期版本中提供了两个分区器,不过在当前kafka版本中已经不推荐使用了。
自定义分区器
首先我们需要创建一个类,然后实现Kafka提供的分区类接口Partitioner,接下来重写方法。这里我们只关注partition方法即可,因为此方法的返回结果就是需要的分区编号。
/**
* 自定义分区器实现步骤:
* 1. 实现Partitioner接口
* 2. 重写方法
* partition : 返回分区编号,从0开始
* close
* configure
*/
public class KafkaPartitionerMock implements Partitioner {
/**
* 分区算法 - 根据业务自行定义即可
* @param topic The topic name
* @param key The key to partition on (or null if no key)
* @param keyBytes The serialized key to partition on( or null if no key)
* @param value The value to partition on or null
* @param valueBytes The serialized value to partition on or null
* @param cluster The current cluster metadata
* @return 分区编号,从0开始
*/
@Override
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
return 0;
}
@Override
public void close() {
}
@Override
public void configure(Map<String, ?> configs) {
}
}
配置分区器
public class ProducerPartitionTest {
public static void main(String[] args) {
Map<String, Object> configMap = new HashMap<>();
configMap.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
configMap.put( ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
configMap.put( ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
// 这里配置自定义分区器
configMap.put( ProducerConfig.PARTITIONER_CLASS_CONFIG, KafkaPartitionerMock.class.getName());
KafkaProducer<String, String> producer = null;
try {
producer = new KafkaProducer<>(configMap);
for ( int i = 0; i < 1; i++ ) {
ProducerRecord<String, String> record = new ProducerRecord<String, String>("test", "key" + i, "value" + i);
final Future<RecordMetadata> send = producer.send(record, new Callback() {
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if ( e != null ) {
e.printStackTrace();
} else {
System.out.println("数据发送成功:" + record.key() + "," + record.value());
}
}
});
}
} catch ( Exception e ) {
e.printStackTrace();
} finally {
if ( producer != null ) {
producer.close();
}
}
}
}
热门推荐
中国发布全球首个干细胞数据管理国际标准,推动干细胞与再生医学领域健康发展
类似GTA5的手游盘点:五款经典的开放世界游戏推荐
2025年耐玩的沙盒类开放世界手游前十 自由探索的沙盒开放世界游戏大全
管弦乐队中的乐器,管弦乐队的四大乐器
管弦乐队中的木管乐器:长笛、单簧管、双簧管、大管和短笛
联合国难民署:刚果(金)安全和人道主义局势持续恶化
不同疫苗同时接种,这可行吗?
定期存款一年与三年,哪个更合算?
经纬恒润加入“无剑联盟”,携手推动RISC-V软件生态发展
《红楼梦》人物关系深度解析
医患共追“一道光”:上海瑞金医院首设复发淋巴瘤临床研究专病门诊
道家天道:探寻宇宙神秘韵律,感悟生命智慧之光
Excel 数据可视化:掌握 20 个图表、图形和绘图
福建移民海外有多少?解析移民现象与背后原因
大伯在法国,舅舅在英国,大姨西班牙:为什么福建人那么爱出国?
肺结节吃9天拜复乐缩小了是真的吗
梦见我在梦里被鬼压床
银行存折存款到期后如何转存?两种方式优缺点全解析
新月同行麻雀介绍 新月同行麻雀分析
胸痛、胸闷气短、心悸,小心抑郁会“不请自来”
通道四通八达 南昌开放势能澎湃
CRISPR基因编辑:医学革命的新希望
宁夏首例异基因造血干细胞移植成功完成
GTA 5 开发成本与 GTA 6 预算:大幅增加
体脂高怎么减肥?教你三招降低体脂率
投资案例:如何炒好股票?3招麻雀战法,进退自如,却少有人深究
乌鸡白凤丸,神奇中药还是隐藏风险?揭秘它的副作用与使用误区
开学第一课:哪吒的魔力台词如何点亮你的新学期
臭桂鱼的来历与制作方法
图形引擎实战:开放世界游戏制作分享