乐趣区

关于java:kafka上基本结构和消息存储

与传统的 mq(如 rabbitmq)不同,kafka 以文件模式存储和传输音讯,官网将其定义为 事件流式解决平台,它人造具备分布式属性。

2.8 版本前,kafka 须要 zk 存储 broker 和 consumer 局部信息(留神:producer 不依赖 zk);2.8 之后,kafka 曾经不再依赖 kafka。

然而生产环境目前(kafka 3.1 版本)还是要应用 zk。

抄一段官网文档:

It is now possible to run Apache Kafka without Apache ZooKeeper! We call this the Kafka Raft metadata mode, typically shortened to KRaft mode. KRaft is intended to be pronounced like craft (as in craftsmanship).
It is currently PREVIEW AND SHOULD NOT BE USED IN PRODUCTION, but it is available for testing in the Kafka 3.1 release.

根本构造

  • 生产者

没啥可说的,负责向 broker 推送音讯

  • broker

kafka 的一个服务节点,多个 broker 形成 kafka 集群;broker 个别部署在不同的物理机上

  • topic

同一类音讯放入同一个主题中,比方订单属于一个主题,领取属于另一个主题;但有一点须要留神,topic 只是逻辑层面的概念,音讯实在存在于 partition 中

  • partition
| --topic1-0     --> 这个文件夹就是 partition
    | --00000000000000000000.index
    | --00000000000000000000.log
    | --00000000000000368769.index
    | --00000000000000368769.log
| --topic2-0
| --topic2-1

能够看到 partition 的序号是从 0 开始的。

partition 实际上是服务器磁盘上一个文件夹,同一个 topic 能够蕴含很多 partition。减少 partition 可能无效的减少吞吐量,相似于 nginx 下减少 tomcat 可无效减少吞吐。

比方上图中 topic1,有 5 个 partition 均匀分布在 3 台 broker 中。如果发送音讯时指定主题是 topic1,此音讯会按肯定规定推送到某一个 partition 上。当然,发送时也能够指定

音讯在一个 partition 中是有序的,在多个 partition 中无奈保障有序。

  • segment

partition 外部是两种文件,*.index*.log 文件。

log 文件寄存音讯,index 文件寄存索引,它们是成对呈现的;雷同名字的一对 log+index 文件称之为一个 segment,是 kafka 文件存储的最小单位。

segment 是概念性的货色,没啥实际意义。

  • replication

partition 的正本,作为数据备份不对外提供服务。replication 和 partion 个别不在同一台 broker 上以减少容错,相似上图的散布。

  • consumer

消费者负责生产音讯,通过保护 offset 来确定音讯。
offset 能够了解成一个指针,指向以后生产的音讯;同时 offset 也和 partition 相干,这个前面细说。

音讯被生产后 offset 会减少,但音讯自身仍然存在于 partition 中不被清理。partition 音讯只会被定时清理,默认保留 7 天。

  • group

生产端有个 group 的概念,一个 group 下能够有一个 consumer,也能够有多个 consumer。

一条音讯只会发送到同一个 group 下的其中一个 consumer

多个 partition 能够对应一个 consumer(上图 group2);然而一个 paratition 不能对应多个 consumer,最多对应一个(上图 group1)。
如果一个 group 中的 consumer 数量比 partition 数多,会呈现闲置的 consumer(上图 consumer3)

音讯存储

来看一下 kafka 音讯存储形式

| --topic1-0     --> 这个文件夹就是 partition
    | --00000000000000000000.index
    | --00000000000000000000.log
    | --00000000000000368769.index
    | --00000000000000368769.log
    | --00000000000000744271.index
    | --00000000000000744271.log
| --topic2-0
| --topic2-1

音讯采纳 程序写 的形式写入 .log 文件中,当文件大小达到阈值,会生成新的 log 和 index 文件。

开始只有 00000000000000000000.log,当文件大小达到 500m(默认)会生成
00000000000000368769.log。368769 这个数字,正是 00000000000000000000.log 文件中 offset 的最大值。

log 采纳这样的命名形式有一个益处,如果查找 offset=728378 的音讯,能够很快锁定它所在的文件,肯定在 00000000000000744271.log 文件中。

再看 index 索引文件,kafka 采纳稠密索引的形式——不为每条数据建设索引,索引是不间断的。(上图为第 1、3、6、8、N 条数据建设了索引,2、4、5 就没有索引)

依据 log 文件的名字(00000000000000368769.log),很容易晓得第 1 条数据对应的 offset 是 368769+1=368770。

咱们看一下这个 partition 中数据 offset=368776 的音讯的查找过程:

  1. 368769<368776<744271,因而定位到 00000000000000368769.log 文件
  2. 368776-368769=7,因而找文件中的第 7 条数据
  3. 去 00000000000000368769.index 中查找,7 没在索引中,但 6 和 8 都有索引
  4. 依据索引 <6,1407> 的 value,定位到 00000000000000368769.log 中物理偏移地址 1407,定位到音讯 Message368775;但这是第 6 条数据数据应该找它的下一条,找到了 Message368776

附录

P6-P7 常识合辑

退出移动版