Stories

Detail Return Return

用裝飾器模式實現多層緩存:讓PHP應用更快更穩 - Stories Detail

為什麼要做多層緩存?

想象這樣一個場景:你的PHP應用每次訪問數據庫都要花1秒鐘,用户抱怨頁面加載太慢。這時候你會想到加緩存——但只用一層緩存夠嗎?

比如:

  • 內存緩存雖然快,但重啓服務數據就沒了
  • Redis緩存能持久化,但網絡請求也有開銷
  • 文件緩存最可靠,但磁盤讀寫速度有限

多層緩存的思路很簡單
把最快的緩存放在最前面,就像快遞櫃一樣——

  1. 優先從內存取(速度最快)
  2. 內存沒有再查Redis(速度中等)
  3. Redis沒有最後查文件或數據庫(速度最慢但最可靠)

這樣既能減少對慢速存儲的訪問,又能保證數據最終可用性


為什麼選擇裝飾器模式?

假設我們要實現這樣的調用鏈:
內存緩存 → Redis緩存 → 文件緩存 → 數據庫

如果用傳統繼承方式:

// 偽代碼:噩夢般的多層繼承
class MemoryThenRedisThenFileCache extends FileCache {
    // 要重寫所有方法...
}

裝飾器模式就像俄羅斯套娃:

// 真實使用示例:自由組合
$cache = new MemoryCache(
    new RedisCache(
        new FileCache(
            new DatabaseSource()
        ),
        [
            'host' => '127.0.0.1'
            'port' => 6379,
            'password' => null,
            'ttl' => 3600
        ]
    ),
    300
    1024
);

三大優勢

  1. 靈活組合:隨時換緩存順序,比如把Redis放最外層
  2. 代碼乾淨:每個類只關注自己的緩存邏輯
  3. 易於擴展:新增緩存類型只需寫一個新類

怎麼用?三行代碼搞定

該模塊已經在我PHP的常用工具庫中實現,可以通過composer集成到項目 點擊查看GitHub與文檔

可以通過該命令安裝: composer require hejunjie/tools

假設已經安裝了這個composer包:

use Hejunjie\Tools\Cache\Decorators;
// 1. 創建基礎數據源(比如數據庫查詢類)
$dbSource = new DatabaseSource();

// 2. 像套娃一樣包裹緩存層
$cache = new Decorators\MemoryCache(           // 第一層:內存
    new Decorators\RedisCache(                 // 第二層:Redis - 未安裝 redis 則去掉該層
        new Decorators\FileCache(              // 第三層:文件
            $dbSource,                            // 第四層:數據庫(用户自定義)
            '[文件]緩存文件夾路徑',
            '[文件]緩存時長(秒)'
        ),
        '[redis]配置'
        '[redis]前綴'
        '[redis]是否持久化鏈接'
    ),
    '[內存]緩存時長(秒)',
    '[內存]緩存數量(防止內存溢出)'
);

// 3. 無感知使用(自動走緩存鏈)
$data = $cache->get('user_123');    // 自動按 內存 → Redis → 文件 → 數據庫 順序查找,找到後立即返回不繼續向後調用;返回時根據查找順序倒序返回並自動存儲

$cache->set('user_123', '張三');    // 同時更新所有緩存層

實際效果對比

場景 無緩存 單層緩存 三層緩存
讀取速度 1.2s 0.3s 0.05ms
數據庫壓力 100% 30% \<5%
服務重啓後 正常 緩存失效 仍有文件緩存兜底

為什麼推薦這個設計?

  1. 像搭積木一樣簡單
    隨時增刪緩存層,比如臨時去掉Redis:

    $cache = new Decorators\MemoryCache(           // 第一層:內存
        new Decorators\FileCache(                  // 第二層:文件
            $dbSource,                                // 第三層:數據庫(用户自定義)
            '[文件]緩存文件夾路徑',
            '[文件]緩存時長(秒)'
        ),
        '[內存]緩存時長(秒)',
        '[內存]緩存數量(防止內存溢出)'
    );
  2. 安全有保障

    • 文件緩存自動加鎖防止衝突
    • Redis自動重連機制
    • 內存緩存限制最大條目數
  3. 看得見的效果
    內存緩存自帶統計面板:

    print_r($cache->getStats());
    /* 輸出:
    [
        'hits' => 2953,      // 命中次數
        'misses' => 47,      // 未命中次數
        'hit_rate' => 0.984, // 命中率98.4%
        'items' => 1024      // 當前緩存條目
    ]
    */

適合什麼場景?

  • 高頻讀取的數據(如商品信息)
  • 需要快速響應的API接口
  • 數據庫壓力大的系統
  • 希望服務重啓後快速恢復

總結

通過裝飾器模式實現多層緩存,就像給應用穿上了多層保暖衣:

  • 內層(內存) :最貼身,響應最快
  • 中層(Redis) :保持温度,持久化
  • 外層(文件) :防風防雪,絕對可靠

這種設計用簡單的代碼實現了靈活高效的緩存策略,下次當你遇到性能瓶頸時,不妨試試這種"套娃式"的解決方案吧!

user avatar feixiangdemojing Avatar flydehuli Avatar
Favorites 2 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.