TENCHIANG / blog

issue blog
10 stars 1 forks source link

Redis经验 #35

Open TENCHIANG opened 5 years ago

TENCHIANG commented 5 years ago

清空当前数据库所有key

flushdb

incr不会改变ttl 但是也不能设置ttl(redis初次incr优化)

如果incr一个不存在的key的话 value为1没问题 但是ttl为-1 不会过期 所以要进一步处理: incr后如果ttl为-1那么就expire 还有个更妙的:incr的结果为1那么它的ttl必为-1 因为是第一次生成的(不用运行ttl一次了)

// 为了保留ttl但是又要每次修改其值加一,还要处理key不存在的情况
const isNew = await redis.incr(key) == 1
if (isNew) await redis.expire(key, expire)

pipline不支持subscribe+select一起 因为pipeline不保证顺序

但是为啥pipline又支持select+set呢

const pipelineRes = await redis.pipeline([
    ['select', dbIndex],
    ['set', `${orderSnPrefix}:${order_sn}`, '', 'px', ms(unpaidExpire)],
    ['select', 0]
]).exec()
ctx.helper.printLog('order.create', { pipelineRes })

subscribe事件是怎么监听到的?

const sub2 = new Redis(client)
await sub2.on('subscribe', (channel, count) => {
    console.log('on subscribe', channel, count)
})

线上环境会收到多次信息,如何保证其唯一性?或者根本无需担心?只要接收到消息后的操作是有条件的

sub.on('message', async (channel, message) => {
    const unique = `unique:${message}`
    if (await redis.get(unique)) {
        console.log('为保证redis定时器唯一性 这次不处理 因为已有别在处理这个订阅了')
        return
    }
    // 时间不得超过定时器的有效期 不然会一个都处理不了
    await redis.set(unique, '唯一性保证', 'ex', unpaidExpire * 60)
}

monitor显示由client发送给redis的command

const sub3 = new Redis(client)
sub3.monitor().then(monitor =>
    monitor.on('monitor', (time, args, source, database) => {
        console.log('monitor', new Date(parseInt(time * 1000)).toLocaleString(), args, source, database)
    })

错误 EXECABORT Transaction discarded because of previous errors

这是redis事务处理multi报的错,redis的事务没有回滚,就算前面出错了也会继续后面执行下去,只保证操作的顺序性,pipeline不保证顺序性,所以selectsubscribe不能连用和其它一些限制,但是速度快啊 参考: