v1.4 为 Kafka Simulator 带来 事务 模块 —— 10 个新场景,讲的是工程师最常点头称是、却最少真正看见的主题:exactly-once 语义。课程体系达到 125 个中的 55 个

v1.4 里有什么

事务把一串写入变成一个原子单元,同时也改变了消费者被允许看到的内容:

  • read_committed 与 last stable offset(LSO) —— 为什么事务型消费者读到 LSO 而不是 high watermark,以及一个未结束的事务如何把这个上限按在原地。
  • begin / commit / abort —— 生产者的事务生命周期,作为一台你亲手驱动的状态机,包括 abort 标记对它所覆盖的记录做了什么。
  • consume–process–produce 循环 —— sendOffsetsToTransaction,以及为什么把偏移量提交放在事务内部,才让端到端的 exactly-once 成为现实。
  • 屏蔽(fencing) —— 僵尸生产者如何被 epoch 挡在门外,以及为什么这是整个模型底下的安全网。

exactly-once 难教,是因为其中大半都不可见:标记、LSO、epoch,还有一个悄悄跳过已中止记录的消费者。模拟器把这一切都摆上时间线 —— 你可以看着 LSO 在未结束的事务下一动不动,又在它提交的那一刻向前一跃。

自由模式的新集群类型:双活

从 v1.3 的主备开始的拓扑阶梯继续往上走:自由模式的集群选择器新增了第三种形态 —— Active / active(双活):两个区域都接受写入,并各自向对方镜像。

它刻意不是「把主备的箭头翻一倍」。这个预设是对称的:

  • 每个区域拥有自己的 topic。 west 拥有 west.orderseast 拥有 east.orders,各自以只读方式镜像到对面区域 —— 于是两边都持有完整的流,而不会出现同名之下谁能写的歧义。
  • 每个区域本地写、全局读。 生产者只往自己区域的 topic 追加;每个区域的消费者组同时读本地 topic 和镜像过来的副本,因此每条记录在每一侧都恰好被看到一次。
  • 每个区域都是独立的集群。 两边各跑一个独立的 KRaft 仲裁组,所以你可以杀掉某个区域的控制器 —— 或者整个区域 —— 看看幸存的一侧还能做什么、不能做什么。

最后这一点,正是与本次版本包所讲的事务保证之间那道锋利的对照:exactly-once 是单集群范围内的承诺,而一对双活是两个集群。事务模块给你的一切,在一个区域内部成立,到镜像那里为止。

解释这些形态的灾备课程仍然会在 v1.8 到来 —— 沙盒先落地是有意为之,好让你在场景开口讲述之前,先有地方把这些想法试一遍。

建立在复制之上

这个版本包直接站在 v1.3 之上。事务就是在持久性保证之上再加一层原子性,所以你在那里学会读的 ISR 和 high watermark,在这里依然是底层事实 —— LSO 只不过是压在它们之上、更严格的一道上限。

打开模拟器,开启一个事务,往里生产,然后中止它 —— 再看看 read_committed 消费者看得到什么、看不到什么。