doctrine 查询缓存和结果缓存需在 symfony 7.0 中分层配置:元数据与查询缓存共用 doctrine.system_cache_pool,结果缓存必须使用独立池(如 doctrine.result_cache_pool)并设置 default_lifetime,否则永不过期。

Doctrine 查询缓存和结果缓存怎么配
Symfony 7.0 中 Doctrine 的缓存不是“打开数据库缓存”这种笼统操作,而是分层启用:元数据缓存(metadata)、查询缓存(query)、结果缓存(result)。三者默认都不启用,必须显式配置,且都依赖 Symfony 的 cache.adapter 驱动。
核心原则是:元数据和查询缓存建议用 cache.adapter.redis_tag_aware(或 cache.adapter.php_files 仅限开发),结果缓存必须独立配置池并指定 TTL,否则缓存永不过期。
-
metadata_cache_driver和query_cache_driver推荐共用doctrine.system_cache_pool,该池可复用、轻量,适合存储小而稳定的结构化数据 -
result_cache_driver必须指向单独池(如doctrine.result_cache_pool),便于设置default_lifetime控制查询结果过期时间 - 若未配置
result_cache_pool的default_lifetime,缓存将永久存在,极易导致脏数据
cache.yaml 里怎么写 Redis 缓存池
Doctrine 缓存池必须在 framework.cache.pools 下定义,并与 Doctrine 配置中的 pool 值严格匹配。不能只写 adapter,漏掉 default_lifetime 或拼错池名会导致静默降级为无缓存。
示例(生产环境):
framework:
cache:
pools:
doctrine.system_cache_pool:
adapter: cache.adapter.redis_tag_aware
default_lifetime: 3600
doctrine.result_cache_pool:
adapter: cache.adapter.redis_tag_aware
default_lifetime: 1800
注意点:
-
cache.adapter.redis_tag_aware是 Symfony 7+ 推荐的适配器,支持按标签批量清除,比cache.adapter.redis更适合 Doctrine 场景 -
default_redis_provider必须已配置(如redis://localhost:6379),否则池初始化失败,Doctrine 会 fallback 到空实现 - 本地开发若没 Redis,可用
cache.adapter.php_files替代,但需确保sys_get_temp_dir()可写,且不能用于高并发测试
Doctrine ORM 配置里怎么引用缓存池
Doctrine 层的缓存开关在 doctrine.orm 下,靠 type: pool + pool: xxx 绑定到上一步定义的池。配置位置通常是 config/packages/doctrine.yaml。
关键字段不能缩写或省略:
-
metadata_cache_driver:必须设为{ type: 'pool', pool: 'doctrine.system_cache_pool' } -
query_cache_driver:同样用doctrine.system_cache_pool,避免重复建池 -
result_cache_driver:必须设为{ type: 'pool', pool: 'doctrine.result_cache_pool' },且该池的default_lifetime才真正生效
完整片段:
doctrine:
orm:
auto_generate_proxy_classes: false
metadata_cache_driver:
type: pool
pool: doctrine.system_cache_pool
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool
缓存没生效?检查这三处硬伤
Doctrine 缓存不生效最常见原因不是配置错,而是运行时条件不满足:
- APP_ENV 不是
prod或debug为true:Doctrine 在 debug 模式下强制禁用所有缓存,哪怕配置全对也白搭 - 实体类用了
@Cache(usage="NONSTRICT_READ_WRITE")等注解但没启用二级缓存:该功能需额外开启second_level_cache,且 Symfony 官方不推荐,容易引发一致性问题 - 查询中含动态参数(如
new \DateTime()、$user->getId())或未绑定参数:Doctrine 要求查询语句完全一致才命中查询缓存;结果缓存则要求参数值序列化后完全相同
验证是否生效:开 Web Profiler,看 “Doctrine” 面板里的 “Cache hits/misses”,或者直接查 Redis —— KEYS "doctrine*" 应有对应前缀的键存在。











