Redis 是基于内存来存储数据的,所以 Redis 对数据读取的速度远远大于使用硬盘来读取数据的速度,因此经常被用作缓存。除此之外,Redis 还经常使用在应用排行榜、网站访问统计、数据过期处理、商品秒杀(队列机制)等地方。在本博客中,针对访问量比较大的数据,如首页信息,以及热门的文章,设计了 Redis 缓存方案。
安装 Redis
安装 Redis 的流程还是很简单的,具体的流程可以参考官网介绍 Redis Quick Start。在下载并且编译完成 Redis 以后,在虚拟机上部署 Redis 时,我配置了 redis.conf 中的几个参数,其中有:
1 | daemonize yes // 设置 Redis 后台启动 |
当然,除此以外,还可以配置连接 Redis 的用户验证密码,日志的输出记录等。因为 Redis 的数据都是存储在内存中的,所以会比较消耗内存资源,所以在配置文件中,也可以注意以下设置 Redis 可以使用的最大存储内存。具体很多的参数,有需要的同学,可以参考下面文章进行设置:redis.conf配置及说明
在我的环境中,为了方便启动 Redis,还使用 alias
重新定义了 Redis 的启动命令:
1 | alias startredis="/root/redis/redis-3.2.9/src/redis-server /root/redis/redis-3.2.9/redis.conf" |
Redis 相关库
Redis 官方提供了多种语言连接的库,其中 JS 的库可以在 NodeRedis 这里找到说明。官方的 redis
库是基于回调函数来进行异步处理的,我们也可以使用 bluebird 来包装该库,来实现基于 Promise 处理的能力。
1 | var redis = require('redis'); |
1 | // We expect a value 'foo': 'bar' to be present |
使用 bluebird
来包装异步调用的方法在 redis GitHub 上也可以找到。
除此以外,还需要注意一点,在使用 Redis 的库的时候,如果有多个查询,可以使用 multi()
+ execAsync()
函数来进行一次处理多个请求。
同步 Mongodb 数据到 Redis
在我的博客数据库的数据中,需要同步到 Redis 的数据有:
series
:用来为/series/
目录和/archives/
提供数据abstracts
:用来为首页提供数据articles
:用来为文章提供数据
通过上面需要同步的信息,好像我们已经把数据库中基本所有的数据都同步了,但其实不能这样做。由于 Redis 使用的是内存来缓存数据,所以,如果服务器的内存太小,或者已有的数据太多时,会消耗很大的内存,所以,我们在同步数据的时候要对数据进行选择。
比如说,可以只从 MongoDB 中获取最热门的 20
篇文章,或者只获取 abstracts
中在首页前三页展示的数据等,通过这种方式来选择要同步的数据,来节约服务器的内存使用情况。(在本博客目前还没有进行热门数据的筛选功能,不过预计在接下使用 Google 统计处理这方面的数据,然后再更新本文中热门数据的获取代码。)
所以,目前获取数据的函数只是实现了功能,还没有考虑到重用性,这部分会在接下来使用 Google 统计后,根据获得的数据类型进行设计更新。
1 | /** |
设置同步周期
博客在设计同步的时候,分为主动同步和被动同步。主动同步是在修改文章和创建新文章的时候,调用上面定义好的 fetchFormMongoToRedis
函数来讲数据同步到 Redis 缓存中,被动同步是每 5 分钟被动调用该函数从数据库中获取一次需要的数据来更新缓存,被动更新的目的是,当使用 Google 统计和 Qisqus 评论系统以后,被动获得最热门的文章以及当前的评论数来进行更新。
本博客系统创建了一个新的 JS 脚本,通过 node-schedule 库来实现每隔 5 分钟获取数据的能力。并且在生产环境中通过 PM2 保障该脚本的运行,相关代码如下:
1 | var rule = new schedule.RecurrenceRule(); |