1

在我的 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:set => ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this contextsubscriberRedis.config('set',...)

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

编辑

我将代码更改为此,它现在可以工作了。但是,当我转向生产时,您认为“竞争条件”问题仍然存在吗?

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)
4

1 回答 1

1

问题是当你打电话给subscriberRedis.config('set'你的subscriberRedis 时,Redis 已经订阅了 subscriberRedis.subscribe(EVENT_SET)

subscriberRedis.config('set'而且,您在订阅期间不能使用此连接。

于 2020-04-21T15:25:27.653 回答