有讲到分区机制了,我发现只要是数据存储系统,都会涉及到分区的概念。例如mysql的分表/redis的分区/kafka的分区。在概览这一节我们看到了Kafka的基本组件,在Broker里面可以有多个主题的消息存储单元。在存储单元内可以有多个分区。
生产者生成消息之后发送给Broker,但是怎么进行分区呢。分区又会带来什么优点呢?
- 负载均衡,分区主要的目标是可扩展性,不同的分区可以部署在不同的机器上,我们可以扩展机器,增加吞吐量
- 保证消息的有序性。在同一个分区的消息,能保证消息的消费顺序。
负载均衡策略
Kafka是java语言开发的,在生产者端可以配置分区策略:
继承实现接口:org.apache.kafka.clients.producer.Partitioner
int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);
- 轮询策略:默认策略,不配置特定实现则默认选择轮询策略,分区从0,1,2,3分别插入数据
- 随机策略:随机分配实现上面的接口方法 partition
List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return ThreadLocalRandom.current().nextInt(partitions.size());
- 根据key分区策略:Kafka允许给消息设置关键字Key,我们可以根据key分区。
这个key是比Topic更细的概念。比如同样是审批消息,可以分为授信审批-放款审批-还款审批,如果按照key分区,同样的key的消息在一个分区里面,那么这些消息可以保证消费的有序性。这一点非常重要
List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return Math.abs(key.hashCode()) % partitions.size();
上面三种是常见的三种负载均衡策略,在实际例子中还有一些特别需要特别定制的需求
- 根据ip归属地分区
- 根据车牌号分区