如何设计一个简单的页面缓存


How to design a simple page cache?

我想限制在特定时间段内生成页面的次数,但我甚至不确定如何解决这个问题。

以前,我已经通过调度要在cron作业中生成和保存的页面来解决类似的问题,但这不允许我动态地这样做。

这是一个场景:

我有n个用户创建的房间。我想构建一个JSONAPI,允许用户访问房间信息,以便在自己的页面上使用。然而,为每个请求生成一个新的JSON结果将非常低效,并给数据库服务器带来安全风险。我想限制它,以便x中的所有请求每次都使用相同的JSON结果,而不是新的结果。

一个简单的缓存系统可以像这样完成

 if (!file_exists($cacheFile) || filemtime($cacheFile) - time() > $cacheLifetime){
     //generate json and save to $cacheFile
 }
 header("Content-Type: application/json");
 header("Content-Length: ".filesize($cacheFile));
 readfile($cacheFile);

这个问题是缓存的典型用例。

一般算法是(当请求资源时):

if (resource is cached) {
    return cached contents
} else {
    construct the resource
    store resource in cache
    return the resource
}

如果你想实现基于时间的失效,算法变成:

if (resource is cached) {
    if (cached resource older than threshold) {
        remove resource from cache
    } else {
        return cached contents
    }
}
construct the resource
store resource in cache
return the resource

缓存内容的"年龄"是从该内容的创建日期开始计算的,您需要将其与缓存条目一起存储。

根据用户网站的动态程度,如果自上一代以来"没有任何变化",您可能还希望而不是重新生成JSON。你的算法会变成:

if (resource is cached) {
    if (cached resource older than threshold AND something changed) {
        remove resource from cache
    } else {
        return cached contents
    }
}
...

"什么都没有改变"的含义取决于您,可能是用户发布了新内容,也可能是更新了一些统计数据,或者是用于构建资源的任何内容。当此类事件发生时,在缓存上设置一个标志。

缓存可以采取任何形式:服务器上的平面文件、数据库行、会话变量等。

使用数据库缓存json字符串(不要忘记时间戳)。然后,您可以首先搜索数据库,并提供已经生成的JSON字符串:)