該文是wecenter學習筆記的一部分
Cache的實現(xiàn)原理
wecenter支持兩種緩存
- Memcached
- File
基于Zend_Cache實現(xiàn)的文件緩存機制。
system/core/cache.php
$this->cache_factory = Zend_Cache::factory($this->frontendName, $this->backendName, $this->frontendOptions, $this->backendOptions);
讀緩存
$result = $this->cache_factory->load($this->cachePrefix . $key);
寫緩存
$result = $this->cache_factory->save($value, $this->cachePrefix . $key, array(), $lifetime);
刪除緩存
return $this->cache_factory->remove($key);
清理緩存
return $this->cache_factory->clean(Zend_Cache::CLEANING_MODE_ALL);
Zend Cache
為了方便使用,Zend Cache根據(jù)緩存的數(shù)據(jù)類型構(gòu)造了各種 FrontCache,并根據(jù)存儲類型引入了BackendCache的概念。
** Frontend **
-
Capture
Capture能將php的start和flush之間的輸出緩存起來,內(nèi)部通過ob_start注冊的output_callback來將php的緩沖內(nèi)容存儲到緩存中。
Zend/Cache/Frontend/Capture.php#start
ob_start(array($this, '_flush')); ob_implicit_flush(false);通過調(diào)用
ob_flush來刷新緩沖區(qū) -
Page
捕獲輸出的部分內(nèi)容
-
Output
使用方式
// if it is a cache miss, output buffering is triggered if (! $cache->start('mypage')) { // output everything as usual echo 'Hello world! '; echo 'This is cached ('.time().') '; $cache->end(); // output buffering ends } echo 'This is never cached ('.time().').'; -
Class
通過重寫__call,代理目標對象的函數(shù)調(diào)用,并將函數(shù)調(diào)用結(jié)果緩存起來。
public function __call($name, $parameters) { $callback = array($this->_cachedEntity, $name); if (!is_callable($callback, false)) { Zend_Cache::throwException('Invalid callback'); } $cacheBool1 = $this->_specificOptions['cache_by_default']; $cacheBool2 = in_array($name, $this->_specificOptions['cached_methods']); $cacheBool3 = in_array($name, $this->_specificOptions['non_cached_methods']); $cache = (($cacheBool1 || $cacheBool2) && (!$cacheBool3)); if (!$cache) { // We do not have not cache return call_user_func_array($callback, $parameters); } $id = $this->makeId($name, $parameters); if (($rs = $this->load($id)) && (array_key_exists(0, $rs)) && (array_key_exists(1, $rs)) ) { // A cache is available $output = $rs[0]; $return = $rs[1]; } else { // A cache is not available (or not valid for this frontend) ob_start(); ob_implicit_flush(false); try { $return = call_user_func_array($callback, $parameters); $output = ob_get_clean(); $data = array($output, $return); $this->save( $data, $id, $this->_tags, $this->_specificLifetime, $this->_priority ); } catch (Exception $e) { ob_end_clean(); throw $e; } } echo $output; return $return; } -
Function
緩存函數(shù)調(diào)用的結(jié)果
function call($callback, array $parameters = array(), $tags = array(), $specificLifetime = false, $priority = 8)調(diào)用這個函數(shù),會跟進函數(shù)名稱和參數(shù)生成緩存主鍵,如果緩存有效,則直接返回緩存結(jié)果,否則調(diào)用函數(shù)并進行緩存,與classs的__call實現(xiàn)基本一致。
-
File
根據(jù)文件的修改狀態(tài)來判斷緩存是否有效。
** Backend **
需要符合基本的接口
Zend/Cache/Backend/Interface.php
public function setDirectives($directives);
public function load($id, $doNotTestCacheValidity = false);
public function test($id);
public function save($data, $id, $tags = array(), $specificLifetime = false);
public function remove($id);
public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array());
-
File
基于文件系統(tǒng)的緩存。
每個緩存除了生存緩存文件外,還會生出一個文件名以
internal-metadatas---開頭的元數(shù)據(jù)文件,并依靠元數(shù)據(jù)文件來存儲數(shù)據(jù)的基本信息:Zend/Cache/Backend/File.php#touch
'hash' => $metadatas['hash'], 'mtime' => time(), 'expire' => $metadatas['expire'] + $extraLifetime, 'tags' => $metadatas['tags'] -
Sqlite
將數(shù)據(jù)和元數(shù)據(jù)存儲到sqlite中
Zend/Cache/Backend/Sqlite.php#_buildStructure
private function _buildStructure() { $this->_query('DROP INDEX tag_id_index'); $this->_query('DROP INDEX tag_name_index'); $this->_query('DROP INDEX cache_id_expire_index'); $this->_query('DROP TABLE version'); $this->_query('DROP TABLE cache'); $this->_query('DROP TABLE tag'); $this->_query('CREATE TABLE version (num INTEGER PRIMARY KEY)'); $this->_query('CREATE TABLE cache (id TEXT PRIMARY KEY, content BLOB, lastModified INTEGER, expire INTEGER)'); $this->_query('CREATE TABLE tag (name TEXT, id TEXT)'); $this->_query('CREATE INDEX tag_id_index ON tag(id)'); $this->_query('CREATE INDEX tag_name_index ON tag(name)'); $this->_query('CREATE INDEX cache_id_expire_index ON cache(id, expire)'); $this->_query('INSERT INTO version (num) VALUES (1)'); }顧名思義,cache存儲緩存數(shù)據(jù),tag存儲標簽, version存儲緩存的版本號。
每次執(zhí)行操作之前都會調(diào)用
_checkAndBuildStructure檢查是否需要構(gòu)建表結(jié)構(gòu)
-
memcached
依賴
Memcache客戶端來提供服務。 -
libmemcached
依賴
Memcached來提供服務 -
xcache
來自于lightd團隊的開源緩存服務器
Apc
BlackHole
Static
TwoLevels
-
WinCache
wincache僅支持NTS(非線程安全版本)的PHP
ZendServer Disk
ZendServer Share memeory
ZendPlatform
涉及的緩存服務太多,不能一一探究。
插件機制 ←o→ 配置參數(shù)管理