2016-03-03 103 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

这非常有帮助谢谢! –