mongodb(mongoose-redis-cache)
在传统的项目中,我们经常会用到缓存来优化数据库的读取,比如java中,我们利用spring的AOP能力,在读写数据库前增加对缓存的操作。
在node与mongodb的项目中也仍然会存在类似问题,本文参考了mongoose-redis-cache这个插件。
https://github.com/conancat/mongoose-redis-cache
该插件还不太完善,但基本的思路是很简单的,初始化一个redis客户端,然后重写mongoose的exec方法,将exec的参数设置为redis的key,将数据库返回的结果设置为对应的value。
每次操作时优先读取redis。
代码如下:
// Generated by CoffeeScript 1.5.0
var mongooseRedisCache, redis, _; redis = require("redis"); _ = require("underscore"); mongooseRedisCache = function(mongoose, options, callback) {
var client, host, pass, port, redisOptions;
if (options == null) {
options = {};
}
host = options.host || "";
port = options.port || "";
pass = options.pass || "";
redisOptions = options.options || {};
mongoose.redisClient = client = redis.createClient(port, host, redisOptions);
if (pass.length > 0) {
client.auth(pass, function(err) {
if (callback) {
return callback(err);
}
});
}
//这里做了改动,原来是execFind,在我当前的Mongoose版本下无法使用
mongoose.Query.prototype._exec = mongoose.Query.prototype.exec;
mongoose.Query.prototype.exec = function(callback) { var cb, expires, fields, key, model, query, schemaOptions, self;
self = this;
model = this.model;
query = this._conditions;
options = this._optionsForExec(model);
fields = _.clone(this._fields);
schemaOptions = model.schema.options;
expires = schemaOptions.expires || 60; if (!schemaOptions.redisCache && options.lean) {
return mongoose.Query.prototype._exec.apply(self, arguments);
}
key = JSON.stringify(query) + JSON.stringify(options) + JSON.stringify(fields); cb = function(err, result) {
var docs;
if (err) {
return callback(err);
}
if (!result) {
return mongoose.Query.prototype._exec.call(self, function(err, docs) {
var str;
if (err) {
return callback(err);
}
str = JSON.stringify(docs);
client.set(key, str);
client.expire(key, expires);
return callback(null, docs);
});
} else {
docs = JSON.parse(result);
return callback(null, docs);
}
};
client.get(key, cb);
return this;
};
}; module.exports = mongooseRedisCache;
写测试用例如下:
var mongoose = require('mongoose');
var async = require('async');
var mongooseRedisCache = require("mongoose-redis-cache");
mongooseRedisCache(mongoose);
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/cachetest');
var user = new Schema({
username:{
type:String,
index:true
},
password:String
});
user.set('redisCache', true);
var userModel = mongoose.model('user', user);
var entity = new userModel({
username:'fredric',
password:'sinny'
});
var users = [];
for(var i = 0; i < 1000; i++){
users.push({
username:'fredric' + i,
password:'sinny' + i
});
}
function testCache(){
function datainit(item,cb){
var entity = new userModel(item);
entity.save(function(err){
cb(err);
});
}
async.mapSeries(users, datainit, function(err, results){
console.log('datainit finished');
var timestamp = new Date().valueOf();
var round = [];
for(var i = 0; i < 2000; i++){
round.push(i);
}
//利用缓存
function test(item,cb){
query = userModel.find({'username':'fredric101'});
query.lean();
query.exec(function(err, result){
cb(err);
});
}
//不利用缓存
function test_nocache(item,cb){
query = userModel.find({}).setOptions({nocache: true});
query.where("username", "fredric101");
query.exec(function(err, result){
cb(err);
});
}
async.mapSeries(round, test_nocache, function(err, results){
console.log(new Date().valueOf() - timestamp);
});
});
}
testCache();
测试结果还是比较明显的,在我本地笔记本上(安装redis + mongodb),上述测试用例执行:
1、无缓存、无索引:21501ms
2、无缓存、有索引:1966ms
3、有缓存、有索引:281ms
mongodb(mongoose-redis-cache)的更多相关文章
- 现在 做java 构架(RabbitMQ redis mysql )之类的
现在 做java 构架(RabbitMQ redis mysql )之类的
- mongoDB (mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
MongoDB - 简介 官网:https://www.mongodb.com/ MongoDB 是一个基于分布式文件存储的数据库,由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储 ...
- HTTP协议(缓存机制Cache)
HTTP的缓存 至于响应消息的实体,与请求消息的实体内容相似,这里只借绍下User-Agent头 User-Agent头域的内容包含发出请求的用户信息. Cache-Control头域(请求和应答通用 ...
- MongoDB(课时29 MapReduce)
3.7.4 MapReduce MapReduce 是整个大数据的精髓所在(实际中别用,因为在MongoDB中属于最底层操作). MapReduce是一种计算模型,简单的说就是将大批量的工作分解执行, ...
- MongoDB(课时24 全文索引)
3.6.3 全文索引 在一些信息管理平台上经常需要进行信息模糊查询,最早的时候是利用了某个字段上实现的模糊查询,但这个时候返回的信息并不会很准确,因为只能够查A字段或B字段,而在MongoDB里面实现 ...
- MongoDB(课时17 更新函数)
3.4.3 数据更新操作 MongoDB数据存的是副本数据, 最终的数据还要保存在传统的数据库里,所以如果关系型数据库里数据变了,最好的方法是删除里面的MongoDB数据重新插入. 在MongoDB里 ...
- NoSQL高级培训课程-HBase&&MongoDB(两天版)
课程大纲 主题 时间 主题 列数据库 (第1天) 上午 HBase发展简史-Google BigTable的开源实现 HBase基础:安装部署.管理命令.运行监控和开发接口: HBase专题:服务组件 ...
- Debian Buster 配置 Laravel 运行环境(nginx + redis + supervisor)
1 目标 将开发完成的 Laravel 项目布署于 Debian 之上.由于项目要求使用 horizon 官方扩展,要求 PHP7.1+,故采用 Debian buster (下一版) 2 材料 IP ...
- 配置到 Framework GAC(Global Assembly Cache) Assembly
配置到 Framework 通常有两种方法,一种是直接把它放到GAC(Global Assembly Cache作用是可以存放一些有很多程序都要用到的公共Assembly)中 :另一种是把它们放到具体 ...
- MongoDB(课时7 逻辑运算)
3.4.2.2 逻辑运算 逻辑运算主要三种类型:与($and),或($or),非($not.$nor). 范例:查询年龄在20~21岁的学生信息 db.students.find({"age ...
随机推荐
- Oracle 12c 的新功能:模式匹配查询
模式匹配SQL 在一系列的数据行中辨识出某种模式是一种广泛需求的功能,但在以前的SQL中是不可能的.有许多解决方法,但这些都很难写,很难理解,而且执行效率低下.在Oracle数据库中,从12c开始,你 ...
- JAVA网络编程
网络技术基础 OSI模型 应用层-表示层-会话层-传输层-网络层-数据链路层-物理层 TCP/IP分层模型 应用层-传输层-网络互联层-网络接口层Socket(套接字) TCP套接字编程 Serv ...
- 史上最全的常用iOS的第三方框架
文章来源:http://blog.csdn.net/sky_2016/article/details/45502921 图像: 1.图片浏览控件MWPhotoBrowser 实现了一个照片 ...
- js原生ajax请求get post笔记
开拓新领域,贵在记录.下面记录了使用ajax请求的get.post示例代码 //ajax get 请求获取数据支持同步异步 var ajaxGet = function (reqUrl, params ...
- 《笨办法学C》笔记之指针
C语言编程主要操作的对象就是指针. 指针从哪里来 指针就是表示内存存储区域的一组数值,使用%p格式化字符串. Linux系统会为程序维护两个临时变量存储位置:栈.堆.栈的空间少,栈通常在用户更高的地址 ...
- [mk] 喝一杯咖啡, 写一写 Makefile
Makefile 是 Linux 下组织程序的一个工具,它的命令是 make. (首字母M/m都可以) [Makefile] Makefile 编写的主旋律: target: [dependency] ...
- MMS搜索功能修改
高通平台的MMS源码中提供了搜索功能,但要先选择分类(名字,号码,信息内容,彩信主题),再输入字符,根据分类进行搜索. 而在Contacts中却不需要分类,直接根据输入字符搜索任意匹配字段.相比之下, ...
- php二维数组按照键值排序的方法
//按照传入数组中的num倒序 public function numdesc($array,$key="num",$order="desc"){ $arr_n ...
- json数据测试接口
json数据测试接口:http://www.xiaoqiang.org/tools/JsonView/?1348068433
- 读取全球ip获取用户地区
这个 首先说明下.ip库是qq纯真ip库 dat文件类型 public static string QQipPath = AppDomain.CurrentDomain.BaseDirectory + ...