##1.24.1 論緩存的重要性
在很多情況下,我們都需要緩存。如對重復獲取但變化不大的數據進行緩存以提供服務器的響應能力,又如當需要為數據庫服務器減少QPS時等等。但同時緩存也因為有延時導致數據不能實時更新,或者在需要更新時不能被更新。如在接口調試、單元測試或者預覽時,但這些都可以通過一些技巧來獲得。這里,將從簡單的緩存、再到高速緩存、多級緩存逐步進行說明。
##1.24.2 簡單緩存
這里所指的簡單緩存,是指文件緩存。因為實現簡單,且部署方便。但其缺點也是明顯的,如文件I/O讀寫導致性能低,不能支持分布式。所以在沒有集群服務器下是適用的。
當需要使用文件緩存時,先對文件緩存進行DI注冊,便可使用。
```javascript
//$ vim ./Public/init.php
DI()->cache = new PhalApi_Cache_File(array('path' => API_ROOT . '/Runtime', 'prefix' => 'demo'));
// 設置
DI()->cache->set('thisYear', 2015, 600);
// 獲取
echo DI()->cache->get('thisYear');
// 刪除
DI()->cache->delete('thisYear');
```
##1.24.3 高速緩存
高速緩存通常具備分布式的能力,并能進駐內存,因此性能高。但同樣此優點所帶來的則是需要另外部署緩存擴展,如常見的Memcached、Redis。若需要考慮緩存落地,還要進一點篩選和配置。
如使用Memcached:
```javascript
DI()->cache = new PhalApi_Cache_Memcached(array('host' => '127.0.0.1', 'port' => 11211, 'prefix' => 'demo_'));
// 設置
DI()->cache->set('thisYear', 2015, 600);
// 獲取
echo DI()->cache->get('thisYear');
// 刪除
DI()->cache->delete('thisYear');
```
從上面示例代碼注意到,我們使用了前綴配置,以防同一臺MC服務器同一端口下key名沖突。當然,更好是使用配置文件來配置緩存的地址和端口,以及前綴。
##1.24.4 多級緩存
然而,很多時候,我們需要多級緩存來承載更大的訪問量。以便結合本地低速緩存和分布式高速緩存來獲得更好的用戶體驗和服務器吞吐率。這時,則可以使用多級緩存策略。
在切換到多級緩存時,我們明顯希望原有的代碼調用不需要同步調整便能獲得升級后的多級緩存,并且我們后臺開發人員也希望可以輕便在原有的單點緩存的基礎上進行擴展。所以這就引出了一個有趣的問題:我們該如何組織多級緩存?
作為一個框架,除了考慮上述的原有調用、單點緩存復用外,還需要考慮到多級緩存的組裝。部分框架,一如我最喜歡的Phalcon則是使用了配置的形式來實現。但仍然,我們需要了解其配置的各個格式要求才能更好掌握和使用,這點帶來了學習的成本。因此,PhalApi則是使用了簡單的組合模式來實現。
正如你在源代碼中看到的PhalApi_Cache_Multi類,通過此類的實例可以利用PhalApi_Cache_Multi::addCache()快速添加一個緩存節點,而節點的優先級則按開發同學添加的順序來確定。顯然在添加時,我們應該先添加分布式的高速緩存,再添加本地的低速緩存(希望不會有人先添加文件緩存再添加MC緩存)。而各個節點的初始化,則是我們之前所熟悉的。只是簡單添加即可。
以下是結合文件緩存和MC緩存的多級緩存示例:
```javascript
$cache = PhalApi_Cache_Multi();
$mcCache = new PhalApi_Cache_Memcached(array('host' => '127.0.0.1', 'port' => 11211, 'prefix' => 'demo_'));
$cache->addCache($mcCache);
$fileCache = new PhalApi_Cache_File(array('path' => API_ROOT . '/Runtime', 'prefix' => 'demo'));
$cache->addCache($fileCache);
DI()->cache = $cache;
```
然后,就可像之前那樣設置、獲取和刪除緩存,而不需考慮是單點緩存,還是多級緩存:
```javascript
// 設置
DI()->cache->set('thisYear', 2015, 600);
// 獲取
echo DI()->cache->get('thisYear');
// 刪除
DI()->cache->delete('thisYear');
```
##1.24.5 靜態結構圖
對應地,我們可以得出清晰明了的UML靜態結構圖:

