大错特错! “你不需要 Kafka,用 Postgres 就够了” 到底谁的错?
大错特错! “你不需要 Kafka,用 Postgres 就够了” 到底谁的错?
大错特错! “你不需要 Kafka,用 Postgres 就够了” 错了?
我反对, 我就干过这样的事, 但是作者没有说用advisory lock, 这个才是王道啊, 别用长事务来抨击PG, 明显是设计有问题, advisory lock用法如下(参考原文):
《高并发持久工作流/任务流/任务分配的数据库选型: 为什么PG会胜出?》 《PostgreSQL 高并发任务分配系统 实践》
下面看看这个作者Gunnar Morling的说法.
原文: https://www.morling.dev/blog/you-dont-need-kafka-just-use-postgres-considered-harmful/
“你不需要 Kafka,用 Postgres 就够了” 这种说法是有害的
作者:Gunnar Morling(2025 年 11 月 3 日发布)
如果你想登上 HackerNews 的头版,写一篇“Postgres 就够了”或“以你的规模不需要 Kafka”的文章几乎是万无一失的方法。这个话题总是很热门。但作者认为,所有这些文章都忽略了重点:Postgres 和 Kafka 是为截然不同的目的设计的工具。
作者认为“你不需要 Kafka,用 Postgres 就够了”这个建议弊大于利,因为它会导致系统以一种不理想的方式构建。这不是一篇“反 Postgres”的文章,而是一篇“为工作选择合适的工具”的文章。
核心争论点:
“你不需要 Kafka,用 Postgres 就够了”这类文章通常声称 Kafka 难以运行或运行成本高昂,或者两者兼有。他们会展示如何使用 SELECT ... FOR UPDATE SKIP LOCKED 来构建 作业队列(Job Queue) 。
关于作业队列:
作者指出,队列本身就不是 Kafka 典型的应用场景,但即使在 Postgres 上构建一个健壮的队列也比听起来要难。 消费者长时间运行的事务可能导致 MVCC 膨胀(MVCC bloat) 和 WAL 堆积(WAL pile-up) 。如果 Postgres 的 vacuum进程跟不上变化速度,很快就会成为问题。如果选择这样做,建议使用现有的扩展如 pgmq,而不是自己实现。
关于事件流平台(Event Streaming Platform):
Postgres 是一个数据库,而 Kafka 是一个事件流平台。不清楚要用 Postgres 来解决什么问题,这种争论毫无意义。Kafka 适用于微服务通信、数据交换、日志处理、低延迟数据管道和实时流处理(如欺诈检测)。 即使是小数据量场景,用 Postgres 替代 Kafka 也是不合理的,因为它缺乏 Kafka 的核心能力:
| 日志语义 (Log Semantics) | |
| 容错性与高可用性 (HA) | |
| 消费者组 (Consumer Groups) | |
| 低延迟 (Low Latency) | LISTEN/NOTIFY 已知存在严重的锁争用问题。 |
| 连接器 (Connectors) | |
| 客户端、模式和开发者体验 |
结论:选择合适的工具
“小规模”论点的问题: 今天的低数据量可能下周就会变成更大的数据量。为当前的 10 倍负载做准备是合理的建议。Kafka 从设计之初就考虑了可扩展性,而 Postgres 上的队列实现是单写入的,很难垂直扩展。届时,再迁移到 Kafka 将会是一个巨大的工程。 最终建议: 归根结底,是为工作选择合适的工具。 如果你想管理和查询关系型数据集,请使用 Postgres。 如果你需要实现实时事件流用例,请使用 Kafka。 最佳实践: 通常,最佳解决方案是同时使用这两种工具:Postres 用于管理服务的内部状态,Kafka 用于与其他服务交换数据和事件。 同步两者的方法:变更数据捕获(Change Data Capture, CDC) ,尤其是 Outbox Pattern(发件箱模式) ,可以帮助保持 Postgres 和 Kafka 的一致性。使用 Debezium 等工具,通过数据库写入事件,然后通过 CDC 将事件发送到 Kafka。 运营开销: 作者认为运营开销的担忧通常被夸大了。使用 KRaft 模式后,运行单个 Kafka 实例变得非常简单。对于小规模用例,托管服务是首选,其成本在可控范围内。自己解决定制实现中的所有问题所需的时间和精力也应计入总拥有成本(TCO)。
最后,作者总结道:如果你想有效地解决实际问题,请确保了解工具的最佳适用范围和局限性,并为工作选择正确的工具。