Nodejs 使用 Redis 如何处理因异步取值不准确的问题?

发布于 1周前 作者 bupafengyu 来自 nodejs/Nestjs

大概描述一下应用场景:

app.get("/handle-work/:workid", async (req, res) => {
	const workid = req.params.workid;
const work = await client.get(workid);
if (!work) {
	res.send("The work already done:" + workid);
    return;
}

// do something sync

// clean redis cache
await client.del(workid);

res.send("Handle:" + workid);

});

这种写法可能会导致一个 workid 被处理两次。 应该如何避免呢? 谢谢


Nodejs 使用 Redis 如何处理因异步取值不准确的问题?

10 回复

你需要搜索的关键字可能是"redis 分布式锁"


  1. do something sync 这里看下能否设计成幂等的. 偶尔调用端抖动一下请求了两次,无碍
    2. 如果 1 不可以,要在 handle 之前对 workid 上锁,这里的锁也可以顺势复用 redis 的能力 https://redis.io/docs/manual/patterns/distributed-locks/

把 client.get 换成 client.getdel

op, 这有个大佬,@luin ,快逮着问

用原子操作的 pop spop

大哥,你这不是普通的 get ,而是你要上锁啊,拿某个资源,就得锁,让别人竞争不到

幂等,防抖

你这问题不是异步处理带来的。

感谢大佬~~~ 解开了我的困惑,谢谢

在Node.js中使用Redis时,处理因异步取值不准确的问题通常涉及到确保数据的一致性和正确管理异步操作。这里有几个关键策略和代码示例来帮助你解决这个问题:

  1. 使用回调函数或Promise确保顺序执行: 你可以使用Redis客户端(如redis库)提供的回调函数或返回Promise的特性来确保操作按顺序执行。

    const redis = require('redis');
    const client = redis.createClient();
    
    async function getValue(key) {
        const value = await new Promise((resolve, reject) => {
            client.get(key, (err, reply) => {
                if (err) reject(err);
                resolve(reply);
            });
        });
        return value;
    }
    
    async function main() {
        const key = 'myKey';
        const value = await getValue(key);
        console.log(value);
    }
    
    main();
    
  2. 使用async/await管理异步流程: 结合async/await可以让异步代码看起来更像同步代码,从而更容易理解和维护。

  3. 事务处理: 对于需要原子性操作的多步Redis命令,可以使用Redis事务。

    client.multi()
        .set('key1', 'value1')
        .get('key1')
        .exec((err, replies) => {
            console.log(replies); // ['OK', 'value1']
        });
    
  4. 使用Lua脚本: Lua脚本在Redis中执行是原子性的,可以用来保证复杂操作的一致性。

通过这些方法,你可以有效地处理Node.js中使用Redis时的异步取值不准确问题。

回到顶部