kafka分区知识点

概念

topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队;在磁盘上以文件夹的形式存在;消息最终以文件形式保存在partition文件夹下面,分段存储。

  1. segment文件:

对于一个partition(在Broker中以文件夹的形式存在),里面又有很多大小相等的segment数据文件(这个文件的具体大小可以在config/server.properties中log.segment.bytes=XXX属性设置),这种特性可以方便old segment file的快速删除。

下面先介绍一下partition中的segment file的组成:

  • segment file 组成:由2部分组成,分别为index file和data file,这两个文件是一一对应的,后缀”.index”和”.log”分别表示索引文件和数据文件;
  • segment file 命名规则:partition的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset,ofsset的数值最大为64位(long类型),20位数字字符长度,没有数字用0填充。如下图所示

关于segment file中index与data file对应关系图,这里我们选用网上的一个图片,如下所示:

segement索引文件中存着大量的元数据、数据文件中存储着大量消息;索引文件中的元数据指向数据文件中的消息(message)物理偏移地址。以3,497为例:3表示数据文件的第3个消息(在全局的partition中是第368772个)497表示该消息的物理偏移地址为497

注:Partition中的每条message由offset来表示它在这个partition中的偏移量,这个offset并不是该Message在partition中实际存储位置,而是逻辑上的一个值(如上面的3),但它却唯一确定了partition中的一条Message(可以认为offset是partition中Message的id)。

为什么消息要加分段、索引

我们首先试想一下,如果对于Kafka的一个topic而言,如果topic的partition中只有一个数据文件的话会怎么样?

  • 新数据是添加在文件末尾的,不论文件有多大,时间复杂度永远是O(1)
  • 查找某个offset的Message永远是顺序查找,如果数据量很大,查找效率就很低,和ArrayList一样

如何解决这个问题?Kafka有2大法宝:分段和索引

  • 数据文件的分段: 这个是比较好理解的,加入有100条message,它们的offset是从0到99,假设将数据文件分为5端,第一段为0-19,第二段为20-39,依次类推,每段放在一个单独的数据文件里面,数据文件以该段中最小的offset命名。这样在查找指定offset的Message的时候,用二分查找就可以定位到该Message在哪个段中。
  • 为数据文件建索引:数据文件分段使得可以在一个较小的数据文件中查找对应offset的message了,但是这依然需要顺序扫描才能找到对应offset的message。为了进一步提高查找的效率,Kafka为每个分段后的数据文件建立了索引文件,文件名与数据文件的名字是一样的,只是文件扩展名为.index。

索引文件中包含若干个索引条目,每个条目表示数据文件中一条message的索引。索引包含两个部分(均为4个字节的数字),分别为相对offset和position

  • 相对offset :因为数据文件分段以后,每个数据文件的起始offset不为0,相对offset表示这条message相对于其所属数据文件中最小的offset的大小。举例,分段后的一个数据文件的offset是从20开始,那么offset为25的message在index文件中的相对offset就是25-20 = 5。存储相对offset可以减小索引文件占用的空间。
  • position:表示该条message在数据文件中的绝对位置。只要打开文件并移动文件指针到这个position就可以读取对应的message了。

为什么要分区

假如没有分区,topic都存在一个broker上,那么这个broker就会成为瓶颈。 Kafka中,分区可以均匀的分配在不同的broker集群上面,这样消息就可以均匀(取决于你的消息分区策略,默认的hash也会做到相对的均匀)的分布在不同的分区上,方便水平扩展。

消息如何分区

  • 默认根据消息的key的hashcode%为该topic分配的分区
  • 自定义分区:实现Partitioner;如果有些大客户数据(这些数据的key都是相同的),那么某个分区数据也会很多,这时候可以自定义分区,为大客户指定单独的分区。

如何设置合适的分区数量

  • 主题需要达到多少吞吐量?例如是需要达到每秒钟写入100KB还是1GB
  • 从单个分区读取数据的最大吞吐量是多少?每个分区都会有一个消费者,如果你知道消费者每秒将数据写入数据库的速度不会超过50MB/S,那么从一个分区读取数据的吞吐量不要超过50MB/S
  • 可以通过类似的方法估算生产者向单个分区写入数据的吞吐量,不过生产者的速度一般比消费者的速度快很多,所以最好为生产者多估一些吞吐量
  • 每个broker包含的分区数、可用的磁盘空间和网络带宽
  • 如果消息是按照键值来分区的,那么为已有的主题新增分区就会很困难
  • 单个broker对分区的数量是有限制的,因为分区越多,占用的内存越多,完成首领选举的时间就越长。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值