做這個項目時,服務端最開始是使用原生php寫的,在查詢數據庫時,沒有做任何緩存,後來做到商城,採用thinkphp框架,頁面加載突然提速了很多,專門和做php的朋友交流了一下,了解到thinkphp內置緩存機制,無需從磁盤實時查詢mysql,大多數時候從緩存(內存)中讀取數據。記錄如下:

原理

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

緩存使用

ThinkPHP提供了方便的緩存方式,包括數據緩存、靜態緩存和查詢緩存等,支持包括文件方式、APC、Db、Memcache、Shmop、Sqlite、Redis、Eaccelerator和Xcache在內的動態數據緩存類型,以及可定製的靜態緩存規則,並提供了快捷方法進行存取操作。

數據緩存

  • 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);  
    ?>

    訪問http://127.0.0.1/Home/index.php/Index/index,
    第一次訪問:

    這是直接讀取數據庫的數據
    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/’目錄下面的數據緩存。
系統內置的數據字段信息緩存就是用了快速緩存機制。

查詢緩存

對於及時性要求不高的數據查詢,我們可以使用查詢緩存功能來提高性能,而且無需自己使用緩存方法進行緩存和獲取。
查詢緩存功能支持所有的數據庫,並且支持所有的緩存方式和有效期。
在使用查詢緩存的時候,只需要調用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秒。

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

    其中,{:action}
    表示當前的操作名稱

  3. 第三種是定義某個控制器的操作的靜態規則,例如,我們需要定義Blog控制器的read操作進行靜態緩存
    'blog:read'=>array('{id}',0)
  4. 第四種方式是定義全局的靜態緩存規則,這個屬於特殊情況下的使用,任何模塊的操作都適用,例如
    '*'=>array('{$_SERVER.REQUEST_URI|md5}'),

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

靜態規則

靜態規則是用於定義要生成的靜態文件的名稱,靜態規則的定義要確保不會衝突,寫法可以包括以下情況:

  1. 使用系統變量
    包括 _GET、_REQUEST、_SERVER、_SESSION、_COOKIE
    格式:
    {$_×××|function}

    例如:

    {$_GET.name} 
    {$_SERVER.REQUEST_URI|md5}
  2. 使用框架特定的變量
    {:module} 、{:controller} 和{:action}
    分別表示當前模塊名、控制器名和操作名。
    例如:
    {:module}/{:controller}_{:action}
  3. 使用_GET變量
    {var|function}也就是說 {id}其實等效於 {$_GET.id}

  4. 直接使用函數
    {|function} 例如:{|time}

  5. 支持混合定義
    例如我們可以定義一個靜態規則為:

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