2014-04-10 17 views
1

我在我的應用程序中有很多數據表(即可隨時更新的數據表,但大多數時候它們顯示相同的數據)。使用Memcached實時數據表

有些表的背後都有相當密集的查詢,讓用戶每次回來一個頁面再次運行查詢,即使沒有新的更新。

這是當我想到Memcached的將是理想的加快爲我的用戶性能,但是我不確定如何實現這個,因爲我很新的高速緩存的想法。

我如何獲得MySQL告訴Memcached的導致一定的查詢已經改變,表不應該下​​次來自高速緩存加載它,而是來自於數據庫,因此更新緩存?另外,我認爲只更新表的數據對象更新會更好,但我不知道這個過程是什麼,如果有人有一些想法,他們可以分享我的使用情況下,將不勝感激。

+0

MySQL查詢緩存將已經緩存查詢的結果集。但是,只要表得到更新,緩存的結果集就會失效。所以,我想用Memcached緩存特定的結果集仍然是一個很好的用例。您是否正在使用可能具有使用Memcached的API的框架? – dcarrith

+0

如果您使用的是Laravel框架,那麼這個問題將很容易解決。一般來說,爲了回答你的問題,你需要使用每個用戶唯一的密鑰緩存一個特定的結果集(也許某些值與user_id連接)。如果某個特定用戶存在緩存記錄,則可以從緩存中加載。否則,您將運行查詢並緩存結果集。然後,對於負責更新主查詢中使用的任何表的任何頁面,您都可以通過使用基於user_id的唯一鍵來使緩存記錄無效。 – dcarrith

回答

0

這只是一個想法:我認爲你可以從MySQL獲取數據並將其保存到文件中。然後你可以直接使用這個文件而不是數據庫。爲了更新你的文件,你可以使用許多項目中使用的彗星方法,例如Facebook使用彗星進行通知。

1

也許這是一個選項,當有更新時記錄。所以你可以創建一個額外的表格,稱爲更新。它應該有兩列,優先級和日期時間。

刷新頁面每次,你檢查,通過MySQL的,如果一個特定的優先級,日期,時間已經改變。如果是這樣,您知道您需要更新該頁面上的數據。如果不是這樣,你對當前的數據沒有問題。

對於這項工作,當然,你將有更新的更新表,與每個數據庫的變化。這可以手動完成或通過mysql觸發器完成。

+0

一個好主意,但可能會變得複雜,因爲我有許多用戶使用我的系統。所以我只想在「屬於」用戶的行更改時發佈更新。 – imperium2335

+0

而不是一個類別,你可以使用一個用戶ID。所以每個用戶都有自己的更新時間。 – JJJ

+0

+1這是我最初的想法。前一段時間,我在NodeJS中嘗試了一些做同樣事情的東西。 – imperium2335

0

這裏有一個通用的答案,應該幫助你完成你想做什麼:

比方說,你有mainpage.php其中包含你擔心密集的查詢。這是假設你已經有了一個Memcached的對象單:

$m = new Memcached(); 
$m->addServer('localhost', 11211); 

某處mainpage.php,你會檢查基礎上,$user_id緩存結果集:

$data = null; 

if($cachedResultSet = $m->get('resultSet'.$user_id)) 
{ 
    $data = $cachedResultSet; 
} 
else 
{ 
    $data = run_intensive_query($user_id); 

    $m->set('resultSet'.$user_id, $data); 
} 

// Then you use $data as long as it's not null 

然後,每當MySQL表這是上述結果集的一部分得到更新後,您會想要使有關用戶的特定緩存記錄無效:

$m->delete('resultSet'.$user_id); 

這將確保下次加載mainpage.php時,「陳舊」resultSet將不再存在於緩存中,因此它將檢索新結果並適當緩存它們。

0

對於你的問題:

我如何獲得MySQL告訴Memcached的導致對某個查詢 已經改變,一個表不應來自緩存在下一次​​ 被加載,而是來了從數據庫中並因此更新 的緩存?

當數據更新(或等到它過期)時,您需要清除緩存。

Memcache是​​一個關鍵存儲...所以你需要一個唯一的鍵代表你試圖檢索的數據。

例如,假設您有與博客文章相關的查詢。一個唯一的ID將是你的帖子ID或它的頁面url/slug。

所以你通常做的是在做數據庫查詢之前,檢查Cache中是否有存儲的版本。

$memcache = new Memcache(); 
$memcache->connect('localhost', 11211) or die ("Could not connect"); 

$postId = 1234; // this would vary between each posts. 
$commentsKey = 'comments_'. $postId; 


$result = $memcache->get($commentsKey); 

if ($result === false) { // key not found 

    // only fetch when result are NOT in cache 
    $pdo = new PDO(); 
    $stmt = $pdo->query("SELECT * FROM comments WHERE postId=". $pdo->quote($postId)); 
    $result = $pdo->fetchAll(); 

    // store it for next time 
    $memcache->set($commentsKey, $result); 

} //if 

// use result either from cache or database 
foreach ($result as $comment) { 
    // do something with data 
} 

而且重置緩存(或無效的話),你可以清除評論鍵時,有人張貼新評論...

$memcache = new Memcache(); 
$memcache->connect('localhost', 11211) or die ("Could not connect"); 

$postId = 1234; // this would vary between each posts. 
$commentsKey = 'comments_'. $postId; 

$memcache->delete($commentsKey); 

// OR 

$memcache->set($commentsKey, false); 
這樣,下次用戶retreives評論將有

將其從數據庫中取出而不是緩存,因爲$ result將是錯誤的。