我的任务是为一个客户开展项目,该客户有一个他估计每天会收到1-2M点击量的网站。他拥有一个5800万用户的现有数据库,需要按照每个注册的方式为新品牌提供种子。大多数网站的内容都是通过外部API提供的数据提供的,我们的Mongo设置中存储的大部分数据都是配置文件信息和保存的API参数。
NginX将在端口80上,并在端口8000 - 8010上负载均衡到节点群集。
我的问题是如何处理缓存。我来自LAMP背景,所以我习惯于用PHP编写静态HTML文件,并为最小化MySQL负载提供服务,或者为需要更高级别缓存的网站使用Memcached。这个设置对我来说有点陌生。
对于最小响应时间和CPU负载,哪个是最理想的?
参考:http://andytson.com/blog/2010/04/page-level-caching-with-nginx/
server {
listen 80;
servername mysite.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
location / {
proxy_pass http://localhost:8080/;
proxy_cache anonymous;
}
# don't cache admin folder, send all requests through the proxy
location /admin {
proxy_pass http://localhost:8080/;
}
# handle static files directly. Set their expiry time to max, so they'll
# always use the browser cache after first request
location ~* (css|js|png|jpe?g|gif|ico)$ {
root /var/www/${host}/http;
expires max;
}
}
hash()
功能是此页面上的numbers()
功能:http://jsperf.com/hashing-strings
function hash(str) {
var res = 0,
len = str.length;
for (var i = 0; i < len; i++) {
res = res * 31 + str.charCodeAt(i);
}
return res;
}
var apiUrl = 'https://www.myexternalapi.com/rest/someparam/someotherparam/?auth=3dfssd6s98d7f09s8df98sdef';
var key = hash(apiUrl).toString(); // 1.8006908172911553e+136
myRedisClient.set(key,theJSONresponse, function(err) {...});
hash()
功能是此页面上的numbers()
功能:http://jsperf.com/hashing-strings
function hash(str) {
var res = 0,
len = str.length;
for (var i = 0; i < len; i++) {
res = res * 31 + str.charCodeAt(i);
}
return res;
}
var fs = require('fs');
var apiUrl = 'https://www.myexternalapi.com/rest/someparam/someotherparam/?auth=3dfssd6s98d7f09s8df98sdef';
var key = hash(apiUrl).toString(); // 1.8006908172911553e+136
fs.writeFile('/var/www/_cache/' + key + '.json', theJSONresponse, function(err) {...});
我做了一些研究和基准测试,比如本网站上显示的那些基准测试让我远离这个解决方案,但我仍然愿意考虑它是否最有意义:http://todsul.com/nginx-varnish
答案 0 :(得分:18)
我会做一个组合,并使用Redis缓存具有短TTL的会话用户API调用,并使用Nginx缓存长期RESTless数据和静态资产。我不会写JSON文件,因为我认为文件系统IO将是列出的选项中最慢和最耗费CPU的。{/ p>
答案 1 :(得分:4)
nginx页面级缓存适用于缓存静态内容。但对于动态内容,这并不好。例如,如果在上游更改内容,如何使缓存无效?
Redis非常适合内存数据存储。但我不喜欢将它用作缓存。由于内存量有限,我不得不经常担心内存不足。是的,您可以设置策略以使redis中的密钥到期。但这是额外的工作,仍然不如我希望它成为缓存提供商。
没有选择3和4的经验。
我很惊讶你没有在这里包含memcache作为选项。根据我的经验,它作为缓存提供商是可靠的。 redis没有的一个memcache功能是它不能保证密钥在你指定的到期时间内不会过期。这对于数据存储是不利的,但它使得memcache成为缓存的理想选择:您不必担心使用分配给memcache的内存。 memcache将删除较少使用的密钥(缓存较少使用),即使这些密钥的到期时间尚未达到。
Nginx提供此内置版memcache module。它很坚固。如果你在线谷歌,可以参考一些教程。
这个我最喜欢的(见下面的链接)。缓存失效很容易:例如,如果页面在上游更新,只需从上游应用服务器中删除memcache密钥。作者声称响应时间增加了4倍。相信它对你的用例来说已经足够了。
http://www.igvita.com/2008/02/11/nginx-and-memcached-a-400-boost/
答案 2 :(得分:1)
至于清漆,我不打算破译您找到的网站上的基准,但我可以告诉您,它们数字非常糟糕,并且与真正的高流量实施没有任何共同点(google for varnish optimizations并查看基准显示100-200k req / s而不是8k)。
Nginx也是页面缓存的正常选择,每天点击1-2M,您不需要极高的性能。所以,请选择与您合作的方式。
两个节点解决方案确实是一个更糟糕的选择。页面缓存应与动态应用程序分开,以提供可靠性和性能。
此外,如果您将应用程序用作对象缓存或常用反序列化数据的缓存,redis / memcached将最有助于扩展应用程序。