mcpField
B
bitrix-caching

bitrix-caching

github.com/bxmaximum开发47301 次安装2 周前更新
代码仓库

关于 bitrix-caching

bitrix-caching 是面向 Bitrix 开发者的缓存实践技能,介绍数据、托管、ORM、组件与整页缓存的 API 和失效方式。内容还涵盖缓存键设计、标签清理及引擎配置中的注意事项。

主要功能

  1. 01数据缓存与标签失效
  2. 02托管缓存及清理方法
  3. 03ORM 查询缓存配置
  4. 04组件结果缓存控制
  5. 05整页缓存与引擎配置指南

适用场景

  1. 01为 Bitrix 数据查询添加缓存
  2. 02在数据变更时按标签清理缓存
  3. 03设置组件缓存键与空结果处理
  4. 04排查缓存引擎配置或回退行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bxmaximum/bitrix-framework-skills --skill bitrix-caching

安装后在 Claude Code 中输入/bitrix-caching确认已加载。

详细介绍

缓存

基线:main 23.0+ · 已验证:main 26.800.0

级别API失效方式
数据缓存Data\Cache(initCache/startDataCache)TTL、cleanDir($dir)、标签
托管缓存Application::getInstance()->getManagedCache()clean() / cleanDir()
标签Application::getInstance()->getTaggedCache()clearByTag($tag)
ORM 查询缓存setCacheTtl() / 'cache' => ['ttl' => …]ORM 写入时自动失效(bitrix-orm)
组件结果$this->startResultCache()CACHE_TIME、标签、clearResultCache()
整个页面Compositebitrix-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' => …]]。
  • 未知的 type 字符串(拼写错误、大小写错误)会静默地表示“无缓存”,不会发出警告。自定义类缺失或引擎不可用(缺少扩展、服务器宕机)时,会回退到“无缓存”,且只发出 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 唯一。

评论

支持 Markdown