【多租户架构实战】如何让一个AI系统同时服务多个用户且数据完全隔离?(完整设计方案)
一、问题场景(真实踩坑)
在AI工具上线一段时间后,我遇到一个非常严重的问题:
👉 A用户的数据,居然被B用户"看到了一部分"
虽然不是完整泄露,但已经是致命安全问题
当时系统设计是这样的:
python
sessions = {
"user_id": [...]
}
看似已经按用户隔离,但实际问题在于:
- 缓存是共享的
- RAG知识库没有隔离
- Prompt上下文混用了
👉 本质问题:系统不是"多租户设计"
二、问题分析
1️⃣ 什么是多租户?
👉 一个系统服务多个用户(租户),但:
text
数据必须隔离
资源可以共享
2️⃣ AI系统中的隔离维度
| 模块 | 是否需要隔离 |
|---|---|
| 会话上下文 | 必须 |
| 向量数据库 | 必须 |
| 缓存 | 必须 |
| 模型调用 | 可共享 |
3️⃣ 常见错误设计
❌ 只用 user_id 区分
❌ 缓存不隔离
❌ 向量库混用
三、解决方案(架构设计)
👉 三层隔离模型:
text
用户请求
↓
租户识别(tenant_id)
↓
数据隔离层
↓
AI服务
四、实操步骤(完整实现)
步骤1:定义租户ID
python
def get_tenant_id(user):
return user["tenant_id"]
步骤2:Session隔离
python
sessions = {}
def get_session(tenant_id, user_id):
key = f"{tenant_id}:{user_id}"
return sessions.setdefault(key, [])
步骤3:缓存隔离(关键)
python
import redis
r = redis.Redis()
def cache_key(tenant_id, prompt):
return f"{tenant_id}:{prompt}"
def set_cache(tenant_id, prompt, value):
r.set(cache_key(tenant_id, prompt), value)
步骤4:向量数据库隔离
👉 方式1:分库
text
tenant_1_db
tenant_2_db
👉 方式2:加namespace(推荐)
python
vector_db.search(query, namespace=tenant_id)
步骤5:Prompt隔离
python
def build_prompt(tenant_id, input_text):
system = f"你是{tenant_id}的专属助手"
return system + input_text
五、验证结果
优化前:
- 数据混用风险
- 安全不可控
优化后:
- 数据完全隔离
- 支持企业级用户
六、踩坑记录
1️⃣ 忘记隔离缓存 → 数据串用
2️⃣ 向量库未隔离 → 严重泄露
3️⃣ 日志未隔离 → 隐私风险
七、适合收藏(核心总结)
✔ 多租户设计原则
- 数据必须隔离
- 逻辑可以复用
- 资源适度共享
✔ 避坑清单
- ❌ 不要只靠user_id
- ❌ 不要共享缓存
- ❌ 不要混用知识库
八、总结
👉 多租户不是"功能",而是系统级能力
九、进阶优化
- SaaS级租户隔离
- 独立数据库
- 权限体系结合
十、下一篇
👉 分布式缓存(Redis集群)