随着網絡的發展,資料越來越多,進而導緻運算壓力越來越大。為了解決這一問題,就需要合理配置設定資源,充分利用已有資源,緩存的工作實際就是資源的合理配置設定。
在web世界裡,理論上每層都可以被緩存。
- 底層的cpu緩存,磁盤檔案緩存。
- 應用層的虛拟機變量緩存,memcached緩存,apc基于位元組碼的緩存。
- 資料庫層table cache,thread cache,queary cache.
- servlet 容器層有apache緩存
命中率衡量緩存機制的好壞和效率。
一般來說命中率達到85%以上已經很高了,達到98%是理想狀态。
緩存更新政策
FIFO最先進緩存的資料在緩存空間不夠的情況下,會首先清理出來。
LFU最少使用元素會被清理掉。這要求緩存元素有Hit屬性,最小的先被清理掉。
LRU最近最少使用的元素被清理掉。緩存元素有個時間戳,最早的元素會被清理掉。
ThinkPHP提供了友善的緩存方式,包括資料緩存、靜态緩存和查詢緩存等,支援包括檔案方式、APC、Db、Memcache、Shmop、Sqlite、Redis、Eaccelerator和Xcache在内的動态資料緩存類型,以及可定制的靜态緩存規則,并提供了快捷方法進行存取操作。
檔案在 項目名/Home/runtime。隻要把runtime的檔案删除再在頁面重新整理就會出現新增的子產品。或者改配置,把緩存有效期的時間改成一秒。。。。配置在下面
/* 資料緩存設定 */
'DATA_CACHE_TIME' => 0, // 資料緩存有效期 0表示永久緩存
'DATA_CACHE_COMPRESS' => false, // 資料緩存是否壓縮緩存
'DATA_CACHE_CHECK' => false, // 資料緩存是否校驗緩存
'DATA_CACHE_TYPE' => 'File', // 資料緩存類型,支援:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator
'DATA_CACHE_PATH' => TEMP_PATH,// 緩存路徑設定 (僅對File方式緩存有效)
'DATA_CACHE_SUBDIR' => false, // 使用子目錄緩存 (自動根據緩存辨別的哈希建立子目錄)
'DATA_PATH_LEVEL' => 1, // 子目錄緩存級别
資料緩存
Thinkphp緩存檔案的配置
Home是我建立的前台項目,在Home\Conf\config.php找到緩存的配置檔案,配置如下
<?php
return array(
'DB_TYPE'=>'mysql',
'DB_HOST'=>'127.0.0.1',
'DB_NAME'=>'w3note',
'DB_USER'=>'root',
'DB_PWD'=>'123456',
'DB_PORT'=>'3306',
'DB_PREFIX'=>'w3_',
'DATA_CACHE_TYPE'=>'file',//設定緩存方式為file
'DATA_CACHE_TIME'=>'600',//緩存周期600秒
);
?>
複制
Thinkphp緩存函數的使用
在thinkphp中,使用快捷緩存函數S()進行緩存,其用法如下:
S('data',$Data);//使用data辨別緩存$Data資料
S('data',$Data,600);// 緩存$Data資料600秒
$Data = S('data');// 擷取緩存資料
S('data',NULL);// 删除緩存資料
複制
執行個體示範
<?php
// 本類由系統自動生成,僅供測試用途
class IndexAction extends Action{
public function index(){
//如果有緩存,則讀取緩存資料
//如果沒有緩存,則讀取資料庫當中的資料放入緩存
$lists=S('lists');
if(emptyempty($lists)){
$news=M('news');
$lists=$news->select();
S('lists',$lists,600);
echo '這是直接讀取資料庫的資料';
}
dump($list);
?>
複制
第一次通路
這是直接讀取資料庫的資料
array(10) {
[0] => array(12) {
["id"] => string(1) "1"
["catid"] => string(2) "13"
["title"] => string(4) "thinkphp的緩存技術"
["content"] => string(8) "thinkphp的緩存技術"
["tags"] => string(4) "緩存"
["thumb"] => string(0) ""
["description"] => string(7) "thinkphp的緩存技術"
["inputtime"] => string(10) "1348370202"
["posid"] => string(1) "1"
["ord"] => string(1) "2"
["hits"] => string(1) "1"
["status"] => string(1) "1"
複制
}
第二次通路
array(10) {
[0] => array(12) {
["id"] => string(1) "1"
["catid"] => string(2) "13"
["title"] => string(4) "thinkphp的緩存技術"
["content"] => string(8) "thinkphp的緩存技術"
["tags"] => string(4) "緩存"
["thumb"] => string(0) ""
["description"] => string(7) "thinkphp的緩存技術"
["inputtime"] => string(10) "1348370202"
["posid"] => string(1) "1"
["ord"] => string(1) "2"
["hits"] => string(1) "1"
["status"] => string(1) "1"
}
複制
說明:第一次運作時,會列印出如上面所示資訊,重新整理一下頁面後,少了 “ 這是直接讀取資料庫的資料" ,說明讀取的是先前生成的緩存資料.
快速緩存
如果你僅僅是希望用檔案的方式緩存一些簡單的資料,并且沒有有效期的概念,那麼系統還提供了一個快速緩存方法F可以用來更快的操作。
快速緩存Data資料,預設儲存在DATA_PATH目錄下面
F('data',$Data);
複制
快速緩存Data資料,儲存到指定的目錄
F('data',$Data,TEMP_PATH);
複制
擷取緩存資料
$Data = F('data');
複制
删除緩存資料
F('data',NULL);
複制
F方法支援自動建立緩存子目錄,在DATA_PATH目錄下面緩存data資料,如果User子目錄不存在,則自動建立:
F('User/data',$Data);
複制
3.1.2版本開始F方法支援使用通配符批量删除功能,使用如下:
F('User/*',NULL);
複制
表示删除DATA_PATH.'User/'目錄下面的資料緩存。
系統内置的資料字段資訊緩存就是用了快速緩存機制
查詢緩存
對于及時性要求不高的資料查詢,我們可以使用查詢緩存功能來提高性能,而且無需自己使用緩存方法進行緩存和擷取。
APP/config.php配置:
'DATA_CACHE_TIME' => 60, // 資料緩存有效期 0表示永久緩存
'DATA_CACHE_TYPE' => 'File',
// 資料緩存類型,支援:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator
'DB_SQL_BUILD_CACHE' => true,
'DB_SQL_BUILD_LENGTH' => 20, // SQL緩存的隊列長度
'DATA_CACHE_PATH' => TEMP_PATH,
複制
查詢緩存功能支援所有的資料庫,并且支援所有的緩存方式和有效期。
在使用查詢緩存的時候,隻需要調用Model類的cache方法,例如:
$Model->cache(true)->select();
複制
如果使用了cache(true) ,則在查詢的同時會根據目前的查詢SQL生成查詢緩存,預設情況下緩存方式采用DATA_CACHE_TYPE參數設定的緩存方式(系統預設值為File表示采用檔案方式緩存),緩存有效期是DATA_CACHE_TIME 參數設定的時間,也可以單獨制定查詢緩存的緩存方式和有效期:
$Model->cache(true,60,'xcache')->select();
複制
表示目前查詢緩存的緩存方式為xcache,并且緩存有效期為60秒。
同樣的查詢,如果沒有使用cache方法,則不會擷取或者生成任何緩存,即便是之前調用過Cache方法。
查詢緩存隻是供内部調用,如果希望查詢緩存開放給其他程式調用,可以指定查詢緩存的Key,例如:
$Model->cache('cache_name',60)->select();
複制
則可以在外部通過S方法直接擷取查詢緩存的内容,
$value = S('cache_name');
複制
除了select方法之外,查詢緩存還支援find和getField方法,以及他們的衍生方法(包括統計查詢和動态查詢方法)。具體應用的時候可以根據需要選擇緩存方式和緩存有效期。
SQL解析緩存
除了查詢緩存之外,ThinkPHP還支援SQL解析緩存,因為ThinkPHP的ORM機制,所有的SQL都是動态生成的,然後由資料庫驅動執行。
是以如果你的應用有大量的SQL查詢需求,那麼可以開啟SQL解析緩存以減少SQL解析提高性能。要開啟SQL解析緩存,隻需要設定:
'DB_SQL_BUILD_CACHE' => true,
複制
即可開啟資料庫查詢的SQL建立緩存,預設緩存方式為檔案方式,還可以支援xcache和apc方式緩存,隻需要設定:
'DB_SQL_BUILD_QUEUE' => 'xcache',
複制
我們知道,一個項目的查詢SQL的量可能會非常巨大,是以有必要設定下緩存的隊列長度,例如,我們希望SQL解析緩存不超過20條記錄,可以設定:
'DB_SQL_BUILD_LENGTH' => 20, // SQL緩存的隊列長度
複制
注意:隻有查詢方法才支援SQL解析緩存
靜态緩存
要使用靜态緩存功能,需要開啟HTML_CACHE_ON參數,并且使用HTML_CACHE_RULES配置參數設定靜态緩存規則檔案 。
雖然也可以在應用配置檔案中定義靜态緩存規則,但是建議是在子產品配置檔案中為不同的子產品定義靜态緩存規則。
靜态規則定義
靜态規則的定義方式如下:
'HTML_CACHE_ON' => true, // 開啟靜态緩存
'HTML_CACHE_TIME' => 60, // 全局靜态緩存有效期(秒)
'HTML_FILE_SUFFIX' => '.shtml', // 設定靜态緩存檔案字尾
'HTML_CACHE_RULES' => array( // 定義靜态緩存規則
// 定義格式1 數組方式
'靜态位址' => array('靜态規則', '有效期', '附加規則'),
// 定義格式2 字元串方式
'靜态位址' => '靜态規則',
)
複制
定義格式1采用數組方式 便于單獨為某個靜态規則設定不同的有效期,定義格式2采用字元串方式訂閱靜态規則,同時采用HTML_CACHE_TIME設定的全局靜态緩存有效期。
靜态緩存檔案的根目錄在HTML_PATH定義的路徑下面,并且隻有定義了靜态規則的操作才會進行靜态緩存。 并且靜态緩存支援不同的存儲類型。 靜态緩存僅在GET請求下面有效。
靜态位址
靜态位址包括下面幾種定義格式:
- 第一種是定義全局的操作靜态規則,例如定義所有的read操作的靜态規則為:
'read'=>array('{id}',60)
複制
其中,{id}
表示取$_GET['id']
為靜态緩存檔案名,第二個參數表示緩存60秒。
- 第二種是定義全局的控制器靜态規則,例如定義所有的User控制器的靜态規則為:
'user:'=>array('User/{:action}_{id}','600')
複制
其中,{:action}
表示目前的操作名稱
- 第三種是定義某個控制器的操作的靜态規則,例如,我們需要定義Blog控制器的read操作進行靜态緩存
'blog:read'=>array('{id}',0)
複制
- 第四種方式是定義全局的靜态緩存規則,這個屬于特殊情況下的使用,任何子產品的操作都适用,例如
'*'=>array('{$_SERVER.REQUEST_URI|md5}'),
複制
表示根據目前的URL進行緩存。
靜态規則
靜态規則是用于定義要生成的靜态檔案的名稱,靜态規則的定義要確定不會沖突,寫法可以包括以下情況:
-
使用系統變量
包括 _GET、_REQUEST、_SERVER、_SESSION、_COOKIE
格式:
{$_×××|function}
複制
例如:
{$_GET.name}
{$_SERVER.REQUEST_URI|md5}
複制
-
使用架構特定的變量
{:module} 、{:controller} 和{:action}
分别表示目前子產品名、控制器名和操作名。
例如:
{:module}/{:controller}_{:action}
複制
-
使用_GET變量
{var|function}也就是說 {id}其實等效于 {$_GET.id}
-
直接使用函數
{|function} 例如:{|time}
-
支援混合定義
例如我們可以定義一個靜态規則為:
'{id},{name|md5}'
複制
在{}之外的字元作為字元串對待,如果包含有"/",會自動建立目錄。
例如,定義下面的靜态規則:
{:module}/{:action}_{id}
複制
則會在靜态目錄下面建立子產品名稱的子目錄,然後寫入操作名_id.shtml 檔案。
靜态緩存有效期
機關為秒。如果不定義,則會擷取配置參數HTML_CACHE_TIME的設定值,如果定義為0則表示永久緩存。
附加規則
通常用于對靜态規則進行函數運算,例如
'read'=>array('Think{id},{name}','60', 'md5')
複制
翻譯後的靜态規則是
md5('Think'.$_GET['id']. ', '.$_GET['name']);
複制