数据基本上很长时间不做改变的站点… 想起来 PHP 有缓存. 比如频繁访问的数据卸载文件… 在 Node 里缓存是怎么处理的? 缓存是放在磁盘里做文件, 还是直接在内存里用一个变量存储, 这在性能上怎么考虑?
看情况了,我一般直接一个变量存储,大一点的用Buffer
放在磁盘中肯定不够放在内存中快了,但是放在磁盘中容量可以很大。
如果内存足够,一般都会优先选择放在内存中吧。还有,放在内存中万一程序重启了,之前的缓存就木有了。
@jiyinyiyong var str = JSON.decode({“key”:“value”}); 降对象变成json字符串之后,再变成buffer对象 var buffer = new Buffer(str); 反之亦然
@jiyinyiyong Buffer对象是不归V8管理的,所以,不受V8的内存限制
@jiyinyiyong 自己封装成一个函数嘛,比如:
var cache = {};
exports.set = function (n, v) {
cache[n] = new Buffer(JSON.stringify(v));
};
exports.get = function (n) {
return JSON.parse(cache[n].toString());
};
我的做法是从档案读取,然后每隔一段时间将内存的数据储存 储存时我还使用了lzw算法来压缩文件
这样的缓存有必要么, 集群呢, 就算不集群, 那么worker之间内存无法共享, 用处太弱了, 还是memcache或者redis之类的
@jiyinyiyong buffer就是内存
function CacheLRU(capacity) {
/* 利用Buffer写的一个LRU缓存,capacity为缓存容量,为0时构造一般缓存。
myCache = new CacheLRU(capacity); //构造缓存
myCache.get(key); //读取名为key的缓存值
myCache.put(key, value); //写入名为key的缓存值
myCache.remove(key); //删除名为key的缓存值
myCache.removeAll(); //删除所有缓存值
myCache.info(); //返回myCache缓存信息,包括:
{capacity: 缓存容量,
length: 当前已使用容量,
size: 缓存数据大小bytes,
ratio: 缓存命中率,
keys: 当前已缓存的数据名称(key)数组
}
*/
this.capacity = capacity || 0;
this.cache = {};
this.hash = {};
this.miss = 0;
if(capacity < 0) this.capacity = 0;
};
//为了提高取值效率,get方法只有取值和取值计数操作,key为string类型。
CacheLRU.prototype.get = function(key) {
key = '_' + key;
if(this.hash[key]) this.hash[key] += 1;
else this.miss += 1;
return JSON.parse(this.cache[key].toString());
};
//LRU cache由存值put方法实现
CacheLRU.prototype.put = function(key, value) {
key = '_' + key;
if(this.capacity === 0) {
this.cache[key] = new Buffer(JSON.stringify(value));
this.hash[key] = 1;
} else {
var r = Object.keys(this.hash);
if(r.length < this.capacity) {
this.cache[key] = new Buffer(JSON.stringify(value));
this.hash[key] = 1;
} else {
that = this;
r.sort(function(a, b) {
return that.hash[a] - that.hash[b];
});
delete this.cache[r[0]];
delete this.hash[r[0]];
this.cache[key] = new Buffer(JSON.stringify(value));
this.hash[key] = 1;
}
}
return this;
};
CacheLRU.prototype.info = function() {
var keys = Object.keys(this.hash);
var hit = 0, size = 0;
keys.forEach(function(key, i) {
if(this.hash[key]) hit += this.hash[key];
size += this.cache[key].length;
keys[i] = key.slice(1);
}, this);
return {
capacity: this.capacity,
length: keys.length,
size: size,
ratio: hit / (this.miss + hit),
keys: keys
};
};
CacheLRU.prototype.remove = function(key) {
key = '_' + key;
delete this.cache[key];
delete this.hash[key];
return this;
};
CacheLRU.prototype.removeAll = function() {
this.cache = {};
this.hash = {};
return this;
};
module.exports = CacheLRU;
// test:
/*var user = new CacheLRU(10);
user.put('user1', {name:'admin', age: 30});
user.put('user2', {name:'user', age: 31});
user.put('user3', {name:'guest', age: 32});
console.log(user.get('user1'));
console.log(user.get('user2'));
console.log(user.get('user3'));
console.log(user.info());*/
还有一个直接使用内存对象缓存(存在V8引擎内)的版本,见 https://github.com/zensh/jsgen/blob/dev/lib/tools.js
经测试,使用Buffer构建的读写都要快一点,容量也不受V8限制,只是不适合在客户端浏览器使用
上面get方法还有一个bug,如果值不存在,会抛出错误,更新后的版本在 https://gist.github.com/zensh/5069881