Board logo

主題: [php] Cache (APC/Memcached) for PHP [打印本頁]

發表人: Vic    時間: 2011-3-17 11:08 PM     主題: Cache (APC/Memcached) for PHP

熊小最近在看有關一些大型網站如何運作的文章...發現有一些同通點。

1. Cache
-將資料存放於RAM...以減少db的查詢...比較常用的是memcached(user data cache, 支援跨主機)...APC(Opcode + user data cache, 不過只限同一主機)

2. NoSQL
-取代MySQL等Relational DB...(內容後補)

3. CDN
-Content Delivery Network...也就是用其他網絡供應商放置一些用戶存取的檔案...分散處理 (內容後補)


這次主要關於cache方面...雖然discuz有一些cache的功能...不過只限於file based...如要加快存取速度...以APC/memcached等memory cache效果更好。

論壇一直有用APC做Opcode caching...不過user data就沒試過。


本次目標是cache db query...以減少對db query的次數。

1. 安裝APC for pecl (最新的stable是3.1.6)
2. 查找論壇那些部份可以做caching
3. 利用apc_store / apc_fetch 來存取cache data

以下一條discuz常見的query

引用:
$query = $db->query("SELECT * FROM {$tablepre}threads t WHERE tid='$tid' AND displayorder>='0'");
$var = $db->fetch_array($query);


修改成APC版..用一個簡單function,  加到include/global.func.php

引用:
function query_cache($sql,$ttl=86400) {
        if ($sql == '')
                return null;

        global $db;
        $iKey = md5($sql);
        if (!$cached_res = apc_fetch($iKey)) {
                $query = $db->query($sql);
                while($this_res = $db->fetch_array($query)) {
                        $cached_res[]        =        $this_res;
                }
                apc_store($iKey, $cached_res,$ttl);
        return $cached_res;
}


本來的code改成:

引用:
$sql = "SELECT * FROM {$tablepre}threads t WHERE tid='$tid' AND displayorder>='0'"
$var = query_cache($sql);



結果 (as of 2011-03-17)

減少query數如下
index.php - 1
forumdisplay.php - 3
viewthread.php - 3

問題:

1. cache何時refresh
-當forumdisplay被cache後...新增主題/回覆不會顯示...因為它們不存在於cache內...這時必須刪除舊cache而重新query db以得到新cache...但因為apc_delete不支援prefix/suffix刪除...md5後的key變得難以單一刪除...現在的做法是當有新增文章/回覆時...刪除全部cache...方法不是很好...不過暫時沒想到更好的.

2. discuz內query最多的是common.inc.php內有關memeber...與viewthread.php有關post...不過2者太多..(每個member, 每個post都是一個獨立query)...cache效果不大。
發表人: dayi    時間: 2011-3-18 10:07 AM

我的做法是另外開一個memory table
這個table記錄每個實體db table最後被異動的時間
有一支db的trigger會自動去檢查,然後把異動時間寫到memory table裡

然後在需要用到cache的程式裡會記錄cache最後更新的時間
再用這個時間和memory table裡的時間做比對
時間有更新時才會重下query

不過我的系統架構算是比較特殊的
在web上可能不太適用
只是提供一個參考的方向
發表人: charleshwu    時間: 2011-8-15 10:10 PM

想加速web server的執行, 建議可以參考以下兩本書,
Steve Souders, Even Faster Web Sites:Performance Best Practices for Web Developers Oreilly, (2009.06.18) 0596522304

Steve Souders, High Performance Web Sites:Essential Knowledge for Front-End Engineers Oreilly, (2007.09.11)  0596529309

分享一下我的經驗, 假如某個 SQL Query 常被執行, 其對應的資料自然就會被 cache 進記憶體裡.
確定各SQL 的Access Plan是合適的, 有正確的 index 即可.




歡迎光臨 TWed2k (http://twed2k.org/) Powered by Discuz! 4.1.0