14 KiB
AI生图平台桶缓存落地对接答复(基于本项目现状)
1. 文档目的
本文档用于回应本地清单 AI生图平台桶缓存落地对接清单.md,并结合当前项目的真实实现,给出一份可以直接用于和基础设施、资源域名、桶存储负责人对齐的项目侧答复。
本文只描述“当前项目已实现的事实”和“基于这些事实的建议”,不把尚未上线的理想方案写成现状。
2. 一句话结论
对本项目来说,只要 https://s3.jiansun.vip 继续作为统一对外资源主域名,并且入口服务器上的 180G 磁盘缓存只做“读缓存”而不改上传链路,那么项目应用层基本不需要改代码,就可以直接受益。
原因很简单:
- 项目当前所有图片类资源最终都走统一存储服务上传
- 对外 URL 由存储配置里的
publicUrl决定,而不是写死在业务代码里 - 项目默认就是“新内容新 key”,天然适合读缓存
- 当前没有依赖“对象覆盖后立刻强制失效”的核心链路
3. 当前项目真实存储链路
3.1 上传入口
项目中的图片上传与多数生图结果回存,都会走统一存储服务:
- 核心实现:
lib/storage/service.ts - 聊天上传接口:
app/(chat)/api/files/upload/route.ts
统一存储服务的优先级如下:
- 数据库中配置的默认 S3 兼容存储
- 备用桶故障切换配置
- 环境变量 S3
- Vercel Blob 兜底
也就是说,项目本身已经是“多存储后端兼容”的。
3.2 对外 URL 生成方式
当前项目上传成功后,对外图片 URL 的生成规则是:
- 如果存储配置里设置了
publicUrl- 返回:
publicUrl + /uploads/...
- 返回:
- 如果没有设置
publicUrl- 返回:
endpoint + /bucket + /uploads/...
- 返回:
因此,对项目来说真正关键的不是“桶后面用不用缓存”,而是:
- 当前默认存储配置中的
publicUrl是否统一指向https://s3.jiansun.vip
如果是,那么项目对外发给前端、消息、相册、画布、详情页的资源 URL,就会自然统一使用这个域名。
3.3 当前资源 key 规则
项目统一上传时,文件 key 采用:
uploads/{timestamp}-{random}.{ext}
特点:
- 路径前缀稳定:
/uploads/ - 文件名默认唯一
- 默认不会覆盖旧对象
这对读缓存非常友好,因为:
- 同一张新图天然是新 URL
- 缓存不会因为“同 URL 内容被覆盖”而频繁失真
4. 本项目实际会被缓存命中的资源范围
基于当前代码,最适合接入入口机磁盘读缓存的资源,主要是这些:
4.1 用户上传图片
来源:
- 聊天区上传
- 画布素材上传
- 局部编辑、修图、扩图等中间结果回存
特点:
- 统一进
uploads/... - 后续可能被多轮编辑、对话历史、画布再次引用
4.2 AI 生成结果图
来源:
- 聊天生图
- 编辑生成
- 扩图、增强、去水印、角度编辑等图像工作流
落库位置:
generatedImage.originalUrlgeneratedImage.thumbnailUrl
这些 URL 会被以下场景重复读取:
- 聊天消息回放
- 相册页
/gallery - 精选页
- 管理后台图片记录
- 无限画布节点
4.3 详情页生成相关图片
来源:
- AI详情主图
- AI详情追加评价晒图
- 详情历史归档封面图
特点:
- 一轮生成后可能被画布、存档、后续再次编辑反复读取
- 对重复访问更敏感,适合缓存
4.4 工作流中的中间结果图
如:
- 去背景结果
- 增强图
- 扩图结果
- 角度编辑结果
- 场景融合图
特点:
- 虽然是中间态,但在会话里会被持续回读
- 如果用户反复对比和继续编辑,也会产生热点访问
5. 对清单中关键问题的项目侧答复
5.1 关于“需要确认的资源范围”
基于项目实际情况,可以先明确:
当前最值得纳入缓存命中的路径前缀
首选:
/uploads/
原因:
- 当前统一上传服务默认就写入这个前缀
- 这是用户上传图、生成图、处理结果图最稳定的公共前缀
当前最可能成为热点的资源类型
- 会话中反复引用的参考图
- 相册中的生成结果图
- AI详情主图与评价晒图
- 画布中的历史结果图
- 编辑工作流中多轮引用的中间结果图
项目侧当前无法直接从代码给出的内容
项目代码里目前没有现成的“近 3 天 Top20 资源 URL 统计”接口。
所以如果基础设施侧需要:
- 近 3 天最常访问的 20 个资源 URL
- 主要热点路径前缀
建议直接从:
- Nginx access log
- 对象存储访问日志
- 资源域名层日志
做统计,而不是从业务数据库里推。
5.2 关于“是否统一只使用一个主资源域名”
项目建议结论
建议统一:
- 主用:
https://s3.jiansun.vip - 备用:
https://s3.yydd.ai
并且在项目的默认存储配置里:
publicUrl只配置成https://s3.jiansun.vip
为什么对本项目很重要
因为当前项目会把图片 URL 持久化到很多地方:
generatedImage- 消息内容 markdown
- media asset
- 画布数据
- AI详情归档
如果两个公网域名都长期作为默认资源入口使用,就会出现:
- 同一份资源在数据库中可能留下两套公网 URL
- 前端、相册、对话、画布里都可能混用不同域名
这会带来:
- 缓存命中分散
- 数据治理复杂
- 后续域名切换和清理成本变高
项目侧结论
对当前项目来说:
- 可以保留
https://s3.yydd.ai作为基础设施备用 - 但不建议把它配置成业务默认返回的资源 URL
5.3 关于“是否同 key 覆盖”
当前项目默认行为
默认不是同 key 覆盖,而是新内容新 key。
这是当前项目的真实实现。
统一上传时生成的路径形式为:
uploads/{timestamp}-{random}.{ext}
这意味着什么
对于缓存层来说,这其实是最理想的模式:
- 新图 = 新 URL
- 不需要依赖强制 purge
- 缓存旧对象不会污染新对象
需要注意的例外
如果未来有人在对象存储层手工做:
- 同路径覆盖
- 同 key 重写
那么缓存仍可能返回旧内容。
但就当前项目默认代码路径而言,这不是主流行为。
5.4 关于“时效要求”
当前项目的大多数图片链路
当前项目大多数图片资源都适合“读缓存优先”:
- 新图默认新 URL
- 会话、相册、画布大多是读取已经生成好的资源
- 不依赖“同 URL 秒级替换内容”
当前少数需要特别注意的情况
- 如果基础设施层后续做了“同 URL 覆盖”
- 会有缓存短时返回旧图的风险
- 如果资源域名切换
- 旧 URL 已经持久化在数据库和消息里,不能只改 DNS 口径,还要考虑历史数据
项目侧建议
只要遵守:
- 新内容新 key
- 主资源域名单一化
那么当前项目对缓存一致性的压力并不高。
5.5 关于“流量规模”
项目代码层能确定的事实
当前项目存在大量图片重复读取场景:
- 聊天消息回放
- 相册分页
- 画布节点回显
- AI详情历史存档
- 后续编辑再次读取旧图
项目代码层目前不能直接给出的事实
项目中没有现成的资源访问量级面板来回答:
- 峰值并发
- 每分钟请求数
- 热点 URL 排行
- 资源命中曲线
这类数据仍建议由入口网关、Nginx、对象存储日志侧统计。
项目侧判断
从业务形态上看,本项目非常适合读缓存,因为它是明显的“生成后被多次回看、回显、继续编辑”的产品,不是“一次下载后永不再读”的冷资源型系统。
5.6 关于“联调样本”
项目侧建议联调用下面 3 类真实资源:
- 用户上传原图
- 路径特征:
/uploads/... - 用于验证首次回源、二次命中
- AI 生成结果图
- 包括
originalUrl和thumbnailUrl - 用于验证相册、会话回放、画布回显的缓存效果
- AI详情主图或晒单图
- 文件通常更大、读取更频繁
- 用于验证长图场景的稳定性
项目本身可以提供测试资源 URL,但如果要验证“真实热点价值”,仍建议从线上真实访问日志中抽样。
5.7 关于“这次不需要改的内容”
结合项目现状,这次确实不需要先改这些内容:
- 不需要改业务接口域名
- 不需要先迁桶
- 不需要改聊天上传接口
- 不需要改 AI 生图主流程
- 不需要改画布或相册读取逻辑
前提条件只有一个:
- 当前默认存储配置中的
publicUrl继续统一返回主资源域名
6. 项目侧对“会不会有两个 URL”的明确答复
6.1 缓存本身不会制造第二个 URL
对本项目来说,只要缓存层放在:
https://s3.jiansun.vip
前面,且仍返回同一个公网地址,那么:
- 会话里看到的 URL 不变
- 相册里拿到的 URL 不变
- 数据库里保存的 URL 不变
- 只是入口服务器内部多了一份磁盘缓存
所以:
缓存本身不会让本项目出现第二个用户可见 URL。
6.2 真正会导致“双 URL”的是双域名并用
如果业务层长期同时把下面两个域名都写进数据库或消息:
https://s3.jiansun.vip/...https://s3.yydd.ai/...
那对本项目来说就真的是两套 URL 了。
这不仅影响缓存,也会影响:
- 相册聚合
- 画布历史复用
- 消息解析
- 存储迁移时的 URL 替换
因此项目侧建议非常明确:
s3.jiansun.vip作为唯一默认publicUrls3.yydd.ai只做备用访问入口,不写入业务默认配置
7. 项目里已有的相关能力,基础设施侧可以放心利用
7.1 多存储后端兼容 已具备
当前项目支持:
- S3 / MinIO / 阿里云 OSS 风格配置
- 默认存储
- 备用桶故障迁移
7.2 阿里云 OSS 入口桶 + 延迟转存 已具备
当前项目已有:
- 上传优先进入阿里云 OSS 的配置
- 到期后转存到目标默认桶
- 转存后自动替换数据库中的 URL
- 到期后清理源对象
这说明项目本身已经有“入口桶”和“最终落地桶”的概念。
但要注意
这套 OSS 转存能力和你们现在要做的 入口机读缓存 不是一回事:
- OSS 转存:属于存储生命周期管理
- 入口机缓存:属于读路径加速
两者可以并存,而且不会冲突。
7.3 对外资源路径稳定 已具备
当前绝大多数图片都落在:
/uploads/...
这很适合基础设施侧做:
- 路径维度的缓存策略
- 热点资源命中统计
- 单独限流和回源观测
7.4 Provider 读图适配 已具备部分能力
例如 Volcano Vision provider 中,已有把 publicUrl 形式的上传图 URL 重写成底层 endpoint/bucket 形式的逻辑,用于避免部分供应商抓取公开资源时失败。
这说明:
- 项目不是完全假设“所有供应商都直接从公网域名读图”
- 即便公网资源域名前面加了缓存,只要
publicUrl配置一致,当前系统仍然能工作
8. 当前项目对缓存落地的建议
8.1 项目侧推荐落地方式
建议基础设施侧这样落:
- 保持业务默认资源域名为
https://s3.jiansun.vip - 让
s3.jiansun.vip前挂入口服务器读缓存 - 缓存主要覆盖
/uploads/路径 - 不改上传链路,不改桶位置
- 不在业务配置中默认使用
https://s3.yydd.ai
8.2 项目侧推荐前置检查项
在正式切量前,建议先确认:
- 项目当前默认存储配置里的
publicUrl是否为https://s3.jiansun.vip - 历史数据库中是否已经混入了
s3.yydd.ai资源 URL - Nginx 缓存是否正确返回命中头,如
X-Cache-Status - 是否只缓存 GET 读流量,不介入写入逻辑
- 是否对超大文件和极低频资源设置合理淘汰策略
8.3 项目侧不建议的做法
- 不建议把两个公网资源域名同时作为业务默认入口
- 不建议让业务层开始复用同一个对象 key 覆盖新图
- 不建议把“入口读缓存”和“迁桶/改上传链路”绑定在同一个窗口一起做
9. 项目侧当前仍缺少的支持
虽然项目整体适配缓存没有问题,但如果后面要长期运营缓存层,当前项目还缺这些观测能力:
- 没有按资源 URL 维度的访问统计
- 没有热点资源排行榜
- 没有区分“上传成功量”和“资源读取量”的统一面板
- 没有面向缓存层的 purge / 失效控制接口
这些都不是这次缓存落地的阻塞项,但属于后续优化方向。
10. 最终答复口径
如果要给 AI 生图平台负责人一个简短的项目侧结论,可以直接用下面这段:
基于我们当前项目实现,入口服务器上的 180G 磁盘缓存可以直接作为
https://s3.jiansun.vip的读缓存使用,项目业务层基本不需要改造。因为我们当前图片资源统一经存储服务上传,对外 URL 由存储配置中的publicUrl决定,且默认采用uploads/{timestamp}-{random}.{ext}这种新内容新 key 的方式,天然适合缓存命中。对项目最关键的前提只有两个:
- 业务默认资源域名统一使用
https://s3.jiansun.vip;- 不要把
https://s3.yydd.ai同时作为默认业务资源域名写入数据库或消息。只要保持“主域名单一化 + 新内容新 key”,当前这套读缓存方案对我们的聊天生图、画布、相册、AI详情等链路都是正向收益,而且不会改变现有上传链路和真实桶位置。
11. 相关代码位置
如需进一步联调,可重点查看:
- 统一上传服务:
lib/storage/service.ts - 上传接口:
app/(chat)/api/files/upload/route.ts - OSS 转存任务:
lib/jobs/oss-image-migration-job.ts - OSS 转存 API:
app/api/jobs/migrate-oss-images/route.ts - 相册读取:
app/api/gallery/route.ts - 聊天图片落库:
app/(chat)/api/chat/route.ts - Volcano 读图 URL 改写:
lib/ai/providers/volcano-vision.ts