上一篇看到每个 Segment 旁边都有 `.index` 文件。这次直接用 `kafka-dump-log.sh` 把真实的索引内容读出来,和 `.log` 里每个 batch 的真实位置逐条对照,再手工做一次"查 offset 1200"的定位,看索引到底存了什么、查找是怎么
上一篇的 Offset Index 解决"给定 offset 找位置",而"给定一个时间点,找到从那时起的第一条消息"靠的是另一份索引:`.timeindex`。这次写入 300 条时间戳每条相隔 1 秒的消息,读出真实的时间索引,再用真实的时间戳查询看结果,最后试探 broke
`retention.ms` 到期,消息就消失了吗?这次把一个 topic 的 `retention.ms` 设成 20 秒,写入 1200 条消息(跨三个 Segment),然后每秒观察一次磁盘目录,记录文件到底在什么时候被改名、什么时候真正从磁盘消失,以及消息还能不能被读到。
`cleanup.policy=compact` 的 topic 不按时间或大小删数据,而是保证"每个 Key 至少保留最新的一条"。这次给 10 个 Key 各写 5 轮更新,中途给其中一个 Key 写一条墓碑(value 为 null),跨三个 Segment,然后读出清理前
磁盘写满是运维里最怕的 Kafka 故障之一。这次没有靠推测,而是在一个独立的小容量磁盘镜像上单独起了一个 Kafka 4.3.1 broker(不影响主集群,也不碰系统盘),一路写到磁盘满,记录 broker 的日志、进程状态、客户端看到的现象,以及扩容之后的恢复过程。
Leader 所在的 Broker 崩溃后,剩下的副本会接管,这一点前面的文章已经验证过。这篇关心的是客户端的真实体验:正在持续写入的 Producer 会中断多久、会不会报错、丢不丢消息,以及日志里留下了什么痕迹。这次让 Producer 用 `acks=all` 加幂等(`e
默认情况下,只有 ISR 里的副本才能成为新 Leader。`unclean.leader.election.enable=true` 允许一个不在 ISR 里、数据落后的副本上位。这次在真实集群里把这个场景完整走一遍:先让 Follower 掉出 ISR,Leader 独自写入
Kafka Consumer 的 `poll()` 不只是"拿数据",它还是消费者向组协调器证明"我还活着并且在处理"的方式:`max.poll.interval.ms` 规定两次 `poll()` 之间最长能隔多久。这次用一个真实的 Java Consumer,在 poll 之
同一个 `group.id` 下的多个消费者会瓜分一个 topic 的 Partition,成员一变,分配就重新洗牌(rebalance)。这次给一个 6 分区的 topic 依次加入 3 个消费者、再依次让其中两个离开,用真实的 `ConsumerRebalanceListen
可以,而且这是分区数多于消费者数时的常态:一个消费者会同时持有多个分区。真正的问题是它读到的顺序是什么样的。这次往一个 6 分区的 topic 里按序号 0 到 599 依次发送 600 条消息(37 个不同的 key),再用同一个消费组里的单个 Java Consumer 读回
同一个消费组里,一个分区同一时刻只会分给一个消费者,所以消费者数量超过分区数没有意义,分区数不能被整除时会有人多干活。这次用真实数据量化这两点:一个 6 分区的 topic,每个分区 1000 条、共 6000 条消息,每条消息处理时模拟 `Thread.sleep(1)`,分别
常见说法是"消费组里加一个实例会触发 rebalance,所有人暂停消费"。这次用真实数据检验这句话:一个 6 分区的 topic,Producer 以约每 5 毫秒一条的速度持续写入;消费者 A 先独占全部分区,9 秒后再启动消费者 B;对每个分区统计"消息从产生到被消费"的最