我们开发了一个网络应用程序,它依赖于我们用户之间的实时交互。我们使用Angular作为前端,Hasura和Postgres上的GraphQL作为后端。我们注意到,当同时有超过300个用户处于活动状态时,我们会遇到严重的性能损失。
因此,我们希望改进我们的订阅设置。
我们认为可能的问题可能是:
1.订阅过多
1.订阅太大且太复杂,订阅中的分叉太多
关于1.每个用户在使用web应用程序时具有大约5-10个活动的订阅。关于第2项。我们有复杂的订阅,因为我们将多达6个表连接在一起。
我们想到的解决方案:
1.使用更多的查询,并限制对完全需要实时的字段使用订阅。
1.将复杂的查询/订阅拆分为多个较小的查询/订阅。
我们是否遗漏了另一个可能的原因?我们还可以使用什么来提高整体性能?
感谢您的评分
1条答案
按热度按时间l7mqbcuq1#
前言
OP问题非常广泛,不可能在一般情况下回答。
因此,我在这里描述的内容反映了我在优化订阅方面的经验--这是OP的决定,它反映了他们的情况。
系统简短描述
系统用户:上传文档,提取信息,准备新文档,在过程中进行匡威(类似IM的功能),有AI机器人试图减少重复性任务的负担,与外部系统交换数据的服务。
有很多实体,人类和机器人参与者之间有很多互动。加上相当复杂的授权规则:数据的可见性取决于组织、部门和文件的内容。
What was on start
一开始是:
query
更改为subscription
前2-3个月还可以,然后:
首先,我们对查询本身进行了优化,但这还不够:
订阅优化
第一步:订阅拆分:订阅更改日期,查询更改
代替将整个数据拆分为多个部分的复杂订阅:
A.指示实体已更改的单个字段的订阅
例如
而不是:
它返回数千行。
创建一个函数:
于是就变成了:
始终为一行和一个字段
B.应用逻辑的改变
doc_change_date
max_change_date
值注意事项
如果订阅函数有时返回误报,这是完全可以的。
不需要将所有 predicate 从源查询复制到订阅函数。
例如
在我们的案例中:数据的可见性取决于组织和部门(甚至更多)。
因此,如果一个部门的用户创建/修改了文档,则其他部门的用户无法看到此更改。
但这些变化就像每个组织在一分钟内发生一次/两次。
因此,对于订阅功能,我们可以忽略这些粒度,并为整个组织计算
max_change_date
。拥有更快更粗糙的订阅功能是有益的:它将更频繁地触发数据刷新,但是整体成本将更低。
第二步。多路订阅
第一步至关重要。
Hasura有一个多路复用的订阅:https://hasura.io/docs/latest/graphql/core/databases/postgres/subscriptions/execution-and-performance.html#subscription-multiplexing
所以理论上Hasura可以足够聪明并解决你的问题。
但如果你认为“显性比隐性好”,你还可以做另一个步骤。
在我们的案例中:
因此,订阅变为:doc_change_date、dossier_change_date、msg_change_date等。
但实际上,只有一个订阅可能是有益的:“嘿!你有变化了!“
因此,而不是多个订阅应用程序使只有一个。
注意事项
我们考虑了2种多路复用订阅格式:
{max_change_date}
,该字段对所有实体都是累积的{doc_change_date, dossier_change_date, msg_change_date}
现在A为我们工作但也许我们以后会改成B
第三步。我们在hasura2.0中会有什么不同
这是我们还没有尝试过的。
Hasura 2.0允许为查询注册VOLATILE函数。
这允许在DB中创建具有记忆功能的函数:
这允许进一步优化订阅函数和查询函数。
注意事项
实际上,不需要等待hasura 2.0就可以做到这一点,但这需要在postgresql端使用技巧:
它的工作,但这一招是很难推荐.
谁知道呢,也许未来的postgresql版本或更新将使它成为不可能。
总结
这就是我现在能说的关于这个主题的一切。
事实上,我很高兴在一年前读到类似的东西。
如果有人看到一些陷阱-请发表评论,我很乐意听取意见,也许替代方法。
我希望这个解释能帮助一些人,或者至少能启发人们思考如何以其他方式处理订阅。