Laravel - 通过频繁更新来缓存雄辩

时间:2014-09-19 14:37:19

标签: php caching laravel redis eloquent

是否可以对经常修改的对象使用缓存?例如,假设我们有一个BlogPost对象,并且有一个频繁更改的num_of_views列(以及其他列)。是否可以在缓存和数据库中更新num_of_views字段,而不会破坏缓存对象并重新创建它?我可以手动完成,但我担心同步问题。

3 个答案:

答案 0 :(得分:5)

是的,确实如此。我不知道你是如何做缓存的,但你可以随时替换缓存实例:

public function updatePost($post_id, $num_of_views)
{
    if (Cache::has('POST.'.$post_id))
    {
        $post = Cache::get('POST.'.$post_id);
    }
    else
    {
        $post = Post::find($post_id);
    }

    $post->num_of_views = $num_of_views;

    $post->save();

    Cache::put('POST.'.$post_id, $post);
}

答案 1 :(得分:2)

不,遗憾的是没有好办法。但让我解释一下......


但实际上有一个很好的理由 - 缓存的全部原因是加快服务某些静态数据的过程。例如,WikiPedia为您提供90%的服务,因为它有这么多用户。 WikiPedia文章很少改变,流行的文章就是说,缓存是一个很好的解决方案,可以减轻服务器的负担。

在您的情况下,您可能希望基本上每个请求修改缓存,您应该永远不会缓存视图计数,这意味着缓存功能实际上是无用的。即使每2个,3个甚至10个请求进行修改,缓存仍然有些无用,因为它不是缓存重新生成每个请求的目的,而是为了保持服务器的负载。

缓存请求实际上需要比常规实时服务请求更多的资源,因此您可以想象缓存此类可变数据不仅无用,而且对您的服务器也很有问题。


另一个问题是你建议只更改num_of_views但保持对象的其余部分不变,但你不能解释的是你实际上不能用Cache做到这一点。缓存工作的方式是它将你拥有的任何数据压缩成其他东西 - 它是一个简单的密钥&post -object_x'和一个值,通常是某种加密的字符串,如base64或其他。

这意味着num_of_views字段本身实际上并不存在于缓存本身中,除非您解密它然后再修改它并再次加密它,这与破坏和重新创建对象一样快速和资源密集。从纯粹的技术角度来看,这也是不可能的。


我希望你能明白为什么你的想法并没有完全解决,为什么除非你有一个拥有数十亿印象的大型网站,否则它在世界上最好不要缓存任何计数器 - 即使这样,你也应该只针对非常高的请求数而且只有很短的时间。

答案 2 :(得分:1)

有几种选择:

  1. 将高性能指标与数据库记录分开,并更新Php Model代码以反映这一点。实际上,你的“模型”,一个模型,将其setter和getter委托给其他BlogSlowData和BlogFastData模型(我忘记了这个模式的名称)。

  2. 您可以更改写入数据库的方式。因此,例如,当您更新记录时,将其弹出到队列中,该队列可以快速处理。我喜欢使用redis,写入队列到redis,然后另一个程序读取队列并将其写入数据库和缓存。

  3. 最后,也许是最糟糕的答案。您是否可以使用Redis的LUA代码将更新的指标写入数据库,或者如果您使用的是mysql,则可以使用http://dev.mysql.com/doc/refman/5.6/en/innodb-memcached.html内存缓存库将数据直接集成到数据库中。

  4. 你也可以组合使用1& 2,在redis中递增计数器,并将记录推入队列,表明BlogPost.id = 1234,需要$ view增加1。

    -daniel