首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Yii2 快取機制完整指南:檔案快取、Redis、多級快取、依賴關係、標籤失效

     編輯:PHP 相關知識

Yii2 Cache 核心組件深度解析:配置、驅動選型、進階模式、效能調優、常見陷阱

快取是高效能 Web 應用核心。Yii2 提供統一 yii\caching\Cache 介面,支援檔案、資料庫、Memcached、Redis、APC、WinCache、XCache、Zend Data Cache 等多種驅動。本文系統講解配置、基本操作、依賴關係、標籤失效、多級快取、分片策略。

快取組件配置

// common/config/main.php
'components' => [
    // 檔案快取 (開發/小型專案)
    'cache' => [
        'class' => 'yii\caching\FileCache',
        'cachePath' => '@runtime/cache', // 預設
        'keyPrefix' => 'myapp_',
        'gcProbability' => 10, // GC 機率
    ],
    
    // Redis 快取 (生產推薦)
    'cache' => [
        'class' => 'yii\redis\Cache',
        'redis' => 'redis', // 參考 redis 組件
        'keyPrefix' => 'myapp:cache:',
        'defaultDuration' => 3600,
        'serializer' => [ // 自定義序列化
            'serialize' => 'igbinary_serialize',
            'unserialize' => 'igbinary_unserialize',
        ],
    ],
    
    // 多級快取 (L1: APCu 記憶體, L2: Redis 分散式)
    'cache' => [
        'class' => 'yii\caching\MultiCache',
        'caches' => [
            'l1' => ['class' => 'yii\caching\ApcCache'],
            'l2' => ['class' => 'yii\redis\Cache', 'redis' => 'redis'],
        ],
        // 讀取: L1 → L2,寫入: 同時寫入 L1+L2
    ],
],

// Redis 連線配置
'redis' => [
    'class' => 'yii\redis\Connection',
    'hostname' => '127.0.0.1',
    'port' => 6379,
    'database' => 0,
    'password' => env('REDIS_PASSWORD'),
    'retries' => 3,
    'retryInterval' => 100,
],

基本操作 API

$cache = Yii::$app->cache;

// 設定 (自動序列化)
$cache->set('key', $data, 3600); // 1小時
$cache->set('key', $data, 0);    // 永久 (視驅動)

// 獲取
$data = $cache->get('key'); // false = 不存在/過期

// 多鍵獲取
$values = $cache->getMultiple(['key1', 'key2', 'key3']);

// 存在檢查
$exists = $cache->exists('key');

// 刪除
$cache->delete('key');
$cache->deleteMultiple(['key1', 'key2']);

// 清空
$cache->flush(); // 謹慎使用

// 原子操作 (Redis/APCu 支援)
$cache->add('key', $value, 3600); // 僅不存在時設定
$cache->increment('counter', 1);  // 原子遞增
$cache->decrement('counter', 1);  // 原子遞減

快取依賴 (Cache Dependency) - 智能失效核心

use yii\caching\DbDependency;
use yii\caching\ExpressionDependency;
use yii\caching\FileDependency;
use yii\caching\TagDependency;

// 1. DB 依賴:查詢結果變化時失效
$dependency = new DbDependency([
    'sql' => 'SELECT MAX(updated_at) FROM post WHERE status=1',
]);
$cache->set('posts_list', $posts, 3600, $dependency);

// 2. 表達式依賴:任意 PHP 表達式
$dependency = new ExpressionDependency([
    'expression' => 'return Yii::$app->params["site_version"];',
]);
$cache->set('config', $config, 0, $dependency);

// 3. 檔案依賴:檔案修改時間變化
$dependency = new FileDependency([
    'fileName' => '@app/config/params.php',
]);
$cache->set('settings', $settings, 0, $dependency);

