首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redis缓存服务

redis缓存服务

作者头像
ayqy贾杰
发布2019-06-12 12:28:07
8700
发布2019-06-12 12:28:07
举报
文章被收录于专栏:黯羽轻扬黯羽轻扬

一.问题背景

为了HTTPS抛弃了钉子户国内虚拟主机,趁机用Node重写了之前的PHP服务,放到好贵的VPS上,搬出去后发现抓取国内RSS经常超时,不超时的情况也需要loading 20s的样子,完全不可用。搬意已决,那就想办法提速

之前方案是请求时现抓,拿回来解析完毕后响应请求,过程看起来很慢,但实际很快,一般loading不超过3s,自用可以接受,所以只做了客户端内存缓存和离线缓存

现在20s完全无法忍受,所以先上见效最快的内存缓存:

  • 定时抓取,预先存入redis
  • redis内存缓存,简单过期策略

每2小时去全部抓取一遍,存入redis,请求先过缓存检查,缓存里有就不现抓,除非服务刚刚重启过,才需要现抓。定时抓取时不影响正常响应,因为抓取场景可以不用考虑脏数据问题,新一点旧一点没太大关系(但极端情况数据是定时抓取间隔 + 客户端缓存过期时间之前的,这时数据就很旧了)

二.安装配置redis

安装

CentOS环境,编译安装redis stable:

# 下载
wget http://download.redis.io/releases/redis-stable.tar.gz
# 解压
tar -axvf redis-stable.tar.gz
cd redis-stable
# 编译安装
make
make test
make install

默认安装路径在/usr/local/bin

$ ls /usr/local/bin | grep 'redis'
redis-benchmark
redis-check-aof
redis-check-rdb
redis-cli
redis-sentinel
redis-server

配置

默认配置文件在安装包的根目录redis.conf

mkdir -p /etc/redis/
cp redis.conf etc/redis
# 修改配置项
vi etc/redis/redis.conf
# 后台运行,默认不后台
#   把GENERAL节的daemonize no改为daemonize yes
# 改密码,默认免密登录
#   把SECURITY节的requirepass去掉注释,改为requirepass <mypassword>

其它配置项端口号,日志目录等等无所谓,需要的话修改,然后启动验证:

# 启动服务
redis-server /etc/redis/redis.conf
# 客户端连接
redis-cli
auth <mypassword>
# 操作
set 'key' 'value'
get 'key'

P.S.redis的更多命令,请查看Command reference – Redis,或者在线试玩Try Redis

添加到系统服务

redis-server /etc/redis/redis.conf每次这样启动看着比较难受,添加到系统服务里就可以通过service redis <cmd>管理了:

# 拷贝启动脚本
cp util/redis_init_script /etc/init.d/
# 改名
mv /etc/init.d/redis_init_script /etc/init.d/redis

然后修改配置项:

vi /etc/init.d/redis
# 修改第二行的chkconfig xxx为chkconfig 2345 80 90
# 确认端口号正确REDISPORT=6379
# 确认server可执行文件路径正确EXEC=/usr/local/bin/redis-server
# 确认cli路径正确CLIEXEC=/usr/local/bin/redis-cli
# 确认redis.conf路径正确CONF="/etc/redis/${REDISPORT}.conf"
# start改为后台执行
#   把$EXEC $CONF改为$EXEC $CONF &

P.S.# chkconfig 2345 80 90中,2345是指运行级别,80 90分别表示启动/关机优先级,数值越小越优先,控制顺序,更多信息请查看chkconfig

默认读取/etc/redis/${REDISPORT}.conf,也就是/etc/redis/6379.conf,以应对多实例情况,所以我们给配置文件改名:

mv /etc/redis/redis.conf /etc/redis/6379.conf

最后注册系统服务:

# 注册
chkconfig --add redis
# 设置自启动
chkconfig redis on

可以通过service命令管理了:

service redis start

三.node接redis

有现成的第三方模块node_redis

npm install redis --save

尝试连接:

const redis = require('redis');const PORT = 6379;
const HOST = '127.0.0.1';
const PWD = 'mypassword';
const OPTS = {auth_pass: PWD};// connect redis
let client = redis.createClient(PORT, HOST, OPTS);
client
   .on('error', (err) => {
       console.log('Error ' + err);
   })
   .on('ready', () => console.log('redis connected'));

connect之后就可以随便操作了,API与redis命令一致:

// 写
client.set(key, val, callback);
// 读
client.get(key, (error, val) => {});
// 设置有效期
client.expire(key, seconds);
// 检查过期
client.expire(url, (error, ttl) => {
   if (ttl > 0) console.log('alive');
   else console.log('died');
});

特别注意:所有callback都是Node经典方式,第一个参数是err,而不是data

做一个简单的缓存层,结构如下:

cache
 - queue
 - clearQueue()
 - expire()
 - ttl() + set()
 + get()
 + checkFresh()

配合访问抓取和定时抓取:

fetch
 - onerror(error) => {
       emitter.emit('error', error);
   };
 - onsuccess(data) => {
       data && cache.set(url, data);
   };
 - fetchNow() + fetch() => {
       if (noCache) {
           cache.checkFresh(url, (fresh) => {
               if (!fresh) console.log('schedule force fetch now'), fetchNow();
               else oncancel('cache is still fresh now');
           }
       }
       else {
           cache.get(url, (data) => {
               if (data) console.log('fetch from cache'), onsuccess(data);
               else fetchNow();
           });
       }
   }

访问抓取走缓存,直接从缓存去,没有才抓。定时抓取强制不走缓存,但检查过期,如果数据还很新,就取消抓取任务,不新的话现抓,抓取成功就过缓存层记录下来

P.S.定时抓取检查过期是为了避免不必要的重复抓取,比如服务挂了重启了,redis的数据不受影响,仍然是新的,这时没必要再抓一遍

四.总结

提速效果很明显,之前访问国内资源20s的loading缩短到5-6s了,国外资源也快了1-2s的样子,比起之前的PHP服务,5-6s还是挺慢,但接下来的优化项就没这么简单粗暴了:

todo
1.接口拆分,有接口返回128K文本,考虑分页
2.redis数据结构优化,目前是url key对应一个很大的JSON字符串,应该有更科学的方式
3.长连接,降低路途成本
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端向后 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.问题背景
  • 二.安装配置redis
    • 安装
      • 配置
        • 添加到系统服务
        • 三.node接redis
        • 四.总结
        相关产品与服务
        云数据库 Redis
        腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档