忘掉 SQS、RabbitMQ 和 Kafka 吧。用 Postgres 就行。

BBetter Stack
컴퓨터/소프트웨어AI/미래기술

스크립트

00:00:00SQS、Kafka 和 RabbitMQ 可以直接扔进垃圾桶了,因为你现在可以直接在 Postgres 中
00:00:05使用 PGMQ 管理队列。我甚至能听到有人说,这根本无法扩展。
00:00:11但实际上它完全可以,因为 Postgres 可以轻松处理数百万行数据和
00:00:15每秒数千个请求。因此,如果你想保持基础设施的简洁,
00:00:20今天我们将探讨如何使用 PGMQ 构建高吞吐量的分布式应用。
00:00:30废话不多说,我们直接进入演示。我已经用 Docker 设置好了一个项目,
00:00:34并安装了 PGMQ。它支持两种使用方式:纯 SQL 模式,或者使用官方客户端库(如
00:00:41Rust 或 Python),以及诸如 Ruby 或多种不同
00:00:47类型的 TypeScript 等社区库。既然我们在编程语言上永远无法达成一致,我将直接通过
00:00:52纯 SQL 选项来运行这个演示。让我们从创建一个新队列开始。我们运行 select pgmq.create,然后传入
00:00:58队列名称本身。这里的每个队列都是一张独立的表。如果我们直接查看数据库,
00:01:04就会发现新表现在已经存在了。然后我们可以向队列发送消息,指定队列名称,
00:01:09以及作为 JSON 的消息内容。你还可以选择包含一个延迟时间。这样消息就会被推送至
00:01:15队列,但在比如五秒钟内无法被消费。好了,现在我们已经在队列中有了消息。
00:01:20接下来消费它们。我们可以使用 read 命令来做到这一点。VT 代表可见性超时(Visibility Timeout)。在这里它意味着
00:01:26你读取的消息将在 30 秒内保持不可见状态。因此没有其他进程可以获取它们。
00:01:31这就是 PGMQ 保证恰好一次(exactly-once)投递的方式。quantity 参数表示我们希望读取的
00:01:38消息数量。如果它们在该时间窗口内未被删除或归档,就会重新变为可见。而要做到这一点,
00:01:44你可以运行 archive(从队列中删除并添加到归档表),或者直接
00:01:49运行 delete。例如,在这里,我删除了 ID 为 2 的消息。顺便提一句,如果你觉得这个视频
00:01:54对你有所帮助,请订阅频道,这对我们是极大的支持。它能帮助我们持续创作免费内容,
00:01:59从而帮助到尽可能多的开发者。好了,让我们来对 PGMQ 进行压力测试。首先,我向队列中添加 10 万行数据,
00:02:06这大约花费了 0.4 秒。现在我将启动 100 个工作进程,分别以每批 10 个任务的规模来处理作业,
00:02:13看看读取所有这些数据需要多长时间。在这里,所有工作进程所做的工作就是读取消息、
00:02:18记录读取内容,然后将其删除。当然,在实际中你会对这些数据进行更多处理。
00:02:23但在这里,我只关心直接测试 PGMQ 的性能。最终耗时 9 秒。
00:02:29每个工作进程平均每秒处理 111 条消息。因此综合起来大约是每秒 11,100 条消息。
00:02:37我有意将 Docker 容器限制在 2 个 CPU 和 2GB 内存,这对于生产服务来说很典型。
00:02:44现在,正如我之前所提到的,你也可以使用客户端库来与 PGMQ 交互。
00:02:49通过结合使用 TypeScript 和 Prisma,我们可以创建队列、发送消息、批量读取消息,
00:02:55你也可以用 Python 完成同样的操作。因此,如果你不想引入额外的依赖,你完全可以在 Postgres 中
00:03:01通过 PGMQ 运行大规模队列。我们甚至可以更进一步,用 Postgres 替换掉尽可能多的技术栈组件,
00:03:08我在这个视频中对此进行了介绍。

핵심 요약

利用 Postgres 中的 PGMQ 扩展,开发者无需引入额外的消息队列中间件即可构建吞吐量达每秒上万条消息的分布式应用。

하이라이트

  • Postgres 通过 PGMQ 扩展可以完全替代 SQS、RabbitMQ 和 Kafka 等传统消息队列工具。

  • 在限制为 2 个 CPU 和 2GB 内存的 Docker 环境中,PGMQ 处理 10 万行数据的总耗时为 9 秒。

  • 100 个工作进程并发消费时,PGMQ 的综合吞吐量达到每秒 11,100 条消息。

  • PGMQ 支持纯 SQL 模式以及 Rust、Python、Ruby 和 TypeScript 等官方或社区客户端库。

  • 通过设置可见性超时(Visibility Timeout)参数,PGMQ 能够保证消息的恰好一次(exactly-once)投递。

타임라인

使用 Postgres 替代传统消息队列

  • 传统的消息队列工具如 SQS、Kafka 和 RabbitMQ 可以直接被 Postgres 中的 PGMQ 替代。
  • Postgres 能够轻松支撑数百万行数据和每秒数千个请求的扩展需求。
  • 这种方案能够保持基础设施的简洁性并构建高吞吐量的分布式应用。

传统消息队列并非不可替代,现代关系型数据库完全具备处理高并发队列的能力。通过引入 PGMQ,开发者可以直接在数据库内部管理队列,从而减少系统架构中的外部依赖组件。

PGMQ 的基本操作与消费机制

  • PGMQ 支持纯 SQL 模式以及多种主流编程语言的客户端库。
  • 调用创建函数后,队列中的每一条消息都会存入独立的数据库表中。
  • 通过可见性超时机制,读取的消息在指定时间内保持不可见以实现精确投递。

系统支持通过纯 SQL 或通过 Prisma 等客户端库与队列进行交互。向队列发送消息时可以指定 JSON 格式的内容以及延迟时间。读取操作通过可见性超时参数锁定消息,防止其他进程重复获取,直到消息被删除或归档。

性能压测与大规模队列应用

  • 向队列添加 10 万行数据仅耗时 0.4 秒。
  • 100 个工作进程配合每批 10 个任务的规模在 9 秒内完成了全部数据的消费。
  • 在 2 个 CPU 和 2GB 内存的限制下,整体吞吐量达到了每秒 11,100 条消息。

为了验证实际生产环境中的表现,测试对 PGMQ 进行了高并发压力测试。在标准硬件限制的容器中,工作进程持续读取并删除消息,最终测得平均每个进程每秒处理 111 条消息的性能数据,证明了其应对大规模负载的能力。

커뮤니티 글

아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!

이 영상에 대해 글쓰기