Flo*_*rca 4 postgresql graphql graphql-subscriptions hasura
我们开发了一个依赖于用户之间实时交互的网络应用程序。我们使用 Angular 作为前端,使用 Hasura 和 Postgres 上的 GraphQL 作为后端。我们注意到,当超过 300 个用户同时活跃时,我们会遇到严重的性能损失。
因此,我们希望改进我们的订阅设置。
我们认为可能的问题可能是:
关于 1. 每个用户在使用 Web 应用程序时大约有 5-10 个活跃订阅。关于 2. 我们的订阅很复杂,因为我们将最多 6 个表连接在一起。
我们想到的解决方案:
Ale*_* Yu 12
OP问题非常广泛,不可能在一般情况下得到回答。
因此,我在这里描述的内容反映了我在优化订阅方面的经验 - 由 OP 决定是否反映他们的情况。
系统用户:上传文档、提取信息、准备新文档、在处理过程中进行对话(类似 IM 的功能),有人工智能机器人试图减轻重复任务的负担,以及与外部系统交换数据的服务。
有很多实体,人类和机器人参与者之间有很多交互。再加上相当复杂的授权规则:数据的可见性取决于组织、部门和文档内容。
起初是:
querysubscription前2-3个月还可以,然后:
首先我们对查询本身进行了优化,但这还不够:
而不是将整个数据分割成多个部分的复杂订阅:
A. 订阅单个字段,表明实体已更改
例如
代替:
subscription{
document{
id
title
# other fields
pages{ # array relation
...
}
tasks{ # array relation
...
}
# multiple other array/object relations
# pagination and ordering
}
Run Code Online (Sandbox Code Playgroud)
返回数千行。
创建一个函数:
于是就变成了:
subscription{
doc_change_date{
max_change_date
}
}
Run Code Online (Sandbox Code Playgroud)
始终为一行且始终为一个字段
B. 应用逻辑的改变
doc_change_datemax_change_date如果订阅功能有时返回误报,那绝对没问题。
无需将所有谓词从源查询复制到订阅函数。
例如
在我们的例子中:数据的可见性取决于组织和部门(甚至更多)。
因此,如果一个部门的用户创建/修改文档 - 此更改对其他部门的用户不可见。
但这些变化就像每个组织在一分钟内发生/两次。
因此,对于订阅功能,我们可以忽略这些粒度并max_change_date针对整个组织进行计算。
拥有更快、更粗略的订阅功能的好处是:它会更频繁地触发数据刷新,但整体成本会更低。
第一步是至关重要的一步。
Hasura 具有多路复用订阅:https://hasura.io/docs/latest/graphql/core/databases/postgres/subscriptions/execution-and-performance.html#subscription- Multiplexing
所以理论上哈苏拉足够聪明并能解决你的问题。
但如果您认为“显式比隐式更好”,您还可以采取另一步。
在我们的例子中:
所以订阅就变成了:doc_change_date、dossier_change_date、msg_change_date 等等。
但实际上,只订阅一项可能会有好处:“嘿!有适合您的更改!”
因此,应用程序只创建一个订阅,而不是多个订阅。
我们考虑了两种多路订阅格式:
{max_change_date}该字段对所有实体都是累加的{doc_change_date, dossier_change_date, msg_change_date}现在“A”为我们工作。但也许我们将来会改成“B”。
那是我们还没有尝试过的。
Hasura 2.0 允许注册 VOLATILE 函数进行查询。
这允许在数据库中创建具有记忆功能的函数:
这可以进一步优化订阅功能和查询功能。
实际上,无需等待 hasura 2.0 就可以做到这一点,但它需要 postgresql 方面的技巧:
它有效,但很难推荐这个技巧。
谁知道呢,也许未来的 postgresql 版本或更新会让这一切变得不可能。
这就是我现在能就这个话题说的一切。
事实上,我很高兴一年前读到类似的东西。
如果有人看到一些陷阱 - 请发表评论,我很高兴听到意见,也许还有其他方法。
我希望这个解释能够帮助某人或至少激发人们思考如何以其他方式处理订阅。
| 归档时间: |
|
| 查看次数: |
1437 次 |
| 最近记录: |