Contents

[DATABASE] Control Concurrency in distributed system with Distributed Lock mechanism

๊ฐœ์š”

ํŒ”๋กœ์šฐ/์–ธํŒ”, ๋”ฐ๋‹ฅ์œผ๋กœ ์ธํ•œ ์ค‘๋ณต๋ฐ์ดํ„ฐ ์ƒ์„ฑ, ์•„์ด์œ  ํ‹ฐ์ผ“ ๊ฒฐ์ œํ•˜๊ธฐ ๋“ฑ ๋ฐฑ์—”๋“œ์—์„  ๋™์‹œ์„ฑ ๋ฌธ์ œ๋‚˜ ๊ฐ™์€ ์š”์ฒญ์ด ์—ฌ๋Ÿฌ๋ฒˆ ์˜ค๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ์ด๋Ÿฌํ•œ ์ผ€์ด์Šค๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๋กœ์ง ๋‚ด์—์„œ validation ์„ ์ž˜ํ•˜์—ฌ ์ค‘๋ณต๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค๋˜์ง€ DB ํ•„๋“œ์— ์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ค‘๋ณต๋ฐ์ดํ„ฐ๋ฅผ DB ์ฟผ๋ฆฌ๋‹จ์—์„œ ๋ง‰์•„์ค€๋‹ค๋˜์ง€๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค๊ฐ€ ์—ฌ๋Ÿฌ๋Œ€์ด๊ณ  ๋งŽ์€ ์š”์ฒญ์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ์ด๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๊ธฐ๋Š” ์–ด๋ ต๋‹ค. ์ด๋Ÿฌํ•œ ์ผ€์ด์Šค๋ฅผ ์„œ๋น„์Šค ๋กœ์ง ๋‚ด์—์„œ ๋ง‰๊ธฐ์ „์— ๊ทธ ์•ž๋‹จ์—์„œ ๋ฝ์„ ํš๋“ํ•œ ์š”์ฒญ์— ๋Œ€ํ•ด์„œ๋งŒ operation ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๊ณ ์ž ํ•œ๋‹ค.

๊ฐ ์–ธ์–ด๋งˆ๋‹ค ๋ถ„์‚ฐ๋ฝ์„ ๊ตฌํ˜„ํ•˜๋Š” ์œ ๋ช…ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค์Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋งˆ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ๋ถ„์‚ฐ๋ฝ์˜ ๊ตฌํ˜„์€ ์กฐ๊ธˆ ์ฐจ์ด๊ฐ€ ์žˆ๊ณ , ์šฐ๋ฆฌ ์„œ๋น„์Šค์— ํ˜„์žฌ๋กœ์„œ ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๋ถ„์‚ฐ๋ฝ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค. ๋ชจ๋“  trade-off ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ์Œ

๋ถ„์‚ฐ๋ฝ์„ ๋งŒ์กฑํ•˜๋Š” ์†์„ฑ

  1. safety property : 1๊ฐœ์˜ client ๋งŒ์ด lock์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•˜๋Š” ์†์„ฑ์„ ์˜๋ฏธํ•œ๋‹ค.
  2. liveness property A : lock์„ ํš๋“ํ•œ ์š”์ฒญ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์š”์ฒญ์ด lock์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•˜๋Š” ์†์„ฑ์„ ์˜๋ฏธํ•œ๋‹ค.
  3. liveness property B : ์—ฌ๋Ÿฌ๊ฐœ์˜ redis instance๋ฅผ ์šด์˜ํ•˜๋Š” ๊ฒฝ์šฐ, ํ•˜๋‚˜์˜ redis instance์—์„œ ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„, ๋‚˜๋จธ์ง€ ์ธ์Šคํ„ด์Šค ์‚ฌ์ด์—์„œ์˜ ๋ถ„์‚ฐ๋ฝ์€ ์ •์ƒ์ ์œผ๋กœ ์šด์˜๋˜์–ด์•ผ ํ•จ์„ ์˜๋ฏธํ•œ๋‹ค. (Fault tolerance)

