天天看點

緩存技術 2

随着網絡的發展,資料越來越多,進而導緻運算壓力越來越大。為了解決這一問題,就需要合理配置設定資源,充分利用已有資源,緩存的工作實際就是資源的合理配置設定。

在web世界裡,理論上每層都可以被緩存。

  1. 底層的cpu緩存,磁盤檔案緩存。
  2. 應用層的虛拟機變量緩存,memcached緩存,apc基于位元組碼的緩存。
  3. 資料庫層table cache,thread cache,queary cache.
  4. 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請求下面有效。

靜态位址

靜态位址包括下面幾種定義格式:

  1. 第一種是定義全局的操作靜态規則,例如定義所有的read操作的靜态規則為:
'read'=>array('{id}',60)           

複制

其中,{id}

表示取$_GET['id']

為靜态緩存檔案名,第二個參數表示緩存60秒。

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

複制

其中,{:action}

表示目前的操作名稱

  1. 第三種是定義某個控制器的操作的靜态規則,例如,我們需要定義Blog控制器的read操作進行靜态緩存
'blog:read'=>array('{id}',0)           

複制

  1. 第四種方式是定義全局的靜态緩存規則,這個屬于特殊情況下的使用,任何子產品的操作都适用,例如
'*'=>array('{$_SERVER.REQUEST_URI|md5}'),           

複制

表示根據目前的URL進行緩存。

靜态規則

靜态規則是用于定義要生成的靜态檔案的名稱,靜态規則的定義要確定不會沖突,寫法可以包括以下情況:

  1. 使用系統變量

    包括 _GET、_REQUEST、_SERVER、_SESSION、_COOKIE

    格式:

{$_×××|function}           

複制

例如:

{$_GET.name} 
{$_SERVER.REQUEST_URI|md5}           

複制

  1. 使用架構特定的變量

    {:module} 、{:controller} 和{:action}

    分别表示目前子產品名、控制器名和操作名。

    例如:

{:module}/{:controller}_{:action}           

複制

  1. 使用_GET變量

    {var|function}也就是說 {id}其實等效于 {$_GET.id}

  2. 直接使用函數

    {|function} 例如:{|time}

  3. 支援混合定義

    例如我們可以定義一個靜态規則為:

'{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']);           

複制