这个问题的标题可能令人困惑,但问题很简单。
我正在使用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服务器。
但有没有办法以更聪明的方式处理缓存?例如,server1将尝试刷新缓存,而服务器2,3和4仍将使用缓存中的相同值。
我可以写一些代码来做到这一点,但我想知道是否有办法直接用Zend_Cache做到这一点?如果有一个我可以应用于我的问题的设计模式?
[编辑]我想要一些我可以扩展到100台服务器的东西
答案 0 :(得分:1)
不是依赖缓存过期然后在HTTP请求期间重新填充(或者,在多个并发请求期间更有问题),为什么不让缓存永不过期?
然后安排一些直到脚本来运行昂贵的查询(只需一次!)并在后台更新缓存。
答案 1 :(得分:1)
一切皆有可能:)
分布式内存缓存(serv1,2,3,4)。
仅将serv4用于ReCache。
设置“仅限内部”的网站(用户不可见)。
删除“会刷新某些类别”的部分。
获取“阅读量最多的文章” - >解析apache访问日志。
并将网址重新提交给server4。
有访问时间,因此您只能获得所需的部分,即2到6小时之前。
分布式内存缓存会将其值自动填充到serv1,2,3。
答案 2 :(得分:1)
这是您正在执行的实际查询吗?
Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\
也许不是搜索高级缓存解决方案,而是查看为什么此查询会强调您的数据库服务器。一个1.5米行的表并不常见。
您是否尝试添加LIMIT子句或仅选择所需的列:
Select col1, col2 from table where status = 'published' and category = '' order by dateCreated LIMIT 5
它将显着减少数据库和Web服务器之间的流量。
答案 3 :(得分:0)
我终于实现了一个继承自Zend_Cache_Backend_Libmemcached的类 我正在覆盖load()方法。
我的每个服务器都有主机名,由一组数字完成,例如serv01,serv02,serv03,serv04。 主要思想是每个服务器都会认为缓存在不同时间到期。例如,serv01会认为缓存在实际到期前20分钟到期,serv02为15分钟,serv03为10分钟,serv04为5分钟。
通过这样做,我的缓存永远不会在每台服务器上同时刷新,如果一台服务器关闭,缓存将被另一台服务器刷新。