1、设置过期时间
redis设置过期时间:expire key seconds
var redis = require('redis'),
RDS_PORT = 6389, //端口号
RDS_HOST = '127.0.0.1', //服务器IP
RDS_PWD = '88888888888888', //密码
RDS_OPTS = {}, //设置项
rclient = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);
rclient.auth(RDS_PWD,function(){
console.log('redis通过认证');
});
//redis数据库
rclient.set('key','1');//赋值
rclient.expire('key',60);//60秒自动过期
2、pipline
redis客户端执行一条命令分4个过程:
发送命令-〉命令排队-〉命令执行-〉返回结果
这个过程称为Round trip time(简称RTT, 往返时间
),mget mset有效节约了RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量操作,需要消耗N次RTT ,这个时候需要pipeline来解决这个问题
未使用pipeline执行N条命令
使用了pipeline执行N条命令
实践
'use strict';
const cache = require('../libs/cache');
const moment = require('moment');
const co = require('co');
const Lodash = require('lodash');
const CHAT_POPULARITY_TTL = 60 * 5;
function getRoomUserPopularityKey(roomId) {
return `room_id:${roomId}:user_id:popularity`;
}
function getRoomChatPopularityKey(currentTime) {
return `time:${currentTime}:chat:popularity`;
}
function updateChatPopularityByUv(roomId, userId) {
return co(function* () {
const pipeline = cache.batch();
const popularityKey = getRoomUserPopularityKey(roomId);
const currentTime = moment().unix();
const threeBefore = moment().subtract(3, 'm').unix();
pipeline.zadd(popularityKey, currentTime, userId);
pipeline.expire(popularityKey, CHAT_POPULARITY_TTL);
pipeline.zremrangebyscore(popularityKey, 0, threeBefore);
yield pipeline.execAsync();
});
}
function updateChatPopularityByPv(roomId) {
return co(function* () {
const currentTime = formatTime(0);
const popularityKey = getRoomChatPopularityKey(currentTime);
const pipeline = cache.batch();
pipeline.hincrby(popularityKey, roomId, 1);
pipeline.expire(popularityKey, CHAT_POPULARITY_TTL);
yield pipeline.execAsync();
});
}
function getRoomUserPopularityNum(roomId) {
return co(function* () {
const pipeline = cache.batch();
const popularityKey = getRoomUserPopularityKey(roomId);
const threeBefore = moment().subtract(3, 'm').unix();
pipeline.zremrangebyscore(popularityKey, 0, threeBefore);
pipeline.zcard(popularityKey);
const [popularityNum] = yield pipeline.execAsync();
return popularityNum[1];
});
}
function formatTime(second) {
const tmpTime = moment().subtract(second, 'm').format('YYYY_MM_DD_HH_mm');
return tmpTime;
}
function getRoomChatPopularityNum(roomId) {
return co(function* () {
let chatNum = 0;
const pipeline = cache.batch();
for (let i = 0; i < 3; i++) {
const beforeTime = formatTime(i);
const beforeKey = getRoomChatPopularityKey(beforeTime);
pipeline.hget(beforeKey, roomId);
}
const chatRes = yield pipeline.execAsync();
chatRes.map(chat => {
if (!Lodash.isNil(chat)) {
chatNum += Lodash.parseInt(chat);
}
});
return chatNum;
});
}
module.exports = {
updateChatPopularityByUv,
updateChatPopularityByPv,
getRoomUserPopularityNum,
getRoomChatPopularityNum,
};
注意事项
大家使用pipeline的时候千万不要忘记调用pipeline.sync();
https://blog.csdn.net/suifeng629/article/details/95756074
https://blog.csdn.net/y8806662681/article/details/76321932
https://www.cnblogs.com/huangxincheng/p/6212406.html
https://www.cnblogs.com/zhangtingzu/p/6939895.html
EX NX
EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。
如果key为kk的值不存在,设置key为kk的值为1,过期时间为10分钟
cache.setAsync(`kk`, 1, 'EX', 60 * 10, 'NX');
SETEX key seconds value
http://redisdoc.com/string/setnx.html
SSCAN 命令
Redis SSCAN 命令用于遍历集合中键的元素,SSCAN 继承自SCAN。
redis SSCAN 命令基本语法如下:
SSCAN key cursor [MATCH pattern] [COUNT count]
cursor - 游标。
pattern - 匹配的模式。
count - 指定从数据集里返回多少元素,默认值为 10 。
SCAN命令是一个基于游标的迭代器,每次被调用之后,都会向用户返回一个新的游标,用户在下次迭代时需要使用这个新游标作为SCAN 命令的游标参数,以此来延续之前的迭代过程。
https://www.redis.com.cn/commands/sscan.html