ThinkPhp緩存原理及使用詳解

做這個(gè)項(xiàng)目時(shí)躬窜,服務(wù)端最開(kāi)始是使用原生php寫的浇垦,在查詢數(shù)據(jù)庫(kù)時(shí),沒(méi)有做任何緩存荣挨,后來(lái)做到商城男韧,采用thinkphp框架,頁(yè)面加載突然提速了很多默垄,專門和做php的朋友交流了一下此虑,了解到thinkphp內(nèi)置緩存機(jī)制,無(wú)需從磁盤實(shí)時(shí)查詢mysql口锭,大多數(shù)時(shí)候從緩存(內(nèi)存)中讀取數(shù)據(jù)朦前。記錄如下:

原理

如果沒(méi)有緩存的網(wǎng)站是百萬(wàn)級(jí)或者千萬(wàn)級(jí)的訪問(wèn)量,會(huì)給數(shù)據(jù)庫(kù)或者服務(wù)器造成很大的壓力,通過(guò)緩存,大幅減少服務(wù)器和數(shù)據(jù)庫(kù)的負(fù)荷,假如我們把讀取數(shù)據(jù)的過(guò)程分為三個(gè)層,第一個(gè)是訪問(wèn)層,第一個(gè)是緩存層,第三個(gè)是數(shù)據(jù)庫(kù)存取層,如果沒(méi)有緩存層,訪問(wèn)層是直接從數(shù)據(jù)庫(kù)存取層讀取數(shù)據(jù),而設(shè)置緩存后,訪問(wèn)層不再是直接在數(shù)據(jù)庫(kù)存取層讀取,而是從緩存層讀取數(shù)據(jù).
我們做個(gè)簡(jiǎn)單的對(duì)比,假設(shè)一個(gè)頁(yè)面,在一個(gè)小時(shí)可被訪問(wèn)100萬(wàn)次,如果這個(gè)頁(yè)面每次被訪問(wèn)的時(shí)候,都直接讀取數(shù)據(jù)庫(kù)后再編譯生成,在一個(gè)小時(shí)內(nèi)將會(huì)重復(fù)性的生成100萬(wàn)次,而如果這個(gè)頁(yè)面被周期性的緩存10分鐘,也就是每間隔10分鐘緩存數(shù)據(jù)才會(huì)被生成一次,一個(gè)小時(shí)內(nèi)只會(huì)被生成6次,兩種方式一對(duì)比,效果明顯,兩種比較下服務(wù)器負(fù)荷的壓力比差別十幾萬(wàn)倍以上,緩存技術(shù)將使得網(wǎng)站負(fù)載在高峰期游刃有余.

緩存使用

ThinkPHP提供了方便的緩存方式介杆,包括數(shù)據(jù)緩存、靜態(tài)緩存和查詢緩存等韭寸,支持包括文件方式春哨、APC、Db恩伺、Memcache赴背、Shmop、Sqlite晶渠、Redis癞尚、Eaccelerator和Xcache在內(nèi)的動(dòng)態(tài)數(shù)據(jù)緩存類型,以及可定制的靜態(tài)緩存規(guī)則乱陡,并提供了快捷方法進(jìn)行存取操作浇揩。

數(shù)據(jù)緩存

  • Thinkphp緩存文件的配置
    Home是我建立的前臺(tái)項(xiàng)目,在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',//設(shè)置緩存方式為file       
  'DATA_CACHE_TIME'=>'600',//緩存周期600秒       
 );       
 ?>
  • Thinkphp緩存函數(shù)的使用
    在thinkphp中,使用快捷緩存函數(shù)S()進(jìn)行緩存,其用法如下:
S('data',$Data);//使用data標(biāo)識(shí)緩存$Data數(shù)據(jù)  
S('data',$Data,600);// 緩存$Data數(shù)據(jù)600秒  
 $Data = S('data');// 獲取緩存數(shù)據(jù)  
S('data',NULL);// 刪除緩存數(shù)據(jù)
  • 實(shí)例演示