๊ฐ„๋‹จํ•œ ๋ถ„์‚ฐ๋ฝ ๊ตฌํ˜„

  1. ๋ฝ์„ ํš๋“ํ•œ๋‹ค.
  2. ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  3. ๋ฝ์„ ๋ฆด๋ฆฌ์ฆˆํ•œ๋‹ค.

๋ถ„์‚ฐ๋ฝ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๊ณผ์ •์œผ๋กœ ์œ„์™€ ๊ฐ™๋‹ค. ๋จผ์ € ๋ฝ์„ ํš๋“ํ•˜๋Š” ๊ตฌ๊ฐ„์—์„ , SET lockKey my_random_value NX PX 30000 ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ, lockKey ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋‹ค๋ฉด, 30000ms ๋™์•ˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์ค˜ ์ด๋ ‡๊ฒŒ ๋ฝ์„ ํš๋“ํ•˜๊ณ  ๋‚˜์„œ๋Š”, ๋™์‹œ์„ฑ์ด ๋ฐœ์ƒํ• ๋งŒํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ lua script ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฝ์„ ํ•ด์ œํ•˜๊ฑฐ๋‚˜ ์ž์‹ ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” redis library api ๋ฅผ ์ด์šฉํ•ด lockKey ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@Injectable()
export class LockService {
  constructor(@InjectRedis() private readonly redisService: Redis) {}

  async acquireLock(lockName: string, timeout = 10000): Promise<boolean> {
    try {
      const result = await this.redisService.set(
        lockName,
        "OK",
        "PX",
        timeout,
        "NX"
      );
      return result === "OK";
    } catch (err) {
      console.log("acquireLock", err);
      throw err;
    }
  }

  async releaseLock(lockName: string): Promise<void> {
    try {
      const script = `
        if redis.call("get", KEYS[1]) == 'OK' then
            return redis.call("del", KEYS[1])
        else
            return 0
        end
      `;
      const result = await this.redisService.eval(script, 1, lockName);
      console.log(result);
      return;
    } catch (err) {
      console.log("releaseLock", err);
      throw err;
    }
  }
}

// client.ts
if (!(await acquireLock("some-lockKey", 30000))) {
  throw LockAcquiredFailError();
}

// do something logic

await releaseLock("some-lockKey");

์œ„์˜ ๊ฒฝ์šฐ, ๋ฝ ํš๋“์— ์‹คํŒจํ•˜๋ฉด ๋ฐ”๋กœ ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์ง€๋งŒ, ์Šคํ•€๋ฝ ๊ฐ™์€ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์„œ ๋ฝ์„ ํš๋“ํ•  ๋•Œ ๊นŒ์ง€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฌดํ•œ์ • ์‹œ๋„ํ•˜๊ฒŒ ํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ๊ฐ๊ฐ ์žฅ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค.
๋งŒ์•ฝ ์Šคํ•€๋ฝ์„ ์‚ฌ์šฉํ•ด์„œ, ์ผ์ • ๊ฐฏ์ˆ˜๋งŒํผ ๋ฝ ํš๋“์„ ์‹œ๋„ํ•˜๋‹ค๊ฐ€ ์‹คํŒจํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž. ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ 1์ดˆ์ •๋„ ๊ฑธ๋ฆฌ๊ฒŒ ๋˜๊ณ , 100๊ฐœ์˜ ์š”์ฒญ์ด 50ms ๋งˆ๋‹ค lock์„ ํš๋“ํ•˜๋ ค ํ•œ๋‹ค๋ฉด, 2000๋ฒˆ์˜ ์š”์ฒญ์ด ๋ ˆ๋””์Šค ์„œ๋ฒ„์— ๋“ค์–ด์˜ค๊ฒŒ ๋œ๋‹ค. ์š”์ฒญ์˜ ๊ฐฏ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ• ์ˆ˜๋ก ์„ ํ˜•์ ์œผ๋กœ ๋ ˆ๋””์Šค์˜ ๋ถ€ํ•˜๋Š” ์ปค์ง€๊ฒŒ ๋œ๋‹ค. (pubsub ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด ๋ฝ์„ ํš๋“ํ•˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์š”์ฒญ์— ์•Œ๋ฆผ์„ ์คŒ์œผ๋กœ์จ ๋ถ€ํ•˜๋ฅผ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.)
๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ์—๋„ ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฒคํŠธ์— ์ฐธ์—ฌํ•˜๋ ค๋Š” ์š”์ฒญ์„ ์—ฌ๋Ÿฌ๋ฒˆ ๋ณด๋‚ธ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ ์ค‘ ํ•˜๋‚˜๋งŒ ์„ฑ๊ณตํ•˜๊ฒŒ ๋˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ์—๋Ÿฌ๋ฅผ ๋˜์ง€๊ฒŒ ๋˜๋ฏ€๋กœ ์ด ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์—๋Ÿฌ ํ•ธ๋“ค๋ง ์ฝ”๋“œ๊ฐ€ ๋Š˜์–ด๋‚˜๊ฒŒ ๋œ๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค.

