从暴力扫图到成本估算:SpiceDB 如何重构 ReBAC 性能引擎

如果你的公司用了基于关系的访问控制(ReBAC)系统来管权限,可能遇到过这种怪事:系统里明明没几个人,但查个「能不能看这份文档」要等半天;或者反过来,用户和组满天飞,权限检查却快得不可思议。这不是运气,而是你的授权系统压根没搞懂你数据的「形状」。

SpiceDB 最近放出了个实验性功能,叫查询规划器 ,专门治这个问题。这个听起来像数据库领域借来的词,背后藏着一个挺尴尬的现实:过去五年里,他们为提速把缓存、批处理、SQL 优化能用的招全用了,结果还是没解决最核心的问题------查询到底要花多少成本,得看数据长啥样

从「暴力扫图」到「看菜下饭」

事情得从 ReBAC 的本质说起。在 SpiceDB 这类系统里,权限就是一张关系图:文档属于组,组里有成员,成员就是用户。要查 user:maria 能不能 view 文档 budget,系统得沿着「文档→组→成员」这条箭头一路找,看能不能连到 Maria。

以前 SpiceDB 怎么干?它把图遍历当成标准搜索问题,启动一堆协程并发扫,哪儿都试试,直到找到目标或证明找不到为止。这方法在简单场景下没问题,但碰上极端数据分布就傻了。

比如,budget 文档关联了零个组 ------系统还是会先去查库,发现空了才罢休。更惨的是,如果文档关联了几千个组 ,而 Maria 其实一个组都没加,系统会吭哧吭哧把几千个组全扫一遍,最后空手而归。这就像你让快递员去「某栋楼里找个叫张三的」,却不告诉他这栋楼其实是空的,或者城里根本没有这个人。

优化路上的盲人摸象

SpiceDB 团队不是没努力。他们列出的优化清单挺长:请求去重、子问题缓存、一致性哈希、SQL 批量查询、基于类型的跳过、强制走索引......这些招管用了,但都绕开了核心------没人在查询时算算账

edit 权限的例子更明显。这个权限是 (view) AND (editor) 的交集,意思是「既是组成员,又是明确指定的编辑者」。如果 Maria 压根不在 editor 列表里,答案就是铁定的「没权限」,根本不用去查那个可能很复杂的 view 路径。但 SpiceDB 以前傻乎乎地两边并行跑,浪费了提前收工的机会。

团队自己承认:「SpiceDB 采用了简单的方法:在查询时不会做关于如何最快探索图的决策,因为它不知道探索子图的平均成本。」这话听起来像数据库开发者在 1990 年代的自我检讨。

查询规划器的算盘

新方案说白了就一句话:先摸底,再动手

查询规划器会把权限检查翻译成一棵操作树。以上面的 edit 权限为例,树长这样:

复制代码
Intersection(
    Relation(document:editor),
    Arrow(
        Relation(document:group),
        Relation(group:member),
    )
)

每个节点都是树上的积木。关键来了:系统会维护统计信息,估计每个子树可能涉及多少数据。比如,它知道 user:maria 其实只加入了 2 个组,而 document:budget 关联了 500 个组。那它就把箭头操作反过来:先查 Maria 的 2 个组,再去撞文档那边的 500 个组,成本从 500 次检查降到 2 次。

交集操作同理,它会挑那个看起来最便宜、最可能失败的路径先走,争取最快短路。并集操作则反过来,先查最大的集合,保证结果完整性。这些决策在查询运行时动态做,靠的就是预先收集的统计信息。

这不就是数据库干的事吗?

没错。读到这儿,但凡碰过数据库的工程师都会觉得眼熟------查询优化器嘛!PostgreSQL、MySQL 们干了几十年的活儿,把 SQL 掰开揉碎,看哪张表小、哪个索引好、哪种 JOIN 省内存,然后重排执行计划。

SpiceDB 团队自己也没藏着掖着,直接点名:「Query planners can be somewhat fickle. They'll often perform very well for 95% of cases and then strange or downright insane behavior for the remaining 5%; we've experienced this ourselves with the Postgres query planner a number of times.」(查询规划器有点脾气,95% 的情况表现优异,剩下 5% 行为诡异甚至疯癫;我们在 Postgres 查询规划器上自己遇到过好几次。)

这话透着自嘲,也点出了授权系统和数据库系统殊途同归的本质:都是在解决「如何高效遍历数据关系」这个元问题。SpiceDB 把关系存在数据库里,查询时又要管关系,自然逃不开关系型数据库踩过的坑。

实验阶段的「老实人」

既然是实验功能,SpiceDB 团队的态度挺谨慎。他们在代码仓库里搭好了框架,也实现了箭头方向优化这类基础优化,但反复强调「在默认开启前会经受真实与假想场景的轮番轰炸」。

这种态度少见。很多产品爱把实验功能吹得天花乱坠,SpiceDB 反而主动打预防针,生怕用户被那 5% 的疯癫行为误伤。他们甚至直接在博客文末挂出招聘广告,暗示「这活儿不好干,缺人」。

尾声

授权系统从「图遍历」进化到「成本估算」,表面是性能优化,内核是领域成熟度的标尺。当开发者开始关心「数据形状」而非「功能正确性」,说明基础能力已经夯实,开始抠细节了。这对用户是好消息------意味着 ReBAC 不再是实验室玩具,能扛住大规模、异构、复杂的真实世界了。

只是下次你改权限 schema 时,可能得留个心眼:别只顾着逻辑对不对,还得想想「这个关系会有多宽?那个箭头会经过多少节点?」------毕竟,查询规划器在盯着你呢。

相关推荐
流云鹤2 小时前
2026牛客寒假算法基础集训营3(A B G J H F C)
算法
小程故事多_802 小时前
RAG,基于字号频率的内容切分算法,非常强
人工智能·算法·aigc
ADDDDDD_Trouvaille2 小时前
2026.2.15——OJ83-85题
c++·算法
烟花落o2 小时前
算法的时间复杂度和空间复杂度
开发语言·数据结构·笔记·算法
黄俊懿3 小时前
【架构师从入门到进阶】第一章:架构设计基础——第一节:架构设计的目的
架构·系统架构·架构设计
Ronaldinho Gaúch3 小时前
算法题中的日期问题
开发语言·c++·算法
Chary20163 小时前
Opencascade VTK 集成服务 VIS
算法
楠秋9203 小时前
代码随想录算法训练营第三十一天|56. 合并区间 、 738.单调递增的数字、968.监控二叉树
数据结构·算法·leetcode·贪心算法
utmhikari4 小时前
【架构艺术】治理后端稳定性的一些实战经验
java·开发语言·后端·架构·系统架构·稳定性·后端开发