使用 $settings['state_cache'] 加速 Drupal 后端
在我维护的一个大型 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 中,无需配置。您已经获得了收益。
简要清单
- 运行上面的 SQL 检查。
- 从
state
中修剪任何过大的值。 - 在 Drupal 10.3 到 10.x 中,添加
$settings['state_cache'] = TRUE;
并清除缓存。 - 确认管理页面上的查询次数减少,并观察数据库负载下降。
底线
一个小改动。为编辑带来显著的提升。启用它,测试,然后享受更流畅的管理页面。