์ถ”๊ฐ€๋กœ ์œ„ ์ฝ”๋“œ๋Š” single instance ์— ๋Œ€ํ•œ ๋ถ„์‚ฐ๋ฝ์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ ๋ ˆ๋””์Šค ์„œ๋ฒ„์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ํ•ด๋‹น api ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์š”์ฒญ์€ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์—†๊ฒŒ ๋˜๋ฏ€๋กœ Fault tolerance๋ฅผ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด, single instance์— ๋Œ€ํ•ด์„œ ์œ„์™€ ๊ฐ™์ด exclusive lock ๋˜๋Š” barrier๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด ๋ชจ๋“  ์ค‘๋ณต ๋ฐ์ดํ„ฐ ์ƒ์„ฑ, ๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ?? ๊ทธ๊ฑด ์žฅ๋‹ดํ•  ์ˆ˜ ์—†๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์„ ๊ณ ๋ คํ•ด๋ณด์ž.

์œ„ ์ผ€์ด์Šค์—์„œ, ์ฒซ๋ฒˆ์งธ ์š”์ฒญ์— ๋Œ€ํ•ด ํ‚ค๊ฐ€ ์—†์œผ๋ฉด lockKey์— ๋Œ€ํ•ด ๊ฐ’์„ ์„ธํŒ…ํ•ด์ค˜ ๋ผ๊ณ  ๋ ˆ๋””์Šค ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ธ ๋ฐ”๋กœ ์ฆ‰์‹œ ๋‹ค์Œ ์š”์ฒญ์ด ๊ฐ™์€ lockKey ์— ๋Œ€ํ•ด ์š”์ฒญ์ด ๋ณด๋‚ด์ง„ ์ƒํƒœ์ด๋‹ค. safety property ๋ฅผ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด์„ , ์ฒซ๋ฒˆ์งธ ์š”์ฒญ์˜ ์‘๋‹ต์ด ์˜ค๊ธฐ ์ „์— ๋‘ ๋ฒˆ์งธ ์š”์ฒญ์€ ๋ฝ์„ ํš๋“ํ•˜๋Š”๋ฐ ์‹คํŒจํ•˜์—ฌ์•ผ ํ•˜์ง€๋งŒ, ์•„์ฃผ ์ž‘์€ ํƒ€์ด๋ฐ์— ๊ฐ™์€ ์š”์ฒญ์„ ๋‘ ๋ฒˆ ๋ณด๋‚ด๊ฒŒ ๋˜๊ณ  ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ๋Š” ๋™์ผํ•œ 2๊ฐœ์˜ ๋ฝ์„ ์žก๊ณ  ํŠน์ • ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. ๋ถ„์‚ฐ๋ฝ์—์„œ ์กฐ์‹ฌํ•ด์•ผ ํ•  ์ ์€, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ ๋™์‹œ์„ฑ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ ๋ ˆ๋””์Šค๋ฅผ ์ด์šฉํ•ด ๋ถ„์‚ฐ๋ฝ์„ ๊ตฌํ˜„ํ–ˆ์ง€๋งŒ, ๋ ˆ๋””์Šค ๋ถ„์‚ฐ๋ฝ์˜ ๋™์‹œ์„ฑ๊นŒ์ง€ ์žก์•„์ค˜์•ผ ํ•œ๋‹ค๋Š” ๊ด€๋ฆฌ ํฌ์ธํŠธ๊ฐ€ ํ•˜๋‚˜ ๋” ์ƒ๊ธฐ๊ฒŒ ๋œ๋‹ค.

