You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal 9.4.5视图使用Redis(仅数据存储区)时的意外缓存失效问题

解决Drupal 9视图因自动递增字段更新导致全局缓存失效的问题

核心问题分析

Drupal默认会在实体字段更新时,触发该实体对应的缓存标签失效。而视图通常会聚合所有显示实体的缓存标签,所以单个实体的字段更新会导致整个视图的缓存被清除,同时忽略预设的TTL配置。

具体解决方案

1. 优化视图缓存粒度

  • 进入视图编辑页面,找到高级 > 缓存设置,将缓存模式从"基于查询的缓存"改为**"基于每个结果的缓存"**。这样视图会为每一行单独缓存,单个字段更新只会失效对应行的缓存,而非整个视图。
  • 配置缓存上下文(如user、url.path等)时,只保留必要的上下文,避免过度缓存细分影响性能。

2. 自定义字段的缓存行为

创建自定义模块,实现hook_entity_field_update(),拦截字段更新时的缓存标签失效操作:

/**
 * Implements hook_entity_field_update().
 */
function mymodule_entity_field_update(\Drupal\Core\Entity\FieldableEntityInterface $entity, \Drupal\Core\Field\FieldDefinitionInterface $field_definition) {
  // 仅针对你的自动递增字段(替换为实际字段名)
  if ($field_definition->getName() === 'field_increment_counter') {
    // 移除默认的实体缓存标签失效操作
    \Drupal::service('cache_tags.invalidator')->clearTags($entity->getCacheTagsToInvalidate());
    // 可选:仅失效该字段相关的自定义缓存标签,而非整个实体
    \Drupal::service('cache_tags.invalidator')->clearTags(['entity:' . $entity->getEntityTypeId() . ':' . $entity->id() . ':field_increment_counter']);
  }
}

之后需要确保视图的缓存不再依赖该实体的全局缓存标签,而是使用上述自定义的字段级缓存标签。

3. 修改实体的缓存标签生成逻辑

通过hook_entity_type_alter()调整实体的缓存标签,让自动递增字段的更新不影响实体的全局缓存标签:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(array &$entity_types) {
  if (isset($entity_types['node'])) { // 替换为你的实体类型,如node/user等
    $entity_types['node']->setCacheTagsCallback(function(\Drupal\Core\Entity\EntityInterface $entity) {
      // 移除默认的实体缓存标签,或仅保留不包含该字段的标签集合
      $tags = $entity->getCacheTags();
      // 过滤掉可能导致视图缓存失效的标签,或自定义标签
      $tags = array_filter($tags, function($tag) {
        return strpos($tag, 'node:') !== 0; // 示例:移除实体全局标签
      });
      return $tags;
    });
  }
}

注意:此方法需谨慎使用,避免影响其他依赖实体缓存标签的功能。

4. 调整Redis缓存的TTL与分段

在settings.php中为视图缓存单独配置TTL,确保即使缓存被触发失效,也能优先使用TTL过期而非强制清除:

$settings['cache']['bins']['views'] = [
  'default_ttl' => 3600, // 1小时TTL
  'backend' => 'cache.backend.redis',
];

同时,结合视图的缓存键细分,比如在视图的缓存设置中添加自定义缓存键,让不同行的缓存键唯一,避免全局失效。

注意事项

  • 测试所有修改,确保其他依赖缓存标签的功能(如实体详情页、块等)不受影响。
  • 自定义模块需遵循Drupal的编码规范,避免破坏核心缓存逻辑。

内容的提问来源于stack exchange,提问作者user118258

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 21:33:20