自托管实时服务
Supabase Realtime 是一个基于 Elixir 使用 Phoenix Framework 构建的服务器,它允许您通过逻辑复制监听 PostgreSQL 数据库的变化,并通过 WebSocket 广播这些变化。
该服务器有两个版本:Realtime
和 Realtime RLS
。
Realtime
服务器工作原理:
- 监听 PostgreSQL 的复制功能(使用 PostgreSQL 的逻辑解码)
- 将字节流转换为 JSON
- 通过 WebSocket 向所有连接的客户端广播
Realtime RLS
服务器工作原理:
- 轮询 PostgreSQL 的复制功能(使用 PostgreSQL 的逻辑解码和 wal2json 输出插件)
- 将数据库变更传递给 Write Ahead Log Realtime Unified Security (WALRUS) PostgreSQL 函数,并根据行级安全(RLS)策略获取授权订阅者列表
- 将变更转换为 JSON
- 通过 WebSocket 向授权订阅者广播
为什么不直接使用 PostgreSQL 的 NOTIFY
?
有几个原因:
- 您不需要为每个表设置触发器。
NOTIFY
有 8000 字节的有效载荷限制,超过此限制会失败。通常的解决方案是发送一个 ID 然后获取记录,但这会给数据库带来很大压力。Realtime
服务器只消耗两个数据库连接,然后您可以连接许多客户端到这个服务器。减轻数据库负担,要扩展只需添加额外的Realtime
服务器。
优势
- 监听复制功能的妙处在于您可以从任何地方(您的 API、直接在数据库中、通过控制台等)更改数据库,仍然可以通过 WebSocket 接收变更。
- 解耦。例如,如果您想在每次有人购买时发送新的 Slack 消息,您可能会将该功能直接构建到 API 中。这使您可以将异步功能与 API 解耦。
- 这是用 Phoenix 构建的,一个极其可扩展的 Elixir 框架。
该服务器能保证每个数据变更都能送达吗?
目前还不能!由于以下限制:
- PostgreSQL 数据库可能因预写日志(WAL)堆积而耗尽磁盘空间,导致数据库崩溃并阻止 Realtime 服务器接收和广播变更。可以通过在 Realtime RLS 版本中设置 Postgres 配置
max_slot_wal_keep_size
为合理大小来缓解。 - Realtime 服务器可能因复制延迟超过可用内存而崩溃,迫使创建新的复制槽并将复制重置为从最新的 WAL 数据读取。
- 当 Realtime 服务器因任何原因落后太多时(例如与数据库断开连接时 WAL 继续堆积),数据库可能会删除服务器仍需读取的 WAL 段(例如在重新连接后)。