多租户知识库用同一个 collection 存所有租户文档,某次检索请求忘了带 tenant_id 过滤条件,返回结果里出现了另一家公司的合同条款。
这类报错背后常见的原因有几处,逐个排除就行。过滤条件由调用方拼接,漏传就变成全量检索;collection 内没有按租户分区;缓存键不含租户维度,命中别人的结果;管理员接口与业务接口共用同一套检索代码。
第一件事是确认请求里的 filter 是否真的下发
python -c "import json;print(json.load(open('req.json')).get('filter'))"
再往下在服务端强制注入租户条件
python -c "print('filter = {\"tenant_id\": ctx.tenant} | client_filter')"
接着按租户拆分 partition 做物理隔离
python -c "from pymilvus import Collection;c=Collection('kb');c.create_partition('t_1024');print(c.partitions)"
等前面都确认过,再用两个租户的账号交叉验证结果集
python cross_check.py --tenant-a t_1024 --tenant-b t_2048 --query 合同违约
恢复的判定其实很直接。服务端注入后即使调用方漏传也只返回本租户数据,交叉验证两边结果无交集,缓存键带上租户后不再串号。
提醒一点。租户隔离不能依赖调用方自觉传参,过滤条件要在服务端强制拼接,物理分区则是最稳的一层。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