// 4. 標籤依賴:批量失效 (需驅動支援 TagDependency)
TagDependency::invalidate(Yii::$app->cache, 'user_profile'); // 使所有 'user_profile' 標籤失效
$cache->set('user_123', $profile, 3600, new TagDependency(['tags' => ['user_profile', 'user_123']]));
$cache->set('user_123_posts', $posts, 3600, new TagDependency(['tags' => ['user_123']]));

標籤失效實戰模式

// Service 層封裝
class PostService {
    private $cache;
    
    public function getPostList(array $params): array {
        $key = 'post_list_' . md5(json_encode($params));
        return $this->cache->getOrSet($key, function() use ($params) {
            return Post::find()->where($params)->all();
        }, 3600, new TagDependency(['tags' => ['post_list', 'post']]));
    }
    
    public function updatePost(int $id, array $data): bool {
        $result = Post::updateAll($data, ['id' => $id]);
        if ($result) {
            // 使相關快取失效
            TagDependency::invalidate($this->cache, 'post');
            TagDependency::invalidate($this->cache, 'post_list');
            TagDependency::invalidate($this->cache, "post_$id");
        }
        return $result;
    }
}

快取碎片 (Fragment Caching) - 視圖層級

<?php if ($this->beginCache('sidebar_' . $user->id, [
    'duration' => 3600,
    'dependency' => new TagDependency(['tags' => ['user_sidebar', "user_{$user->id}"]]),
    'variations' => [Yii::$app->language], // 按語言區分
])): ?>
    <div class="sidebar">
        <h3>用戶面板</h3>
        <?= $this->render('_profile', ['user' => $user]) ?>
        <?= $this->render('_recent_posts', ['user' => $user]) ?>
    </div>
<?php $this->endCache(); endif; ?>

HTTP 快取 (Response Cache) - 整頁快取

// 控制器行為
public function behaviors() {
    return [
        'httpCache' => [
            'class' => 'yii\filters\HttpCache',
            'only' => ['index', 'view'],
            'lastModified' => function ($action, $params) {
                return Post::find()->max('updated_at');
            },
            'etagSeed' => function ($action, $params) {
                return Post::find()->select('id,updated_at')->asArray()->all();
            },
            'cacheControlHeader' => 'public, max-age=3600',
        ],
    ];
}

驅動選型與效能對比

驅動儲存介質分散式TTL 支援標籤支援適用場景
FileCache磁碟否是否開發、單機小型
DbCache資料庫是是否已有 DB、無 Redis
ApcCache共享記憶體否是否單機高速 L1
MemCache記憶體是是否傳統分散式
Redis Cache記憶體+持久化是是是 (yii\redis\Cache)生產首選
MultiCache混合視 L2是視 L2多級架構

序列化優化

  • 預設 PHP serialize:通用但慢、體積大
  • igbinary:二進位、快 2-3 倍、體積小 30-50% (需擴展)
  • msgpack:跨語言、極快、體積最小
  • 配置:'serializer' => ['serialize' => 'igbinary_serialize', 'unserialize' => 'igbinary_unserialize']

常見陷阱與最佳實踐

陷阱後果解決
快取 Key 衝突資料錯亂keyPrefix + 業務前綴 + 參數雜湊
永久快取無失效機制髒資料永存必加 Dependency 或 TagDependency
大物件未分片網路/記憶體壓力拆分小 Key、或壓縮 (gzip/lz4)
熱 Key 未保護穿透/雪崩互斥鎖重建、隨機過期時間、熔斷
開發環境未關閉快取改代碼不生效ENV 區分、或 force_compile 模式

監控指標

  • Hit Rate = hits / (hits + misses) > 90% 為佳
  • Memory Usage / Eviction Rate
  • Avg Latency (get/set) < 1ms (Redis 本地)
  • Key Count / Expired Keys/sec

善用 Yii2 統一快取介面、依賴關係自動失效、標籤批量清理、多級架構,能將資料庫查詢降低 80%+,回應時間壓縮至 50ms 以內。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved