Skip to content

缓存机制(Preview Cache)

总体说明

为避免重复转换、降低磁盘与 CPU 消耗、提升预览响应速度,预览产品在整体架构中引入了基于 Redis 的统一缓存机制。

缓存贯穿 预览请求 → 转换 → 轮询 → 再次访问 的完整生命周期,是系统性能与稳定性的关键组成部分。

当前版本采用 RedisTemplate 手动控制缓存读写 的方式,实现了对缓存结构、TTL 和清理时机的精细化管理。

一、缓存配置概览(application.yml

1. Redis 连接与连接池配置(底层缓存载体)

yaml
spring:
  data:
    redis:
      host: localhost
      port: 6379
      password:
      database: 0
      timeout: 200ms
      lettuce:
        pool:
          max-active: 16
          max-idle: 8
          min-idle: 2
          max-wait: 200ms

设计要点:

  • 单次操作超时 200ms
    避免 Redis 异常导致请求线程被长时间阻塞。
  • 连接池限额控制
    在高并发轮询、批量缓存查询场景下,保证吞吐能力和稳定性。
  • 统一 RedisTemplate
    所有缓存读写通过统一模板完成,便于控制序列化和行为一致性。

2. 预览模块缓存配置(fileview.preview.cache

yaml
fileview:
  preview:
    cache:
      enabled: true
      default-ttl-hours: 24
      max-cache-size: 1000
      conversion:
        success-ttl: 86400      # 转换成功缓存(秒)
        failed-ttl: 60          # 转换失败缓存(秒)
      direct-preview-ttl: 86400 # 直接预览缓存(秒)

当前真正生效的配置项:

  • conversion.success-ttl
  • conversion.failed-ttl
  • direct-preview-ttl

其余字段说明:

  • enabled:设计为缓存总开关,当前版本尚未绑定逻辑
  • default-ttl-hours:设计为统一默认 TTL,当前版本未使用
  • max-cache-size:设计为缓存容量控制参数,当前版本依赖 Redis 自身内存策略

从产品角度看,这些字段属于前瞻性配置项,为后续版本扩展预留。

二、缓存 Key 设计规范

1. 统一 Key 命名策略

缓存 Key 由统一的 Key 管理器 生成,避免各模块自行拼接导致混乱。

典型规则包括:

  • 转换结果缓存:

    • convert:{fileId}:{targetFormat}
    • convert:{fileId}:{targetFormat}:result
  • 直接预览缓存:

    • preview:direct:{fileId}
  • 其他业务缓存:

    • 下载任务状态
    • EPUB 解压目录
    • 密码解锁状态
    • ETag / 临时标记等

2. 设计价值

  • Key 语义清晰,便于排查问题
  • 支持按 fileId 批量清理
  • 避免不同功能之间发生 Key 冲突

三、缓存数据模型与状态表达

1. 核心缓存对象:PreviewCacheInfo

缓存中保存的是完整的预览状态快照,而不是简单的 URL 字符串。

核心信息包括:

  • 文件元信息:
    • 文件名、路径、格式、大小
  • 预览结果:
    • previewUrl
    • 预览格式、预览文件大小
  • 状态信息:
    • SUCCESS / FAILED / IN_PROGRESS / PASSWORD_REQUIRED
    • DIRECT / CONVERT 模式
  • 安全信息:
    • 是否加密
    • 错误码 / 错误原因
  • 多页预览信息:
    • 是否多页
    • 总页数
    • 每页 URL 列表
  • 生命周期:
    • cachedAt
    • expiresAt

2. 设计价值

  • 缓存即“最终态描述”,前端无需再进行复杂推断
  • 适配直接预览、转换预览、多页预览等多种模式
  • 为长轮询、重复访问提供统一数据来源

四、TTL 策略与缓存写入规则

1. 转换成功缓存

  • TTL: conversion.success-ttl(默认 24 小时)
  • 行为:
    • 写入完整预览信息
    • 支持单页与多页文件
    • 多页场景下,第一页 URL 作为默认预览入口

产品意义:
成功结果可被长时间复用,大幅降低重复转换成本。

2. 转换失败缓存

  • TTL: conversion.failed-ttl(默认 60 秒)
  • 行为:
    • 仅短暂记录失败状态与错误原因
    • 到期后自动清理,允许重新尝试

产品意义:
避免“失败状态永久缓存”,提高系统自恢复能力。

3. 直接预览缓存(不经过转换)

  • TTL: direct-preview-ttl(默认 24 小时)

适用场景:

  • PDF
  • 图片
  • 可直接预览的非加密文件

产品意义:
对“无需转换”的文件提供与转换文件一致的缓存体验。

五、缓存清理与重算机制

系统支持多种主动清理策略:

1. 按文件清理

  • 清除指定 fileId 的所有缓存
  • 适用于文件更新、权限变更等场景

2. 错误状态清理

  • 当密码错误、密码过期、状态异常时
  • 强制清理缓存并重新处理

3. 直接预览清理

  • 用于密码校验失败、文件被撤回等场景

设计原则:

缓存是“加速器”,不是“状态锁死器”。

一旦安全条件或业务条件变化,允许重新计算,避免被缓存状态“锁死”。

六、缓存读取在预览流程中的位置

1. 预览请求的实际流程

  1. 请求进入预览接口
  2. 优先查询 Redis 缓存:
    • 直接预览缓存
    • 转换结果缓存
  3. 缓存命中:
    • 直接返回结果
    • 不再触发下载 / 转换 / MQ
  4. 缓存未命中或被清理:
    • 进入完整预览流程(下载 / 转换 / 长轮询)

2. 设计价值

  • 缓存命中路径完全短路后续逻辑
  • 大幅减少磁盘 IO、CPU 转换、MQ 消息数量
  • 是系统高性能运行的核心保障

七、小结

  • 预览产品采用 Redis 作为统一缓存中心,覆盖预览全流程
  • 缓存设计围绕 状态完整性、TTL 可控性、可清理性
  • 成功结果长缓存、失败结果短缓存,兼顾性能与纠错能力
  • 缓存命中可直接短路下载与转换流程

当前版本中,真正生效的缓存配置为:

  • conversion.success-ttl
  • conversion.failed-ttl
  • direct-preview-ttl