$ docker run --rm --name redis1 -p 6379:6379 redis
$ docker run --rm --name redis2 -p 6380:6379 redis
$ docker run --rm --name redis3 -p 6381:6379 redis
const Redis = require("ioredis"); // 5.3.2
const { default: Redlock } = require("redlock"); // 5.0.0-beta.2
const redis1 = new Redis({
port: 6379,
host: "localhost",
})
const redis2 = new Redis({
port: 6380,
host: "localhost",
})
const redis3 = new Redis({
port: 6381,
host: "localhost",
})
const redlock = new Redlock(
[redis1, redis2, redis3],
{
driftFactor: 0.01, // clock drift를 보상하기 위해 driftTime 지정에 사용되는 요소, 해당 값과 아래 ttl값을 곱하여 사용.
retryCount: 10, // 에러 전까지 재시도 최대 횟수
retryDelay: 200, // 각 시도간의 간격
retryJitter: 200, // 재시도시 더해지는 되는 쵀대 시간(ms)
automaticExtensionThreshold: 500, // lock 연장 전에 남아야 하는 최소 시간(ms)
}
);
const paymentHistoryOfA = {
pointRow: [5000]
}
const wait = (timeToDelay) => new Promise((resolve) => setTimeout(resolve, timeToDelay));
const getCurrentTotalPoint = async () => {
await wait(200); // select 에 0.2ms 소요된다 가정
return paymentHistoryOfA.pointRow.reduce((acc, cur) => (acc += cur), 0);
}
const addNewPointHistory = async (point) => {
await wait(300); // insert 에 0.3ms 소요된다 가정
paymentHistoryOfA.pointRow.push(point);
}
async function purchase(usagePoint) {
try {
console.log("redlock Starting...");
let lock = await redlock.acquire(["a"], 5000);
if (await getCurrentTotalPoint() >= usagePoint) {
await addNewPointHistory(-1 * usagePoint);
console.log('currentTotalPoint: ', await getCurrentTotalPoint());
}
await lock.release();
} catch (err) {
console.error("There was an error:", err.message);
} finally {
await redis1.disconnect();
await redis2.disconnect();
await redis3.disconnect();
}
}
for (let i = 0; i < 10; i++) {
purchase(3000);
}
redlock Starting...
redlock Starting...
redlock Starting...
redlock Starting...
redlock Starting...
redlock Starting...
redlock Starting...
redlock Starting...
redlock Starting...
redlock Starting...
currentTotalPoint: 2000
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
There was an error: The operation was unable to achieve a quorum during its retry window.
참고)