Kafka分区

一、分区的概念规则

1、每个topic(逻辑名称)由一个或多个分区组成,分区是topic物理上的分组,在创建topic时被指定
2、一个partition只对应一个Broke,一个Broke可以管理多个partition
3、由消息在顺序写入,在同一个分区内的消息是有序的,在不同的分区间,kafka并不保证消息的顺序(所以kafka消息是支持跨分区的)
3.1 同一个主题下,不同分区所包含的内容是不同的,每个消息被添加到分区当中时,会被 分配一个偏移量(Offset),它是消息在分区当中的唯一编号,kafka通过offset来确保分区内的消息是顺序的,offset的顺序并不跨越分区。
3.2 要想保证消息顺序消息,需要将partion数目设为1

二、分区(partition)下的leader和follower(也统称为副本)

2.1 每个partition分区会选一server节点火器作为leader,(0个或多个)server节点做Follower
2.2 每个分区有且仅有一个Leader,leader是负责当前数据读写的partition,有0个或多个follower跟随leader,保持数据同步(数据一致性,体现的是follower只用为副本,不负责读写)
2.3 leader失效,会从follower中重新选举一个新的leader,不是所有的follower 都 可以参加选举,只有状态为“同步副本”的follower才可以参于选举(参照 Kafka选举机制简述
2.3.1 控制器(Broker)选举
2.3.2 分区副本选举机制
2.3.3 分区副本选举机制
临时节点,/controller, rpc 通知,优先leader,ISR等
2.4 follower 挂掉、卡住或者同步太慢,leader会把follower删除 ,在新建一个follower
2.5 leader和follower跨节点同步,达到一种选举方式,若是在同一个broker上同步没意义;每个服务器都能作为分区的一个learder和其它分区的followers,因此kafka是一个去中心化的集群,能被很好平衡

三、分区如何分配到broker

1、网上查到的分配策略如下
1.1 将所有的broker和partition排序
1.2 将第i个partition分配到第(i % n)个broker上,这个partition的第一个Replica存在于这个broker上,并且会作为partition的优先副本(learder)
1.3 将第i个partition的 j 个副本,放到第((i+j)%n)个broker上
2、以上分配算法会有一个问题,前几个分区都 会被分配到 broker0, broker1,brokerN上面,直到broker的数量和小于partition数据后会继续重复前面的动作,导致前几个broker压力上升,达不到负载均衡(实际上真实的分配方法并不是这样的)
3、实际上在kafka集群中,每一个broker都有均等 分配partition的learder的机会,kafka是先随机挑选一个broker放置分区0,然后在按顺序放置其他分区,副本也是一样的情况。第一个放置的分区副本一般都是leader,其余的都 是follower

四、Segment

1、由于生产者生产的消息会不断追加到log文件末尾(顺序写入要比内存写入还要快),为防止log文件过大导致数据定位效率低下,kafka采取了分片和索引机制。将每个partition分为多个segment file, 每个segment file存message,segment由两部分组件(.log 数据文件 .index索引文件)组成,并且一一对应
2、目录和file都是物理存储于磁盘,但是kafka不支持随机读写,只支持顺序读写,有效提高磁盘利用率,而且顺序读写速度超过内存读写速度,所以效率很高
3、partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值
4、“.log” 数据文件
4.1 offset在partition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在partition内的位置,即offset表示partition的第多少条message
4.2 MessageSize 表示消息内容data的大小
4.3 data 为Message 的具体内容
5、“.index” 索引文件
5.1 采取稀疏索引的方式,减少了索引文件的大小,相对于稠密索引节约了存储空间,但是查找起来更费时间
5.2 索引包含两个部分,分别为相对offset 和 position
6、消息的查找流程
6.1 通过offset定位数据信息在哪个文件(.index , .log)
6.2 找到文件后,在根据offset和文件名(也是offset)计算相对偏移量,可以找到index中查找到对应position

五、生产者分区策略

1、每一条消息ProducerRecord由主题名称、可选的分区号、可选的键和值组成
2、分区策略
2.1如果消息producerRecord中指定了有效的partition字段,发送记录使用该partition
2.2 如果消息ProducerRecord 中没有指定partition
2.2.1 但指定了key,则将使用key进行hash,采用MurmurHash2算法,(具备高运算性能和低碰撞率)选择一个分区
2.2.2 且没有key,则将以轮询(round-robin)的方式分配一个分区
注意:
如果key不为null,那么hash计算得到的分区号会是所有分区中的任意一个;
如果key为null并且有可用分区,那么计算得到的分区号仅为可用分区中的任意一个
3、自定义分区策略
3.1 随机分区
3.1.1 创建一个类,实现Partitioner,改写partition
3.1.2 在修改配置文件,partitioner.class=package.创建的类名,启动即可
或者 prop.put(“partition.class”, package.创建的类名)

public class DefineRandomPartitioner implements Partitioner {
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueByte, Cluster cluster) {

// 获取总的分区数
Integer partitionNum = cluster.partitionsForTopic(topic);
// 随机策略
int i = random.nextInt(partitionNum);
return i;
}
}

hash 分区
轮询分区
分组分区

提高kafka并行度,其实就是提高kafka topic 分区的个数,分区个数提高了,同一时间同一消费组内可以有的消费者可以更多,消费能力增强。一般分区和消费组内的消费者保持对应

参考&摘录:https://www.cnblogs.com/oneLittleStar/p/13528835.html

上一篇:rabbitmq的常见问题及解决方案


下一篇:Kafka中主题分区副本简介