返回博客

使用 $settings['state_cache'] 加速 Drupal 后端

2025-08-136 分钟阅读

在我维护的一个大型 Gov Drupal 站点上,/admin/reports/status/admin/config 速度很慢。启用 $settings['state_cache'] 后,页面加载速度大大加快。编辑们立刻就注意到了。

如果您的管理区域感觉缓慢,这可能会有所帮助。Drupal 在每次请求时会进行许多小的 State API 读取,缓存它们可以减少数据库往返。在 Drupal 10.3 中,您可以在 settings.php 中通过 $settings['state_cache'] = TRUE 来启用它。在 Drupal 11 中,state 缓存默认开启,该设置已被移除。如果您的站点在 State 中存储了大量大型项目,请先进行审查,然后再在 10.3 中启用它。

State API 存储的内容

Drupal 将站点特定的少量值存储在一个名为 state 的键值集合中。例如:上次 cron 时间、维护标志、核心和模块使用的辅助开关。没有缓存,每次读取都可能命中数据库。

为什么 state_cache 有帮助

管理屏幕会进行大量细微的检查。缓存这些值可以消除许多数据库调用。结果是页面加载更快,数据库负载更低。简单的更改,明显的收益。

可用性

  • Drupal 10.3+:通过 $settings['state_cache'] 选择加入。
  • Drupal 11+:默认开启;该设置已被移除。

工作原理

Drupal 加载一次值,将其存储在缓存中,并在后续请求中重用它。当值发生更改时,Drupal 会更新存储并使缓存条目失效。读取保持快速,数据保持正确。

在 Drupal 10.3+ 中启用

将此添加到 settings.php

$settings['state_cache'] = TRUE;

然后清除缓存。

启用前快速检查

如果您的站点在 state 中保留了过多或过大的值,缓存它们可能会浪费内存。运行此查询:

SELECT COUNT(*) AS num_items,
       SUM(LENGTH(value)) AS total_bytes
FROM key_value
WHERE collection = 'state';

您也可以使用 Drush 运行相同的命令:

drush sql:query "SELECT COUNT(*) AS num_items, SUM(LENGTH(value)) AS total_bytes FROM key_value WHERE collection = 'state';"

PostgreSQL:

drush sql:query "SELECT COUNT(*) AS num_items, SUM(OCTET_LENGTH(value)) AS total_bytes FROM key_value WHERE collection = 'state';"

经验法则:

  • num_items 高达约 100,total_bytes 约 100 KB 通常没问题。
  • 如果您看到大型 blob,请在启用前将其移至其他位置(缓存池、配置或自定义表)。

可以缓解的问题

  • 登录后管理页面缓慢
  • 编辑工作、批量运行或大量 cron 使用期间的高数据库负载
  • 共享数据库服务器上的延迟峰值

如果您的缓存后端是数据库

是的,它仍然有帮助。您将减少从 key_value 的读取次数。管理页面可能会加载得更快。但读取仍然会命中数据库,因此收益比 Redis 或 Memcached 小。现在启用它是安全的,并计划稍后迁移到内存缓存。

良好的搭配

  • 使用 Redis 或 Memcached 作为缓存存储,以便 state 的命中实时保存在内存中。在 settings.php 中检查您的缓存后端,并关注命中率。
  • 保持 state 小巧。将其用于标志和轻量级值,而不是大型 blob。
  • 先测量,后启用。在本地,尝试使用 Webprofiler 或 Devel 来比较查询次数。在生产环境中,使用您的 APM。

注意事项

  • 非常大的 state 值可能会导致缓存膨胀。先修复数据,然后启用。
  • 缓存清除不会删除 state 值;它们只会使缓存副本失效。
  • 在 Drupal 11 中,无需配置。您已经获得了收益。

简要清单

  1. 运行上面的 SQL 检查。
  2. state 中修剪任何过大的值。
  3. 在 Drupal 10.3 到 10.x 中,添加 $settings['state_cache'] = TRUE; 并清除缓存。
  4. 确认管理页面上的查询次数减少,并观察数据库负载下降。

底线

一个小改动。为编辑带来显著的提升。启用它,测试,然后享受更流畅的管理页面。