WordPress multisite下Redis对象缓存管理:适配custom post types与REST API
解决方案:WordPress多站点Redis缓存精细化管控与一致性保障
一、通过WordPress钩子精细化控制缓存清理
1. 自定义文章类型(CPT)更新时的缓存失效
利用WordPress的save_post_{post_type}钩子,针对特定CPT的更新事件触发缓存清理。核心思路是给关联缓存条目归类到同一组,通过清理整个缓存组实现高效批量失效,同时支持单个缓存键的精准删除。
示例代码:
// 监听自定义文章类型 'product' 的保存事件 add_action('save_post_product', function($post_id, $post, $update) { // 跳过自动保存和修订版本,避免无效触发 if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) { return; } // 方案1:清理整个CPT相关的缓存组(高效批量失效) wp_cache_flush_group('product_cache_group'); // 方案2:精准删除单个条目(针对特定缓存键) wp_cache_delete('product_detail_' . $post_id, 'product_cache_group'); }, 10, 3);
2. REST API端点访问后的缓存失效
通过rest_request_after_callbacks钩子,在目标端点请求处理完成后,清理对应缓存。可通过判断请求路由精准定位目标端点。
示例代码:
// 监听REST API请求完成事件 add_action('rest_request_after_callbacks', function($response, $handler, $request) { // 匹配目标端点路由 if ($request->get_route() === '/my/v1/product-collection') { // 清理该端点对应的列表缓存 wp_cache_delete('product_collection_all', 'product_cache_group'); } return $response; }, 10, 3);
关键技巧:合理使用缓存分组
提前将关联缓存条目归类到同一组(比如product_cache_group),通过wp_cache_flush_group()实现批量失效,比逐个删除缓存键更高效,也更易维护。
二、保障多站点间的缓存一致性
1. 基础隔离与跨站点清理(适用于少量站点)
WordPress多站点默认会给缓存键添加博客ID前缀(如blog:1:product_detail_123),天然实现站点间缓存隔离。对于跨站点共享的内容,可通过switch_to_blog()切换站点后清理对应缓存。
示例代码:
// 当站点1的共享产品更新时,清理所有站点的相关缓存 add_action('save_post_product', function($post_id, $post, $update) { if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) { return; } // 获取所有站点ID $site_ids = get_sites(['fields' => 'ids']); foreach ($site_ids as $site_id) { switch_to_blog($site_id); wp_cache_flush_group('product_cache_group'); restore_current_blog(); } }, 10, 3);
2. Redis发布订阅(Pub/Sub)实时同步(适用于大规模站点)
当站点数量较多时,遍历站点清理缓存性能低下,可利用Redis的Pub/Sub功能实现实时缓存失效同步:
步骤1:每个站点订阅缓存失效频道
add_action('init', function() { // 复用Redis Object Cache插件的连接实例,避免重复连接 global $wp_redis; if (!$wp_redis instanceof Redis) { return; } // 订阅跨站点缓存失效频道 $wp_redis->subscribe(['multisite_cache_sync'], function($redis, $channel, $message) { $instruction = json_decode($message, true); if (isset($instruction['group'])) { wp_cache_flush_group($instruction['group']); } elseif (isset($instruction['key'])) { wp_cache_delete($instruction['key'], $instruction['group'] ?? ''); } }); }, 10);
步骤2:触发事件时发布失效指令
add_action('save_post_product', function($post_id, $post, $update) { if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) { return; } global $wp_redis; if (!$wp_redis instanceof Redis) { return; } // 发布缓存失效指令到同步频道 $message = json_encode([ 'group' => 'product_cache_group', 'action' => 'flush' ]); $wp_redis->publish('multisite_cache_sync', $message); // 同时清理当前站点缓存 wp_cache_flush_group('product_cache_group'); }, 10, 3);
3. 全局缓存组配置
如果存在跨站点共享的全局内容,可通过wp_cache_add_global_groups()将对应的缓存组设置为全局,所有站点共享同一组缓存,失效时只需清理一次全局组即可。
示例代码:
// 在wp-config.php或主题functions.php中添加 add_action('wp_cache_init', function() { wp_cache_add_global_groups(['global_product_group']); });
注意事项
- 避免在高频触发的钩子中执行重量级Redis操作,优先使用缓存组批量失效。
- 复用Redis Object Cache插件的连接实例(
global $wp_redis),减少连接开销。 - 测试环境验证缓存失效逻辑,避免出现缓存不更新或过度清理的问题。
内容的提问来源于stack exchange,提问作者Idris abou Mansour
相关产品推荐
相关产品推荐

