如果你的公司用了基于关系的访问控制(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 时,可能得留个心眼:别只顾着逻辑对不对,还得想想「这个关系会有多宽?那个箭头会经过多少节点?」------毕竟,查询规划器在盯着你呢。
