nodejs + express + mongodb + redis 使用redis小实例

性能是最重要的一个指标需要评估在开发一个web服务.

缓存是一个战略旨在解决主要的存储问题,这意味着:存储越大,越慢,反之亦然。缓存是一个组件,最近访问的数据存储在一个更快的存储系统。每次请求数据,(有一些概率)可以从内存越快。

传统上我们的 后台服务就是接收前端过来的 request请求,进入对应的 controller ,执行一系列方法,查库。。。

module.exports.findBookByTitle = function (db, title, callback) {
    db.collection('text').findOne({
        title: title
    }, function (err, doc) {
        if (err || !doc) callback(null);
        else callback(doc.text);
    });
};

但是有些频繁的查库 可能会成为,server的性能负担。因此 引入了 redis把经常访问的数据存入内存,以后访问的时候直接从内存获取,这样会减少数据库的负担。

引入缓存机制


缓存在server中扮演的角色(来源:https://www.sitepoint.com/caching-a-mongodb-database-with-redis/)

nodejs 引入redis很简单 可以在 npm上搜索,有简单的api教程。

下来我们看看 引入缓存 之后 的查询代码:

module.exports.findBookByTitleCached = function (db, redis, title, callback) {
    redis.get(title, function (err, reply) {
        if (err) callback(null);
        else if (reply) //Book exists in cache
        callback(JSON.parse(reply));
        else {
            //Book doesn't exist in cache - we need to query the main database
            db.collection('text').findOne({
                title: title
            }, function (err, doc) {
                if (err || !doc) callback(null);
                else {\\Book found in database, save to cache and
                    return to client
                    redis.set(title, JSON.stringify(doc), function () {
                        callback(doc);
                    });
                }
            });
        }
    });
};

看一下 路由:

app.get('/book/:title', function (req, res) {
    if (!req.param('title')) res.status(400).send("Please send a proper title");
    else {
        access.findBookByTitleCached(db, redis, req.param('title'), function (book) {
            if (!text) res.status(500).send("Server error");
            else res.status(200).send(book);
        });
    }
});

请求进入路由后,会判断 缓存中时候有请求的数据,如果有就从换从中直接拿来主义,否则查库,并将数据存入缓存中。

当然,redis缓存如果只是这么简单的用,这样结果会成为负担,缓存的数据越来越越多。内存被占用,服务器性能就会下降,对于优秀的redis作为缓存来说,怎么可能会这么low,reis带有缓存策略,对缓存进行管理。

由于内存限制,我们必须删除缓存中的某些产品和只保留其中的一些。理想情况下,我们要保持这些的几率最高的再次阅读。选择我们要删除的项目,我们必须建立一种缓存策略。删除随机项可能是一个有效的政策,但它显然不会是非常有效的。我们将使用一个最受欢迎的政策:LRU

LRU:

置换策略

当Redis内存使用达到maxmemory时,需要选择设置好的maxmemory-policy进行对老数据的置换。 
下面是可以选择的置换策略:

  • noeviction: 不进行置换,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回error
  • allkeys-lru: 优先删除掉最近最不经常使用的key,用以保存新数据
  • volatile-lru: 只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据
  • allkeys-random: 随机从all-keys中选择一些key进行删除,用以保存新数据
  • volatile-random: 只从设置失效(expire set)的key中,选择一些key进行删除,用以保存新数据
  • volatile-ttl: 只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据

要合理的运用管理缓存,这样才能为我们的server插上“”翅膀“”


保持更新缓存。

module.exports.access.updateBookByTitle = function (db, redis, title, newText, callback) {
    db.collection("text").findAndModify({
        title: title
    }, {
        $set: {
            text: text
        }
    }, function (err, doc) { //Update the main database
        if (err) callback(err);
        else if (!doc) callback('Missing book');
        else {
            //Save new book version to cache
            redis.set(title, JSON.stringify(doc), function (err) {
                if (err) callback(err);
                else callback(null);
            });
        }
    });
};
app.put('/book/:title', function (req, res) {
    if (!req.param("title")) res.status(400).send("Please send the book title");
    else if (!req.param("text")) res.status(400).send("Please send the new text");
    else {
        access.updateBookByTitle(db, redis, req.param("title"), req.param("text"), function (err) {
            if (err == "Missing book") res.status(404).send("Book not found");
            else if (err) res.status(500).send("Server error");
            else res.status(200).send("Updated");
        });
    }
});
最近在考虑缓存的使用场景,例如复杂查询,访问度较高的数据,等


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值