結構層次非常簡單,但主要分為三大類:左邊是多級緩存;中間突出的是特殊情況,即:空對象模式下的空緩存;右邊是目前已提供或者后期擴展的具體緩存實現。
- 歡迎使用PhalApi!
- 接口,從簡單開始!
- [1.1]-下載與安裝
- [1.2]-創建一個自己的項目
- [1.3]-在線體驗
- [1.4]-文檔、幫助和官網
- [1.10]-對PhalApi框架的抉擇
- [1.11]-快速入門(backup)
- [1.12]-參數規則:接口參數規則配置
- [1.13]-統一的接口請求方式:_sevice=XXX.XXX
- [1.14]-統一的返回格式和結構:ret-data-msg
- [1.15]-數據庫操作:基于NotORM的使用及優化
- [1.16]-配置讀取:內外網環境配置的完美切換
- [1.17]-日記紀錄:簡化版的日記接口
- [1.18]-快速函數:人性化的關懷
- [1.19]-DI服務速查:各資源服務一覽表
- [1.20]-DB操作:數據庫基本操作速查
- [1.21]-類的自動加載:遵循PEAR包的命名規范
- [1.22]-簽名驗證:自定義簽名規則
- [1.23]-請求和響應:GET和POST兩者皆可得及超越JSON格式返回
- [1.24]-緩存策略:更靈活地可配置化的多級緩存
- [1.25]-國際化翻譯:為走向國際化提前做好翻譯準備
- [1.26]-數據安全:數據對稱加密方案
- [1.27]-精益開發:更富表現力的Model層和重量級數據獲取的應對方案
- [1.28]-COOKIE:對COOKIE原生態的支持及記憶加密升級版
- [1.29]-開放與封閉:多入口和統一初始化
- [1.30]-保持的力量:接口開發最佳實踐
- [1.31]-新型計劃任務:以接口形式實現的計劃任務
- [2.11]-核心思想:DI依賴注入-讓資源更可控
- [2.12]-海量數據:可配置的分庫分表
- [2.13]-接口調試:在線SQL語句查看與性能優化
- [2.14]-測試驅動開發:意圖導向編程下的接口開發
- [2.15]-演進:新型計劃任務續篇
- [2.16]-領域驅動設計:應對復雜領域業務的Domain層
- [2.17]-微服務:Api接口服務層
- [2.18]-定制化:資源服務的再實現
- [2.19]-擴展庫:可重用的擴展類庫
- [2.20]-約定編程:架構明顯的編程風格
- [2.21]-服務器統一部署方案簡明版:CentOs---Nginx---php-fpm---MySql-[--Memcached]
- [2.22]-更多工具:精益項目和團隊建設
- [3.1]-擴展類庫:微信開發
- [3.2]-擴展類庫:代理模式下phprpc協議的輕松支持
- [3.3]-擴展類庫:基于PHPMailer的郵件發送
- [3.4]-擴展類庫:優酷開放平臺接口調用
- [3.5]-擴展類庫:七牛云存儲接口調用
- [3.6]-擴展類庫:新型計劃任務
- [3.8]-擴展類庫:用戶、會話和第三方登錄集成
- [3.9]-擴展類庫:swoole支持下的長鏈接和異步任務實現
- [3.11]-擴展類庫:基于FastRoute的快速路由
- [4.2]-開發實戰2:模擬優酷開放平臺接口項目開發
- [4.3]-開發實戰3:一個簡單的小型項目開發(奔跑吧兄弟投票活動)
- [5.1]-架構與思想:PhalApi核心設計和思想解讀
- [5.2]-雜談:扯一些PhalApi的前世和今生
- [5.3]-框架總結:術語表和PHP開發建議
- [5.4]-許可
- [5.5]-聯系和加入我們
- [5.6]-更新日記
- [5.8]-致框架貢獻者:加入PhalApi開源指南
- [6.1]-基于接口查詢語言的SDK包
- [6.2]-SDK包(JAVA版)
- [6.3]-SDK包(PHP版)
- [6.4]-SDK包(Objective-C版)
- [6.5]-SDK包(javascript版)
- [6.6]-SDK包(Ruby版)
- [8.1]-PhalApi視頻教程
- 附錄1:接口文檔參考模板