用途
本技能面向 Bitrix 框架的缓存实现,帮助开发者在不同层级上正确使用缓存 API,并处理缓存失效问题。基线版本为 main 23.0+,已验证版本为 main 26.800.0。
主要能力
技能按层级与失效方式组织,涵盖以下缓存类型:
- 数据缓存(Data cache):使用
Data\Cache(initCache/startDataCache),失效方式为 TTL、cleanDir($dir)、标签。 - 托管缓存(Managed cache):使用
Application::getInstance()->getManagedCache(),失效方式为clean()/cleanDir()。 - 标签(Tags):使用
Application::getInstance()->getTaggedCache(),失效方式为clearByTag($tag)。 - ORM 查询缓存:使用
setCacheTtl()或'cache' => ['ttl' => …],在 ORM 写入时自动失效(bitrix-orm)。 - 组件结果缓存(Component result):使用
$this->startResultCache(),失效方式为CACHE_TIME、标签、clearResultCache()。 - 整页缓存(Whole page):Composite,参见 bitrix-performance。
缓存引擎配置
在 .settings.php 中配置缓存引擎:
'cache' => [
'value' => [
'type' => 'redis', // files | redis | memcached | memcache | apcu
'redis' => ['host' => '127.0.0.1', 'port' => 6379],
'serializer' => \Redis::SERIALIZER_IGBINARY,
'sid' => 'site1', // key prefix: unique per site copy on a shared server
],
'readonly' => false,
],
'cache_flags' => [ // separate top-level section
'value' => [
'config_options' => 3600, // b_option cache TTL
'vendor_module_post_max_ttl' => 600, // ORM TTL clamp per table (0 disables)
],
],
自定义引擎:'type' => ['class_name' => MyEngine::class, 'extension' => 'redis']。多服务器:'servers' => [['host' => …, 'port' => …]]。
注意:未知的类型字符串(拼写错误、大小写错误)会静默地表示“无缓存”,且不会有警告。自定义类缺失或引擎不可用(无扩展、服务器宕机)会回退到“无缓存”,仅产生一个 E_USER_WARNING。
使用方式
数据缓存 + 标签
use Bitrix\Main\Application;
use Bitrix\Main\Data\Cache;
$cache = Cache::createInstance();
$cacheDir = '/vendor_blog/posts';
$cacheId = 'list_' . md5(serialize([$filter, LANGUAGE_ID]));
if ($cache->initCache(3600, $cacheId, $cacheDir))
{
$data = $cache->getVars();
}
elseif ($cache->startDataCache())
{
$tagged = Application::getInstance()->getTaggedCache();
$tagged->startTagCache($cacheDir); // same dir as the data cache
$data = PostTable::query()->setSelect(['ID', 'TITLE'])->setFilter($filter)->fetchAll();
if ($data === [])
{
$tagged->abortTagCache();
$cache->abortDataCache();
}
else
{
$tagged->registerTag('vendor_blog_posts');
$tagged->endTagCache();
$cache->endDataCache($data);
}
}
Application::getInstance()->getTaggedCache()->clearByTag('vendor_blog_posts'); // in the write path / ORM OnAfter* handler
clearByTag() 会删除该标签下注册的所有缓存目录,因此标签数据缓存应使用各自的 $cacheDir。
缓存键应包含所有会改变结果的输入(过滤器、语言、站点、用户组)。切勿在缓存块内读取 $_SESSION/$USER 而不将其纳入键中。
标签是自定义名称。不存在自动的 ORM_<TABLE> 标签;ORM 缓存位于托管缓存目录 orm_<table> 中,并通过 XxxTable::cleanCache() 清除。
托管缓存
$managed = Application::getInstance()->getManagedCache();
if ($managed->read(86400, 'rates', 'vendor_rates'))
{
$rates = $managed->get('rates');
}
else
{
$rates = $this->loadRates();
$managed->set('rates', $rates); // setImmediate() writes now, set() at the end of the hit
}
$managed->cleanDir('vendor_rates');
对于未先 read() 的 id,set()/setImmediate() 是空操作。
组件缓存
if ($this->startResultCache(false, [$userGroupsKey])) // CACHE_TIME from params; extra key parts
{
$this->arResult['ITEMS'] = $this->loadItems();
if (!$this->arResult['ITEMS'])
{
$this->abortResultCache();
}
else
{
Application::getInstance()->getTaggedCache()->registerTag('vendor_blog_posts');
}
$this->setResultCacheKeys(['TITLE']); // arResult keys kept for component_epilog.php
$this->includeComponentTemplate();
}
参数:CACHE_TYPE(A 跟随全局开关,Y,N)、CACHE_TIME。缓存键已包含站点、语言、模板、所有参数以及用户时区偏移;CACHE_GROUPS 仅是一种约定:需自行将用户组加入额外键。
仅当定义了 BX_COMP_MANAGED_CACHE 时,组件才会为其缓存路径打开标签作用域。
检查清单
- 缓存键覆盖所有输入;空/错误结果调用
abort*Cache()。 - 每个标签都在改变数据的代码路径中被清除。
- 标签作用域使用与数据缓存相同的目录。
- 原始 SQL 写入后通过
cleanCache()清除 ORM 缓存。 - 生产环境使用 Redis/Memcached,
sid在共享服务器上每个站点副本唯一。
适用场景与限制
适用于 Bitrix 框架中的缓存实现与失效管理,包括数据缓存、托管缓存、标签缓存、ORM 查询缓存、组件结果缓存以及缓存引擎配置。限制方面:未知缓存类型会静默回退为无缓存;自定义类缺失或引擎不可用仅产生 E_USER_WARNING;标签需自行注册与清除,无自动 ORM 标签;组件标签作用域依赖 BX_COMP_MANAGED_CACHE 常量。