๋˜ํ•œ, ๋ ˆ๋””์Šค ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์šด์˜์ค‘์ด๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋œ๋‹ค.

client 1์ด ๋ฝ์„ ํš๋“ํ•˜๋‹ค๊ฐ€, master node์—์„œ ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•ด slave node ๊ฐ€ master node ๋กœ ์Šน๊ฒฉ๋˜๋Š” ์ƒํ™ฉ์„ ๊ฐ€์ •ํ•ด๋ณด์ž. ์ด ์ˆœ๊ฐ„, ๋ฐ์ดํ„ฐ์˜ ๋ณต์ œ๋Š” ์ง€์—ฐ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด client2์˜ ๋ฝ ํš๋“ ์š”์ฒญ์— ๋Œ€ํ•ด ์„ฑ๊ณต์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

์œ„ 2๊ฐ€์ง€ ์‚ฌ๋ก€์™€ ๊ฐ™์€ ๋ฝ ํš๋“์— ๋Œ€ํ•œ ๋™์‹œ์„ฑ์„ ์žก์•„์ฃผ๊ธฐ ์œ„ํ•ด ๋” ์ •๊ตํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ redlock ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์†Œ๊ฐœํ•˜๊ณ ์ž ํ•œ๋‹ค.

multi instance ์—์„œ ๋ถ„์‚ฐ๋ฝ ๊ตฌํ˜„ - redlock

๋ถ„์‚ฐํ™˜๊ฒฝ์—์„œ lock์„ ํš๋“ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํด๋ผ์ด์–ธํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ๋ จ์˜ ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  1. ๋ฝ ํš๋“์„ ์‹œ๋„ํ•˜๋ ค๊ณ  ํ•˜๋Š” ํ˜„์žฌ ์‹œ๊ฐ(now)๋ฅผ ๋ฐ€๋ฆฌ์ดˆ ๋‹จ์œ„๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.
  2. ๋ชจ๋“  redis์— ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฝ ํš๋“์„ ์š”์ฒญํ•œ๋‹ค.
  3. ๊ฐ ๋ ˆ๋””์Šค์— ๋ฝ ํš๋“์—์„œ์˜ ๊ฑธ๋ฆฐ ์‹œ๊ฐ„์„ ๊ตฌํ•œ๋‹ค.
  4. client ๊ฐ€ Redis ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ์ผ์ • ์ˆ˜์น˜ ์ด์ƒ์˜ ์ž ๊ธˆ์„ ํš๋“ํ•˜๊ณ  ((N+1)/2) , ๋ฝ์„ ํš๋“ํ•˜๊ธฐ๊นŒ์ง€์˜ ์ด ์‹œ๊ฐ„์ด lock-key ์œ ํšจ์‹œ๊ฐ„๋ณด๋‹ค ์ ์€๊ฒฝ์šฐ ๋ฝ์„ ํš๋“ํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.
  5. ๋งŒ์•ฝ client ๊ฐ€ lock์„ ํš๋“ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ๋ชจ๋“  ์ธ์Šคํ„ด์Šค์˜ ์ž ๊ธˆ์„ ํ•ด์ œํ•œ๋‹ค.

note
redlock ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ฐ ํด๋ผ์ด์–ธํŠธ์™€ redis ์„œ๋ฒ„๊ฐ„์˜ ์‹œ๊ณ„๊ฐ€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ๊ฐ€์ •ํ•œ๋‹ค.

