nodejs 中的一致性
Consistency in nodejs
假设我有一个全局键值对并对其进行操作returns一个promise(实际上我正在使用Redis),它存储了剩余硬币的价值。
如果剩余数量大于0,Route /path 将请求中的数字减去硬币。
最初,它的值为 10。
现在,如果两个请求同时到达 10 和 9,它们是否都读取长度为 10 并发生不一致?
我所知道的是,承诺有回调,当第一次请求 getQuantity() 时,事件循环可以处理下一个请求,然后这个请求可以读取数量为 10,这可能会导致不一致。
app.get("/path",(req,res)=>{
const decrementBy=req.value;
const quantity=await obj.getQuantity();
if(quantity-decrementBy>=0){
await setQuantity(quantity-decrementBy);
}
res.send();
})
Node.js 是单线程的。所以没有两段代码可以同时执行。任何时候只有其中一个会执行。不确定的部分是您无法预测将首先处理哪个请求。
异步I/O表示并行等待,不是并行代码执行。
为了保持一致性,您可以为 quantity
使用锁,其中 quantity
将保持锁定状态,直到其中一个请求完成。
如果多个请求同时到来,会出现不一致的情况。
不一致的几率∝请求中的I/O操作数和访问redis的节点进程数。
由于 redis 不是事务性数据存储,因此 redis 不满足 ACID 属性。为了保持一致性,您可以使用锁定 (https://redis.io/topics/distlock)。对于nodeJs node-redlock是要使用的客户端。
假设我有一个全局键值对并对其进行操作returns一个promise(实际上我正在使用Redis),它存储了剩余硬币的价值。
如果剩余数量大于0,Route /path 将请求中的数字减去硬币。
最初,它的值为 10。 现在,如果两个请求同时到达 10 和 9,它们是否都读取长度为 10 并发生不一致?
我所知道的是,承诺有回调,当第一次请求 getQuantity() 时,事件循环可以处理下一个请求,然后这个请求可以读取数量为 10,这可能会导致不一致。
app.get("/path",(req,res)=>{
const decrementBy=req.value;
const quantity=await obj.getQuantity();
if(quantity-decrementBy>=0){
await setQuantity(quantity-decrementBy);
}
res.send();
})
Node.js 是单线程的。所以没有两段代码可以同时执行。任何时候只有其中一个会执行。不确定的部分是您无法预测将首先处理哪个请求。
异步I/O表示并行等待,不是并行代码执行。
为了保持一致性,您可以为 quantity
使用锁,其中 quantity
将保持锁定状态,直到其中一个请求完成。
如果多个请求同时到来,会出现不一致的情况。
不一致的几率∝请求中的I/O操作数和访问redis的节点进程数。
由于 redis 不是事务性数据存储,因此 redis 不满足 ACID 属性。为了保持一致性,您可以使用锁定 (https://redis.io/topics/distlock)。对于nodeJs node-redlock是要使用的客户端。