【问题标题】:Redis Node to listen to SET events and set a TTL to every requestRedis 节点监听 SET 事件并为每个请求设置一个 TTL
【发布时间】:2020-08-03 22:07:57
【问题描述】:

在我的 Nodejs 应用程序中,我使用了一个在我的 Redis 数据库中设置键的库。所以,我需要监听每个创建/更新密钥的请求,并在每个密钥上添加一个ttl(无论它是否已经存在)。

我有我的主要 Redis 客户端(向 Redis 数据库添加密钥):

const redisClient = createClient({
    url: redisUrl,
    tls: {
        ca: Buffer.from(redisCertBase64, 'base64').toString('utf-8'),
    },
})

我添加了另一个应该监听set事件的客户端:

const subscriberRedis = redisClient.duplicate()

function done(err) {
    logger.error('Notifications not active')
    if (err) {
        logger.error(err.stack || err.message || err)
    }
}

const eventType = 'notify-keyspace-events'

subscriberRedis.config('get', eventType, (err, conf) => {
    if (err) {
        logger.debug('subscriberRedis:get =>', err.message)
        return done(err)
    }
    logger.debug('conf =>', conf)
    if (conf[1].indexOf('EKx') < 0) {
        subscriberRedis.config('set', eventType, conf[1] + 'EKx', function (err) {
            if (err) {
                logger.debug('subscriberRedis:set =>', err.message)
                return done(err)
            }
        })
    }
})

const EVENT_SET = '__keyevent@0__:set'

subscriberRedis.on('message', function (channel, key) {
    switch (channel) {
        case EVENT_SET:
            logger.info('Key "' + key + '" set!')
            break
    }
})

subscriberRedis.subscribe(EVENT_SET)

当我运行此代码时,我会进入由subscriberRedis.config('set',...) 记录的日志subscriberRedis:set =&gt; ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context

我不确定我在这里缺少什么。

编辑

我把代码改成了这个,现在它可以工作了。但是,当我开始生产时,您认为“竞争条件”问题仍然存在吗?

const redisClient = createClient({
    url: redisUrl,
    tls: {
        ca: Buffer.from(redisCertBase64, 'base64').toString('utf-8'),
    },
})

/**
 * Subscriber listening to `set` events
 **/
const subscriber = redisClient.duplicate()
const EVENT_SET = '__keyevent@0__:set'

subscriber.on('message', function (channel, key) {
    switch (channel) {
        case EVENT_SET:
            redisClient.expire(key, 300)
            logger.debug('Key "'.red + key + '" set!'.yellow)
            break
    }
})
subscriber.subscribe(EVENT_SET)

【问题讨论】:

  • 你检查过 RedisGears 吗?它可以注册任何你想要的事件并对其采取行动,并且一切都在 Redis 中运行
  • 我没有。我会检查一下!感谢您的提示!

标签: node.js redis listener node-redis ioredis


【解决方案1】:

问题是,当您调用subscriberRedis.config('set' 时,您的subscriberRedis 已经订阅了subscriberRedis.subscribe(EVENT_SET)

而且,当您订阅时,您不能将此连接用于subscriberRedis.config('set'

【讨论】:

  • 我已经更新了代码 :) 你能告诉我当我转向生产时“竞争条件”是否仍然是一个问题吗?谢谢!
  • 好像没问题,我看你只使用连接订阅
  • 是的,我尝试了这种简单的方法,并且有效。每次 Redis 执行 set 时,它都会执行我的事件处理程序。但是,我担心在生产中,由于 Redis 数据库将被大量查询,可能存在“竞争条件”,或者 Redis 是否有队列机制来保护这一点
猜你喜欢
  • 1970-01-01
  • 2019-07-25
  • 2018-05-14
  • 2016-11-01
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
相关资源
最近更新 更多