1

这个问题的标题可能令人困惑,但问题很简单。

我使用 Zend_Cache 和 memcached 作为后端。我有两个模块,分别称为“最新文章”和“热门文章”。这两个模块都在每个页面上,并使用类似的查询,例如:

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\

到目前为止,我的表有 150 万行。我在上一个查询中使用的每个字段都有索引。我将最近的文章缓存 1 小时,将热门文章缓存 4 小时。我有 4 个 Web 服务器(php5/apache2)和 1 个数据库服务器(mysql)。表引擎是 innoDB。

这个问题有时我的缓存在重负载中过期,这使得我的网站不可用,直到这些模块再次被缓存。我可以有一个新的 MYSQL 服务器。

但是有没有办法以更智能的方式处理缓存?例如,服务器 1 将尝试刷新缓存,而服务器 2,3 和 4 仍将使用缓存中的相同值。

我可以编写一些代码来做到这一点,但我想知道是否有办法直接用 Zend_Cache 做到这一点?如果有一种设计模式可以应用于我的问题?

[编辑] 我想要可以扩展到 100 台服务器的东西

4

4 回答 4

1

那是您正在执行的实际查询吗?

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\

也许不是搜索高级缓存解决方案,而是看看为什么这个查询会给你的数据库服务器带来压力。一个有 150 万行的表并不稀奇。

您是否尝试添加 LIMIT 子句或仅选择您需要的列:

Select col1, col2 from table where status = 'published' and category = '' order by dateCreated LIMIT 5

它将显着减少数据库和 Web 服务器之间的流量。

于 2011-07-06T18:57:21.393 回答
1

一切皆有可能 :)

分布式内存缓存(serv1,2,3,4)。

仅将 serv4 用于 ReCache。

设置“仅限内部”网站(用户不可见)。

去掉“会刷新某些类别”的部分。

获取“阅读最多的文章”-> 解析 apache 访问日志。

并重新提交 url 到 server4。

有访问时间,因此您只能获得所需的部分,即从 2 到 6 小时前。

分布式内存缓存将自动将其值填充到 serv1、2、3。

于 2011-07-06T14:35:50.870 回答
1

与其依赖缓存过期然后在 HTTP 请求期间(或者,更有问题的是,在多个并发请求期间)重新填充,为什么不让缓存永不过期呢?

然后安排一些直到脚本来运行昂贵的查询(只需一次!)并在后台更新缓存。

于 2011-07-05T21:04:44.800 回答
0

我终于实现了一个继承自 Zend_Cache_Backend_Libmemcached 的类,我重写了 load() 方法。

我的每台服务器的主机名都以一组数字结尾,例如 serv01、serv02、serv03、serv04。主要思想是每个服务器都会认为缓存在不同的时间过期。例如 serv01 会认为缓存在实际过期前 20 分钟过期,serv02 将是 15 分钟,serv03 是 10 分钟,serv04 是 5 分钟。

通过这样做,我的缓存将永远不会在每台服务器上同时刷新,如果一台服务器关闭,缓存将由另一台服务器刷新。

于 2011-07-12T15:50:18.553 回答