<?php       
 // 本類由系統(tǒng)自動(dòng)生成,僅供測(cè)試用途       
  class IndexAction extends Action{       
    public function index(){       
        //如果有緩存憨颠,則讀取緩存數(shù)據(jù)       
        //如果沒(méi)有緩存胳徽,則讀取數(shù)據(jù)庫(kù)當(dāng)中的數(shù)據(jù)放入緩存       
        $lists=S('lists');                     
        if(emptyempty($lists)){                           
          $news=M('news');   
          $lists=$news->select();   
          S('lists',$lists,600);   
          echo '這是直接讀取數(shù)據(jù)庫(kù)的數(shù)據(jù)';       
           }   
        dump($list);  
 ?>

訪問(wèn)http://127.0.0.1/Home/index.php/Index/index
第一次訪問(wèn):

這是直接讀取數(shù)據(jù)庫(kù)的數(shù)據(jù)
array(10) {  
   [0] => array(12) {  
     ["id"] => string(1) "1"  
     ["catid"] => string(2) "13"  
     ["title"] => string(4) "thinkphp的緩存技術(shù)"  
     ["content"] => string(8) "thinkphp的緩存技術(shù)"  
     ["tags"] => string(4) "緩存"  
     ["thumb"] => string(0) ""  
     ["description"] => string(7) "thinkphp的緩存技術(shù)"  
     ["inputtime"] => string(10) "1348370202"  
     ["posid"] => string(1) "1"  
     ["ord"] => string(1) "2"  
     ["hits"] => string(1) "1"  
     ["status"] => string(1) "1"  
 }

第二次訪問(wèn):

array(10) {  
   [0] => array(12) {  
     ["id"] => string(1) "1"  
     ["catid"] => string(2) "13"  
     ["title"] => string(4) "thinkphp的緩存技術(shù)"  
     ["content"] => string(8) "thinkphp的緩存技術(shù)"  
     ["tags"] => string(4) "緩存"  
     ["thumb"] => string(0) ""  
     ["description"] => string(7) "thinkphp的緩存技術(shù)"  
     ["inputtime"] => string(10) "1348370202"  
     ["posid"] => string(1) "1"  
     ["ord"] => string(1) "2"  
     ["hits"] => string(1) "1"  
     ["status"] => string(1) "1"  
 }

說(shuō)明:第一次運(yùn)行時(shí),會(huì)打印出如上面所示信息,刷新一下頁(yè)面后,少了 “ 這是直接讀取數(shù)據(jù)庫(kù)的數(shù)據(jù)" ,說(shuō)明讀取的是先前生成的緩存數(shù)據(jù).

快速緩存

如果你僅僅是希望用文件的方式緩存一些簡(jiǎn)單的數(shù)據(jù)爽彤,并且沒(méi)有有效期的概念养盗,那么系統(tǒng)還提供了一個(gè)快速緩存方法F可以用來(lái)更快的操作。
快速緩存Data數(shù)據(jù)适篙,默認(rèn)保存在DATA_PATH目錄下面

F('data',$Data);

快速緩存Data數(shù)據(jù)往核,保存到指定的目錄

F('data',$Data,TEMP_PATH);

獲取緩存數(shù)據(jù)

$Data = F('data');

刪除緩存數(shù)據(jù)

F('data',NULL);

F方法支持自動(dòng)創(chuàng)建緩存子目錄,在DATA_PATH目錄下面緩存data數(shù)據(jù)嚷节,如果User子目錄不存在聂儒,則自動(dòng)創(chuàng)建:

F('User/data',$Data);

3.1.2版本開(kāi)始F方法支持使用通配符批量刪除功能,使用如下:

F('User/*',NULL);

表示刪除DATA_PATH.'User/'目錄下面的數(shù)據(jù)緩存硫痰。
系統(tǒng)內(nèi)置的數(shù)據(jù)字段信息緩存就是用了快速緩存機(jī)制衩婚。

查詢緩存

對(duì)于及時(shí)性要求不高的數(shù)據(jù)查詢,我們可以使用查詢緩存功能來(lái)提高性能效斑,而且無(wú)需自己使用緩存方法進(jìn)行緩存和獲取非春。
APP/config.php配置:

'DATA_CACHE_TIME'   => 60, // 數(shù)據(jù)緩存有效期 0表示永久緩存
'DATA_CACHE_TYPE'   => 'File',
 // 數(shù)據(jù)緩存類型,支持:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator
'DB_SQL_BUILD_CACHE' => true,
'DB_SQL_BUILD_LENGTH' => 20, // SQL緩存的隊(duì)列長(zhǎng)度
'DATA_CACHE_PATH' => TEMP_PATH,

查詢緩存功能支持所有的數(shù)據(jù)庫(kù),并且支持所有的緩存方式和有效期缓屠。
在使用查詢緩存的時(shí)候奇昙,只需要調(diào)用Model類的cache方法,例如:

$Model->cache(true)->select();

如果使用了cache(true) 敌完,則在查詢的同時(shí)會(huì)根據(jù)當(dāng)前的查詢SQL生成查詢緩存储耐,默認(rèn)情況下緩存方式采用DATA_CACHE_TYPE參數(shù)設(shè)置的緩存方式(系統(tǒng)默認(rèn)值為File表示采用文件方式緩存),緩存有效期是DATA_CACHE_TIME 參數(shù)設(shè)置的時(shí)間蠢挡,也可以單獨(dú)制定查詢緩存的緩存方式和有效期:

$Model->cache(true,60,'xcache')->select();

表示當(dāng)前查詢緩存的緩存方式為xcache弧岳,并且緩存有效期為60秒。
同樣的查詢业踏,如果沒(méi)有使用cache方法禽炬,則不會(huì)獲取或者生成任何緩存,即便是之前調(diào)用過(guò)Cache方法勤家。
查詢緩存只是供內(nèi)部調(diào)用腹尖,如果希望查詢緩存開(kāi)放給其他程序調(diào)用,可以指定查詢緩存的Key伐脖,例如:

$Model->cache('cache_name',60)->select();

則可以在外部通過(guò)S方法直接獲取查詢緩存的內(nèi)容热幔,

$value = S('cache_name');

除了select方法之外,查詢緩存還支持find和getField方法讼庇,以及他們的衍生方法(包括統(tǒng)計(jì)查詢和動(dòng)態(tài)查詢方法)绎巨。具體應(yīng)用的時(shí)候可以根據(jù)需要選擇緩存方式和緩存有效期。

SQL解析緩存

除了查詢緩存之外蠕啄,ThinkPHP還支持SQL解析緩存场勤,因?yàn)門hinkPHP的ORM機(jī)制,所有的SQL都是動(dòng)態(tài)生成的歼跟,然后由數(shù)據(jù)庫(kù)驅(qū)動(dòng)執(zhí)行和媳。
所以如果你的應(yīng)用有大量的SQL查詢需求,那么可以開(kāi)啟SQL解析緩存以減少SQL解析提高性能哈街。要開(kāi)啟SQL解析緩存留瞳,只需要設(shè)置:

'DB_SQL_BUILD_CACHE' => true,

即可開(kāi)啟數(shù)據(jù)庫(kù)查詢的SQL創(chuàng)建緩存,默認(rèn)緩存方式為文件方式骚秦,還可以支持xcache和apc方式緩存她倘,只需要設(shè)置:

'DB_SQL_BUILD_QUEUE' => 'xcache',

我們知道,一個(gè)項(xiàng)目的查詢SQL的量可能會(huì)非常巨大作箍,所以有必要設(shè)置下緩存的隊(duì)列長(zhǎng)度帝牡,例如,我們希望SQL解析緩存不超過(guò)20條記錄蒙揣,可以設(shè)置:

'DB_SQL_BUILD_LENGTH' => 20, // SQL緩存的隊(duì)列長(zhǎng)度

注意:只有查詢方法才支持SQL解析緩存

靜態(tài)緩存

要使用靜態(tài)緩存功能靶溜,需要開(kāi)啟HTML_CACHE_ON參數(shù),并且使用HTML_CACHE_RULES配置參數(shù)設(shè)置靜態(tài)緩存規(guī)則文件 懒震。

雖然也可以在應(yīng)用配置文件中定義靜態(tài)緩存規(guī)則罩息,但是建議是在模塊配置文件中為不同的模塊定義靜態(tài)緩存規(guī)則。

靜態(tài)規(guī)則定義

靜態(tài)規(guī)則的定義方式如下:

'HTML_CACHE_ON' => true, // 開(kāi)啟靜態(tài)緩存
'HTML_CACHE_TIME' => 60, // 全局靜態(tài)緩存有效期(秒)
'HTML_FILE_SUFFIX' => '.shtml', // 設(shè)置靜態(tài)緩存文件后綴
'HTML_CACHE_RULES' => array( // 定義靜態(tài)緩存規(guī)則
 // 定義格式1 數(shù)組方式
 '靜態(tài)地址' => array('靜態(tài)規(guī)則', '有效期', '附加規(guī)則'), 
 // 定義格式2 字符串方式
 '靜態(tài)地址' => '靜態(tài)規(guī)則', 
)

定義格式1采用數(shù)組方式 便于單獨(dú)為某個(gè)靜態(tài)規(guī)則設(shè)置不同的有效期个扰,定義格式2采用字符串方式訂閱靜態(tài)規(guī)則瓷炮,同時(shí)采用HTML_CACHE_TIME設(shè)置的全局靜態(tài)緩存有效期。

靜態(tài)緩存文件的根目錄在HTML_PATH定義的路徑下面递宅,并且只有定義了靜態(tài)規(guī)則的操作才會(huì)進(jìn)行靜態(tài)緩存娘香。 并且靜態(tài)緩存支持不同的存儲(chǔ)類型苍狰。 靜態(tài)緩存僅在GET請(qǐng)求下面有效。

靜態(tài)地址

靜態(tài)地址包括下面幾種定義格式:

  1. 第一種是定義全局的操作靜態(tài)規(guī)則烘绽,例如定義所有的read操作的靜態(tài)規(guī)則為:
'read'=>array('{id}',60)

其中淋昭,{id}
表示取$_GET['id']
為靜態(tài)緩存文件名,第二個(gè)參數(shù)表示緩存60秒安接。

  1. 第二種是定義全局的控制器靜態(tài)規(guī)則翔忽,例如定義所有的User控制器的靜態(tài)規(guī)則為:
'user:'=>array('User/{:action}_{id}','600')

其中,{:action}
表示當(dāng)前的操作名稱

  1. 第三種是定義某個(gè)控制器的操作的靜態(tài)規(guī)則盏檐,例如歇式,我們需要定義Blog控制器的read操作進(jìn)行靜態(tài)緩存
'blog:read'=>array('{id}',0)
  1. 第四種方式是定義全局的靜態(tài)緩存規(guī)則,這個(gè)屬于特殊情況下的使用胡野,任何模塊的操作都適用材失,例如
'*'=>array('{$_SERVER.REQUEST_URI|md5}'),

表示根據(jù)當(dāng)前的URL進(jìn)行緩存。

靜態(tài)規(guī)則

靜態(tài)規(guī)則是用于定義要生成的靜態(tài)文件的名稱硫豆,靜態(tài)規(guī)則的定義要確保不會(huì)沖突豺憔,寫法可以包括以下情況:

  1. 使用系統(tǒng)變量
    包括 _GET、_REQUEST够庙、_SERVER恭应、_SESSION、_COOKIE
    格式:
{$_×××|function}

例如:

{$_GET.name} 
{$_SERVER.REQUEST_URI|md5}
  1. 使用框架特定的變量
    {:module} 耘眨、{:controller} 和{:action}
    分別表示當(dāng)前模塊名昼榛、控制器名和操作名。
    例如:
{:module}/{:controller}_{:action}
  1. 使用_GET變量
    {var|function}也就是說(shuō) {id}其實(shí)等效于 {$_GET.id}

  2. 直接使用函數(shù)
    {|function} 例如:{|time}

  3. 支持混合定義
    例如我們可以定義一個(gè)靜態(tài)規(guī)則為:

'{id},{name|md5}' 

在{}之外的字符作為字符串對(duì)待剔难,如果包含有"/"胆屿,會(huì)自動(dòng)創(chuàng)建目錄。
例如偶宫,定義下面的靜態(tài)規(guī)則:

{:module}/{:action}_{id}

則會(huì)在靜態(tài)目錄下面創(chuàng)建模塊名稱的子目錄非迹,然后寫入操作名_id.shtml 文件。

靜態(tài)緩存有效期

單位為秒纯趋。如果不定義憎兽,則會(huì)獲取配置參數(shù)HTML_CACHE_TIME的設(shè)置值,如果定義為0則表示永久緩存吵冒。

附加規(guī)則

通常用于對(duì)靜態(tài)規(guī)則進(jìn)行函數(shù)運(yùn)算纯命,例如

'read'=>array('Think{id},{name}','60', 'md5') 

翻譯后的靜態(tài)規(guī)則是

md5('Think'.$_GET['id']. ', '.$_GET['name']);

https://zhidao.baidu.com/question/549987060.html
THINKPHP 怎么開(kāi)啟模版緩存

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痹栖,隨后出現(xiàn)的幾起案子亿汞,更是在濱河造成了極大的恐慌,老刑警劉巖揪阿,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疗我,死亡現(xiàn)場(chǎng)離奇詭異咆畏,居然都是意外死亡牡彻,警方通過(guò)查閱死者的電腦和手機(jī)践宴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)祭衩,“玉大人嚼摩,你說(shuō)我怎么就攤上這事】笫荩” “怎么了枕面?”我有些...
    開(kāi)封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)缚去。 經(jīng)常有香客問(wèn)我潮秘,道長(zhǎng),這世上最難降的妖魔是什么易结? 我笑而不...
    開(kāi)封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任枕荞,我火速辦了婚禮,結(jié)果婚禮上搞动,老公的妹妹穿的比我還像新娘躏精。我一直安慰自己,他們只是感情好鹦肿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布矗烛。 她就那樣靜靜地躺著,像睡著了一般箩溃。 火紅的嫁衣襯著肌膚如雪瞭吃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天涣旨,我揣著相機(jī)與錄音歪架,去河邊找鬼。 笑死霹陡,一個(gè)胖子當(dāng)著我的面吹牛和蚪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播烹棉,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惠呼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了峦耘?” 一聲冷哼從身側(cè)響起剔蹋,我...
    開(kāi)封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辅髓,沒(méi)想到半個(gè)月后泣崩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體少梁,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年矫付,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凯沪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡买优,死狀恐怖妨马,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杀赢,我是刑警寧澤烘跺,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站脂崔,受9級(jí)特大地震影響滤淳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砌左,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一脖咐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汇歹,春花似錦屁擅、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至取视,卻和暖如春硝皂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背作谭。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工稽物, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人折欠。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓贝或,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锐秦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咪奖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容