2016-03-03 107 views
0

因此,我將Redis添加到項目中,並且正在使用緩存調用來封裝數據庫調用。防止Redis密鑰驅逐策略

如果我有一個模型,這樣的查詢(和模型簡單地將數據返回到控制器):

"SELECT * FROM countries"; 

我的計劃是緩存每個國家在這樣的數據結構:

$cache->hmset("country:1", ['id' => 1, name => 'Ireland']);// 250+ more countries 

而且也維護國家ID的一組數據結構,像這樣:

$cache->sadd("countries", 1); 

問題

在檢索所有國家的情況下,我是否需要編寫邏輯來填充兩個redis數據結構中的任何一個都不在緩存中? 例如,應我的國家模式是這樣的:

// Check cache for set of valid countries IDs 
    if (!$cache->exists("countries")) { 
     $ids = "SELECT id FROM countries";// Pretend $ids is array for simplicity 

     // Add countries IDs into cache 
     $cache->sadd("countries", $ids); 
    } 

    /* At this point we know the set of country IDs exists */ 

    $country_ids = $cache->smembers("countries"); 

    $response = []; 

    /* Retrieve each country */ 
    foreach ($country_ids as $id) { 
     /* If "countries:{$id}" is not in cache */ 
     if (!$cache->exists("countries:{$id}")) {// Retrieve country from database 
      $entity = "SELECT * FROM countries WHERE countries.id = {$id}";// Pretend $entity is array of fields for simplicity 

      // Set country entity into cache 
      $cache->hset("countries:{$id}", $entity); 
     } else { 
      $entity = $cache->hgetall("countries:{$id}"); 
     } 

     $response[] = $entity; 
    } 

    return $response; 

UPDATE

的國家表只是樣本數據,但表示正在讀取和寫入定期任何表。緩存必須始終表示存儲在數據庫中的內容,因此當我們插入新實體或更新現有實體時,我們也會更新緩存。 緩存中還存儲了多個其他密鑰和用戶數據,並且可能存在高速緩存清除某些密鑰的情況,並且某些對高速緩存的請求可能導致找不到任何內容。

我的問題是:你如何保證有望在緩存中找到的數據多數民衆贊成或者是: A)在高速緩存中找到,或 B)在高速緩存中找不到的,所以我們把它放在緩存

是否每個請求以從緩存中要求我們運行一個數據庫查詢檢索我們的數據庫中的數據,然後把它放到緩存中,如在上面的例子中所概述的東西嗎?

+0

你的問題不清楚給我。答案取決於你的「國家」SET的目的。請提供更多信息 – thepirat000

+0

@ thepirat000感謝您的反饋。我已經更新了這個問題。這是否回答你的問題? –

回答

1

您需要考慮它否則,請使用cache-aside pattern並具有從緩存中檢索/插入獲取操作的邏輯。

看到這個psedo碼爲例(對不起,我不熟悉PHP):

function GetCountry($id) 
{ 
    if ($cache->hexists("countries:{$id}")) { 
     $entity = $cache->hgetall("countries:{$id}"); 
    } 
    else 
    { 
     $entity = $database.GetCountry($id); 
     $cache->hmset("country:{$id}", ['id' => $entity->id, ... ]); 
    } 
    return $entity; 
} 

function AddCountry($country) 
{ 
    $database.AddCountry($country); 
} 

function UpdateCountry($id, $data) 
{ 
    $database.UpdateCountry($id, $data); 
    $cache->del("country:{$id}"); 
} 

function DeleteCountry($id) 
{ 
    $database.DeleteCountry($id); 
    $cache->del("country:{$id}"); 
} 

所以你永遠不會更新緩存,你只需要添加到緩存中,當對象被檢索這是第一次,並且在更新/刪除實體之後使密鑰無效。

+1

這非常有幫助謝謝! –