์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌด์กฐ๊ฑด safety and liveness property๋ฅผ ๋งŒ์กฑํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€? ๋ผ๊ณ  ์งˆ๋ฌธํ•œ๋‹ค๋ฉด ๊ผญ ๊ทธ๋ ‡์ง€๋Š” ์•Š๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์„ ์ƒ๊ฐํ•ด๋ณด์ž. client A๊ฐ€ redis A,B,D ์—๊ฒŒ ๋ฝ์„ ํš๋“ํ•˜๊ณ , client B๋Š” redis C,E๋กœ ๋ถ€ํ„ฐ ๋ฝ์„ ํš๋“ํ•œ ์ƒํ™ฉ์ด๋‹ค. ์ด ์ƒํ™ฉ์—์„œ redis D์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ client A๊ฐ€ ํš๋“ํ•œ lock-key X๊ฐ€ ํœ˜๋ฐœ๋˜์—ˆ๊ณ , ์žฅ์• ๊ฐ€ ๋ณต๊ตฌ๋˜๋ฉด์„œ client B๊ฐ€ redis D๋กœ ๋ถ€ํ„ฐ lock-key Y ๋ฅผ ํš๋“ํ•˜์˜€๋‹ค. ์ด๋Ÿฐ ์ƒํ™ฉ์—์„  client A, B ๋ชจ๋‘ ๋ฝ์„ ํš๋“ํ•˜์˜€๊ณ  safety property๊ฐ€ ๊นจ์ง€๋Š” ์ƒํ™ฉ์ด๋‹ค.

์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ๋Š”, fsync=always option์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋””์Šคํฌ์— ์“ธ๋•Œ๋งˆ๋‹ค ๊ฐ•์ œ๋กœ ํŒŒ์ผ ์‹œ์Šคํ…œ ์บ์‹œ๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋ฐ”๋กœ ๋””์Šคํฌ์— ๋™๊ธฐํ™”ํ•˜๋„๋ก ์š”๊ตฌํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ๋ชจ๋“  ์“ฐ๊ธฐ ์ž‘์—…์ด ๋””์Šคํฌ์— ์™„์ „ํžˆ ๋™๊ธฐํ™”๋  ๋•Œ๊นŒ์ง€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์ด ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๋„๋ก ๊ฐ•์ œํ•˜์—ฌ ๋ฝ์— ๋Œ€ํ•œ safety ๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํŒŒ์ผ ์‹œ์Šคํ…œ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์“ฐ๊ธฐ์ž‘์—…์˜ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง€๊ณ , ์ „์ฒด์ ์ธ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋„๋ฆฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

๊ฒฐ๋ก 

์„œ๋น„์Šค์— ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š” lock์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค. redlock ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋ถ„์‚ฐ๋ฝ์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ์— ์žˆ์–ด์„œ ๊ฐ€์žฅ ๋ณดํŽธ์ ์ด๊ณ  ์•ˆ์ „ํ•˜๋‹ค ! ๋ผ๋Š” ๊ด€์ ์œผ๋กœ ๋‹น์žฅ ์šฐ๋ฆฌ ์„œ๋น„์Šค์— ์ ์šฉ์‹œํ‚ค๊ธฐ์—” ๊ด€๋ฆฌ ํฌ์ธํŠธ๊ฐ€ ๋” ๋Š˜์–ด๋‚œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๊ณ  ๊ทธ๊ฑธ ๋ฐ˜์˜ํ•จ์œผ๋กœ์จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผํ•˜๋Š” ๊ตฌ๋ฉ์ด ๋” ์ƒ๊ฒจ๋‚˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ๋‹ค. ๊ฐ€์žฅ ์ข‹์€ ๊ฒƒ์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ validation์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ž˜ํ•˜๊ณ  ๊ทธ๊ฑธ๋กœ๋„ ๋™์‹œ์„ฑ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ์šฐ๋ฆฌ ์„œ๋น„์Šค์— ๋งž๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ถ„์‚ฐ๋ฝ ๊ตฌํ˜„์„ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.