SuperAPI AI 工具集

bitrix-caching

编程与开发

查看项目

更新于 10-15 09:02

技能介绍

用途

本技能面向 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 常量。