Skip to content

Latest commit

ย 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

massive-board-learning

Inflearn Lecture Link

ํ•™์Šต ๋ชฉํ‘œ ยท ๋ชฉ์ฐจ

  1. ๋Œ€๊ทœ๋ชจ ์‹œ์Šคํ…œ์˜ ๋ณธ์งˆ
    1. ๋ฌธ์ œ ์ƒํ™ฉ ยท ์ •์˜
    2. ๊ธฐ์ˆ ์  ยท ๋น„๊ธฐ์ˆ ์  ์š”๊ตฌ์‚ฌํ•ญ
    3. CAP ์ •๋ฆฌ
    4. ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ vs. ์ตœ์ข… ์ผ๊ด€์„ฑ
    5. ๋ณ‘๋ชฉ์˜ ์‹๋ณ„ ์ „๋žต
    6. ์žฅ์•  ์ „ํŒŒ ๋ฐฉ์‹
  2. ํŠธ๋ž˜ํ”ฝ ํŠน์„ฑ์— ๋”ฐ๋ฅธ ์„ค๊ณ„ ์ „๋žต
    1. ์ฝ๊ธฐ ยท ์“ฐ๊ธฐ ํŠธ๋ž˜ํ”ฝ์ด ๋น„๋Œ€์นญ์ ์ธ ์ƒํ™ฉ์˜ ์„ค๊ณ„
    2. CQRS
    3. ์บ์‹œ ์ „๋žต
    4. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ
    5. Projection ์„ค๊ณ„ ์ „๋žต
  3. ์•„ํ‚คํ…์ฒ˜์˜ ์„ ํƒ
    1. ๋ชจ๋†€๋ฆฌ์‹ vs. MSA
  4. ๋ฐ์ดํ„ฐ ๊ณ„์ธต ์„ค๊ณ„
    1. RDB | MySQL
      1. ์Šคํ‚ค๋งˆ ์„ค๊ณ„
      2. ์ธ๋ฑ์‹ฑ ์ „๋žต
      3. ์ƒค๋”ฉ ์ „๋žต
      4. ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ์˜ ์œ ์ผ์„ฑ ๋ณด์žฅ
      5. ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
    2. In-Memory | Redis
      1. ์บ์‹ฑ ๋Œ€์ƒ ๋ฐ์ดํ„ฐ ์„ ์ •
      2. ๊ณ ๋ ค์‚ฌํ•ญ
      3. ๊ตฌํ˜„
  5. Message Broker | Kafka
    1. ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์˜ ์—ญํ• 
    2. ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์˜ ํ•„์š”์„ฑ
    3. ์ „์†ก ๋ณด์žฅ ์ˆ˜์ค€
    4. Transactional Outbox ๊ตฌํ˜„
  6. ์ •ํ•ฉ์„ฑ ์ „๋žต
    1. Consumer ๋ฉฑ๋“ฑ์„ฑ ์„ค๊ณ„

๋Œ€๊ทœ๋ชจ ์‹œ์Šคํ…œ์˜ ๋ณธ์งˆ

๋ฌธ์ œ ์ƒํ™ฉ ยท ์ •์˜

  • ํŠธ๋ž˜ํ”ฝ์ด ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๊ฒŒ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ.
  • ์ผ๋ถ€ ๊ธฐ๋Šฅ์—๋งŒ ๋ถ€ํ•˜๊ฐ€ ์ง‘์ค‘๋  ์ˆ˜ ์žˆ์Œ.
  • ํŠน์ • ์„œ๋น„์Šค์˜ ์žฅ์• ๊ฐ€ ๋‹ค๋ฅธ ์„œ๋น„์Šค์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Œ.
  • ๋ฐ์ดํ„ฐ์˜ ๊ทœ๋ชจ๊ฐ€ ๋‹จ์ผ ์žฅ๋น„์˜ ํ•œ๊ณ„๋ฅผ ์ดˆ๊ณผํ•จ.

๋ณ‘๋ชฉ๊ณผ ์žฅ์•  ์ „ํŒŒ๋ฅผ ์–ด๋–ป๊ฒŒ ํ†ต์ œํ•  ๊ฒƒ์ธ๊ฐ€?

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ•œ๊ณ„

  • Connection ์ˆ˜ ์ œํ•œ.
  • IOPS ์ œํ•œ.
  • SPOF.
  • API ์กฐํ•ฉ ๋น„์šฉ ์ฆ๊ฐ€.

๊ธฐ์ˆ ์  ยท ๋น„๊ธฐ์ˆ ์  ์š”๊ตฌ์‚ฌํ•ญ

๋น„๊ธฐ์ˆ ์  ์š”๊ตฌ์‚ฌํ•ญ

  1. ๊ณ ๊ฐ€์šฉ์„ฑ
    1. SLA ์ถฉ์กฑ.
    2. ์žฅ์•  ๋ฐœ์ƒ ์‹œ ์ž๋™ ๋ณต๊ตฌ ๊ฐ€๋Šฅ.
    3. replication, failover ์ „๋žต.
  2. ํ™•์žฅ์„ฑ
    1. ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€์— ๋”ฐ๋ผ ์ˆ˜ํ‰์ ์œผ๋กœ ํ™•์žฅ ๊ฐ€๋Šฅ.
    2. Stateless ๊ธฐ๋ฐ˜ ์„ค๊ณ„.
    3. ์ƒค๋”ฉ ์ „๋žต ์ˆ˜๋ฆฝ
  3. ๋ณต์žก์„ฑ ํ†ต์ œ
    1. ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๊ฒฝ๊ณ„ ๋ช…ํ™•ํ™”.
    2. ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๊ฐ„ ์ฑ…์ž„์˜ ๋ถ„๋ฆฌ.
    3. ์ด๋ฒคํŠธ ๋ธŒ๋กœ์ปค๋ฅผ ์ด์šฉํ•˜์—ฌ ์ˆœํ™˜ ์ฐธ์กฐ, ๋Ÿฐํƒ€์ž„ ์˜์กด์„ฑ ์ œ๊ฑฐ.
    4. ์กฐ์ง ๊ทœ๋ชจ ์ฆ๊ฐ€์— ๋”ฐ๋ฅธ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ์„ฑ์˜ ์œ ์ง€.
  4. ์ผ๊ด€์„ฑ
    1. ๋„๋ฉ”์ธ์— ๋”ฐ๋ผ ์ผ๊ด€์„ฑ ์ˆ˜์ค€์„ ๋‹ค๋ฅด๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Œ.

๊ธฐ์ˆ ์  ์š”๊ตฌ์‚ฌํ•ญ

  1. ์ฝ๊ธฐ ยท ์“ฐ๊ธฐ ๋ถ„๋ฆฌ
    1. CQRS.
    2. Query Model ๊ตฌ์„ฑ.
    3. Redis ์บ์‹ฑ.
  2. ๋น„๋™๊ธฐ ๋ฉ”์‹œ์ง•
    1. ๋ฉ”์‹œ์ง€ ๋ฐœํ–‰ ๋ณด์žฅ.
    2. ์„œ๋น„์Šค ๊ฐ„ ์ง์ ‘ ์˜์กด์„ฑ ๊ฐ์†Œ.
    3. ์žฅ์•  ์ „ํŒŒ ์ฐจ๋‹จ.
    4. ์ตœ์ข… ์ผ๊ด€์„ฑ ๋ณด์žฅ.
  3. ๋ฐ์ดํ„ฐ ํ™•์žฅ ์ „๋žต
    1. Horizontal Sharding.
    2. ๋ถ„์‚ฐ PK ์ „๋žต.
  4. ๋™์‹œ์„ฑ ์ œ์–ด
    1. ๋„๋ฉ”์ธ์— ๋”ฐ๋ผ ์ดํ•˜์˜ ๋ฐฉ์‹ ์ค‘ ์„ ํƒ.
      1. ๋น„๊ด€์  ๋ฝ.
      2. ๋‚™๊ด€์  ๋ฝ.
      3. ๋น„๋™๊ธฐ ์ง๋ ฌํ™” ์ฒ˜๋ฆฌ.
  5. ์บ์‹ฑ ์ „๋žต
    1. ๋„๋ฉ”์ธ์— ๋”ฐ๋ผ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ์ ์šฉ.
    2. ๋„๋ฉ”์ธ์— ๋”ฐ๋ผ Cache-Aside ์ ์šฉ
    3. TTL ํ™œ์šฉ.
    4. Cache Stampede ์ œ์–ดํ•  ๊ฒƒ.

CAP ์ •๋ฆฌ

๋ถ„์‚ฐ ์‹œ์Šคํ…œ์˜ ํ•œ๊ณ„

๋ถ„์‚ฐ ์‹œ์Šคํ…œ์€ ์ดํ•˜์˜ ์†์„ฑ์„ ์ „๋ถ€ ์˜จ์ „ํžˆ ์ถฉ์กฑ์‹œํ‚ฌ ์ˆ˜ ์—†์Œ. ์ถ”๊ฐ€์ ์œผ๋กœ, Partition Tolerance์˜ ๊ฒฝ์šฐ, ๋„คํŠธ์›Œํฌ ๋‹จ์ ˆ์ด ์–ธ์ œ๋“ ์ง€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ์Šคํ…œ์˜ ํŠน์„ฑ์„ ๊ณ ๋ คํ•  ๋•Œ, ์‹œ์Šคํ…œ์˜ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ํ•„์ˆ˜๋ถˆ๊ฐ€๊ฒฐํ•œ ํŠน์„ฑ์ž„. Consistency์™€ Availability ์ค‘ ๋„๋ฉ”์ธ ํŠน์„ฑ์— ๋งž์ถฐ ์กฐ์ ˆํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ.

Consistency(C)

  • ์„ ํ–‰๋œ ์“ฐ๊ธฐ๊ฐ€ ๋ชจ๋“  ํ›„ํ–‰ ์ฝ๊ธฐ์— ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์˜๋จ. | ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ
  • ์‚ฌ์šฉ์ž๋Š” ํ•ญ์ƒ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Œ.

Availability(A)

  • ์ผ๋ถ€ ๋…ธ๋“œ์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ์‹œ์Šคํ…œ์€ ๊ณ„์† ์‘๋‹ตํ•ด์•ผ ํ•จ.
  • ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•จ.

Partition Tolerance(P)

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

Partition Tolerance์˜ ๊ตฌํ˜„ ์ „๋žต

ํ•„์š”์„ฑ

  • ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜์—์„œ๋Š” ๋ฉ”์‹œ์ง€์˜ ๋ฐœํ–‰๊ณผ DB์˜ ํŠธ๋žœ์žญ์…˜์ด ์›์ž์„ฑ์„ ๊ฐ€์ง€์ง€ ์•Š์Œ.
  • ๋„คํŠธ์›Œํฌ ์œ ์‹ค์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, ๋ฉ”์‹œ์ง€์˜ ๋ฐœํ–‰ ๋˜๋Š” DB์˜ ํŠธ๋žœ์žญ์…˜์ด ์‹คํŒจํ•˜์—ฌ ์‹œ์Šคํ…œ ๊ฐ„ ๋ถˆ์ผ์น˜๊ฐ€ ์•ผ๊ธฐ๋จ.
  • ๋„คํŠธ์›Œํฌ ์žฅ์•  ์ƒํ™ฉ์—์„œ๋„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์ˆ˜ํ–‰ํ•˜๋˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ตœ์ข…์ ์œผ๋กœ ์ „๋‹ฌํ•˜๋Š”(At-least-once delivery) ์„ค๊ณ„๊ฐ€ ํ•„์ˆ˜์ ์ž„ | ์ตœ์ข… ์ผ๊ด€์„ฑ

์ „๋žต

2-Phase Commit (๊ฐ•ํ•œ ์ผ๊ด€์„ฑ ๋ชจ๋ธ, ๋น„์ฑ„ํƒ)
  1. Prepare Phase
    1. Coordinator๊ฐ€ ๋ชจ๋“  Participant์—๊ฒŒ ์ค€๋น„ ์ƒํƒœ๋ฅผ ์ฟผ๋ฆฌํ•จ.
    2. Participant๋Š” ๋กœ์ปฌ ํŠธ๋žœ์žญ์…˜ ํ›„, ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  Lock.
    3. ์ค€๋น„๊ฐ€ ๋˜์—ˆ์„ ๊ฒฝ์šฐ Yes, ์•„๋‹ˆ๋ฉด No.
  2. Commit Phase
    1. ๋ชจ๋“  Participant๊ฐ€ Yes๋ผ๊ณ  ์‘๋‹ตํ•  ๊ฒฝ์šฐ, Coordinator๊ฐ€ Commit ๋ช…๋ น์„ ๋‚ด๋ฆผ. ๋‹จ ํ•˜๋‚˜๋ผ๋„ No, ๋˜๋Š” Timeout์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ Rollback.
    2. Participant๋Š” Coordinator์˜ ๋ช…๋ น์— ๋”ฐ๋ผ ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜ ๋กค๋ฐฑํ•จ.
    3. ๋ชจ๋“  ๋ณด๊ณ ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋จ.
  • Coordinator๊ฐ€ SPOF๋กœ ๊ธฐ๋Šฅํ•จ.
  • ์‘๋‹ต ์†๋„๊ฐ€ ๋Šฆ์œผ๋ฉฐ, ์‹œ์Šคํ…œ์˜ ๊ฐ€์šฉ์„ฑ์ด ๋‚ฎ์•„์ง.
  • ์ธํ”„๋ผ ๋‹จ์—์„œ์˜ ์ง€์› ํ•„์š”ํ•จ.
  • Lock ์ ์œ  ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚จ.

Transactional Outbox (์ตœ์ข… ์ผ๊ด€์„ฑ ๋ชจ๋ธ, ์ฑ„ํƒ)

  1. ์„œ๋ฒ„๊ฐ€ ์ด๋ฒคํŠธ ๋งค๋‹ˆ์ €๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰ํ•˜๊ธฐ ์ด์ „์—, ์„œ๋ฒ„๊ฐ€ DB์˜ Outbox ํ…Œ์ด๋ธ”์— ์ด๋ฒคํŠธ ์ „์†ก ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.
  2. Message Relay | common:outbox-message-relay
    1. ๋ณ„๋„์˜ Message Relay ํ”„๋กœ์„ธ์Šค๊ฐ€ Outbox ํ…Œ์ด๋ธ”์„ ํด๋งํ•˜์—ฌ ์ด๋ฒคํŠธ ๋งค๋‹ˆ์ €๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•œ๋‹ค.
    2. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœํ–‰๋˜์—ˆ์„ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.
  3. Transaction Log Tailing(CDC)
    1. DB๊ฐ€ ๊ฐ ํŠธ๋žœ์žญ์…˜์˜ ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•œ๋‹ค. ๋ณ„๋„์˜ ์—์ด์ „ํŠธ๊ฐ€ ๋กœ๊ทธ๋ฅผ ์ถ”์ ํ•˜๋‹ค๊ฐ€ Outbox ํ…Œ์ด๋ธ”์— ๋กœ๊ทธ๊ฐ€ ๊ธฐ๋ก๋  ๊ฒฝ์šฐ, ๊ฐ์ง€ํ•˜๊ณ  ์‹คํ–‰ํ•œ๋‹ค.
Transactional Outbox ํŠน์ง•
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹จ์—์„œ์˜ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•จ.
  • 2PC ๊ธฐ๋ฒ•์— ๋น„ํ•˜์—ฌ, ์‘๋‹ต์†๋„๊ฐ€ ์šฐ์ˆ˜ํ•˜๊ณ  ๊ฐ€์šฉ์„ฑ์ด ๋†’์Œ | ์ตœ์ข… ์ผ๊ด€์„ฑ
  • ์ด๋ฒคํŠธ์˜ ๋ฐœํ–‰๊ณผ Consumer๊ฐ€ ์ฒ˜๋ฆฌํ•˜๊ธฐ๊นŒ์ง€ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.
  • ๋ชจ๋“  ๋ฉ”์‹œ์ง€์˜ ์ตœ์†Œ ํ•œ ๋ฒˆ์˜ ๋ฐœํ–‰์„ ๋ณด์žฅํ•จ.
  • ์žฌ์‹œ๋„ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ์ธํ•œ ์ค‘๋ณต๋ฐœํ–‰์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด Consumer ์ธก์—์„œ ๋ณ„๋„์˜ ๋ฉฑ๋“ฑ์„ฑ ์„ค๊ณ„๊ฐ€ ํ•„์š”ํ•จ.
Message Relay ํŠน์ง•
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹จ์—์„œ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•จ.
  • DB๋กœ๋ถ€ํ„ฐ ๋…๋ฆฝ์ ์ž„.
  • ๋ฉ”์‹œ์ง€๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Œ.
  • DB์— ์ง€์†์ ์ธ ๋ถ€ํ•˜๋ฅผ ์œ ๋ฐœํ•จ.
  • ์‹ค์‹œ๊ฐ„์„ฑ ๋‚ฎ์Œ.

์ ์šฉ

์ข‹์•„์š” | service:like

  • ์„œ๋น„์Šค ๋‚ด๋ถ€์ ์ธ ์›์ž์„ฑ ยท ์œ ํšจ์„ฑ ์ฒดํฌ.
  • ๋„คํŠธ์›Œํฌ ์œ ์‹ค ์ƒํ™ฉ์—์„œ๋„ At-least-once ๋ฐœํ–‰์„ ๋ณด์žฅํ•˜์—ฌ ์ตœ์ข… ์ผ๊ด€์„ฑ ๋ณด์žฅ.

์„œ๋น„์Šค ๋‚ด๋ถ€์ ์ธ ์ตœ์ข… ์ผ๊ด€์„ฑ ๋ณด์žฅ, ์‹œ์Šคํ…œ ๊ด€์ ์—์„œ ์ตœ์ข… ์ผ๊ด€์„ฑ.

์กฐํšŒ์ˆ˜ | service:view

  • Redis๋ฅผ ์ฃผ ์ €์žฅ์†Œ๋กœ, RDB๋ฅผ ๋ฐฑ์—…์œผ๋กœ ํ™œ์šฉ.
  • ๊ณ ๋นˆ๋„ ์“ฐ๊ธฐ ์ž‘์—…์œผ๋กœ ์ธํ•œ Write-Back + ๋ฐฐ์น˜ ์ „๋žต.
  • ์ •ํ•ฉ์„ฑ๋ณด๋‹ค ์‹œ์Šคํ…œ ๊ฐ€์šฉ์„ฑ๊ณผ ์‘๋‹ต ์†๋„๋ฅผ ์šฐ์„ ์‹œํ•˜์—ฌ ์•ฝ๊ฐ„์˜ ์˜ค์ฐจ ํ—ˆ์šฉ.

๊ณต๊ฒฉ์ ์ธ AP ์ถ”๊ตฌ, ์ตœ์ข… ์ผ๊ด€์„ฑ.

์ธ๊ธฐ๊ธ€ ์ง‘๊ณ„ | service:hot-article

  • ๊ฐ€์ค‘์น˜ ๊ธฐ๋ฐ˜ ์Šค์ฝ”์–ด๋ง ์ ์šฉ.
  • ์‹ค์‹œ๊ฐ„ JOIN ๋Œ€์‹ , ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ ์†Œ๋น„๋ฅผ ํ†ตํ•œ ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ.

์‹œ์Šคํ…œ ์ „์ฒด์˜ ์ฒ˜๋ฆฌ๋Ÿ‰ ยท ์ฝ๊ธฐ ์„ฑ๋Šฅ ๊ทน๋Œ€ํ™”๋ฅผ ์œ„ํ•ด ์ตœ์ข… ์ผ๊ด€์„ฑ.

๊ฐ•ํ•œ ์ผ๊ด€์„ฑ vs. ์ตœ์ข… ์ผ๊ด€์„ฑ

๊ฐ•ํ•œ ์ผ๊ด€์„ฑ (Strong Consistency)

  • ์“ฐ๊ธฐ ์™„๋ฃŒ ํ›„, ๋ชจ๋“  ์ฝ๊ธฐ๋Š” ์ตœ์‹  ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•จ.
  • ์“ฐ๊ธฐ ์™„๋ฃŒ ํ›„, ์ดํ›„์˜ ๋ชจ๋“  ์ฝ๊ธฐ์— ๋Œ€ํ•ด ์ ์šฉ๋จ.
  • ๋ฝ, ๋™๊ธฐํ™” ๋น„์šฉ ๋ฐœ์ƒ.
  • ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅ.
  • ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ค๊ณ , ํ™•์žฅ ๋น„์šฉ ์ฆ๋Œ€.
  • ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ ๊ตฌํ˜„ ๋‚œ์ด๋„๊ฐ€ ๋†’์Œ.

์ตœ์ข… ์ผ๊ด€์„ฑ (Eventual Consistency)

  • ์ผ์‹œ์ ์ธ ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜๋ฅผ ํ—ˆ์šฉํ•˜๊ณ , ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ˆ˜๋ ดํ•จ.
  • ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์ฆ‰์‹œ ์ˆ˜์ •๋˜์ง€ ์•Š์„์ˆ˜๋„ ์žˆ์Œ.
  • ๋น„๋™๊ธฐ ๊ธฐ๋ฐ˜.
  • ํ™•์žฅ์„ฑ์ด ๋†’๊ณ , ๊ฐ€์šฉ์„ฑ์ด ๋†’์Œ.
  • ๋„คํŠธ์›Œํฌ๊ฐ€ ๋‹จ์ ˆ๋œ ์ƒํ™ฉ์—์„œ ์œ ๋ฆฌํ•จ.
  • ์ผ์‹œ์ ์œผ๋กœ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ์„ค๊ณ„๊ฐ€ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Œ.

์ ์šฉ

๋„๋ฉ”์ธ ์ผ๊ด€์„ฑ ์ˆ˜์ค€ ์‚ฌ์œ 
๊ฒŒ์‹œ๊ธ€ ์ƒ์„ฑ ์‹œ์Šคํ…œ ์ฐจ์›์˜ ์ตœ์ข… ์ผ๊ด€์„ฑ.
๋‹ค๋งŒ, ์„œ๋น„์Šค ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ ๋ณด์žฅํ•จ.
์„œ๋น„์Šค ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” @Transactional
์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•˜์—ฌ DB์™€ ์ง์ ‘ ํ†ต์‹ ํ•˜๋‚˜, ์กฐํšŒ๋Š” ๋ณ„๋„์˜ ์„œ๋น„์Šค๊ฐ€ ๋‹ด๋‹นํ•˜์—ฌ(ํ›„์ˆ ) ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ. ์กฐํšŒ ๊ด€์ ์—์„œ๋Š” Transactional Outbox ํŒจํ„ด์œผ๋กœ ์ตœ์ข… ์ผ๊ด€์„ฑ ๋ณด์žฅํ•จ.
์ข‹์•„์š” ์‹œ์Šคํ…œ ์ฐจ์›์˜ ์ตœ์ข… ์ผ๊ด€์„ฑ.
๋‹ค๋งŒ, ์„œ๋น„์Šค ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ ๋ณด์žฅํ•จ.
์„œ๋น„์Šค ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” @Transactional
์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•˜์—ฌ DB์™€ ์ง์ ‘ ํ†ต์‹ ํ•˜๋‚˜, ์กฐํšŒ๋Š” ๋ณ„๋„์˜ ์„œ๋น„์Šค๊ฐ€ ๋‹ด๋‹นํ•˜์—ฌ(ํ›„์ˆ ) ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ. ์กฐํšŒ ๊ด€์ ์—์„œ๋Š” Transactional Outbox ํŒจํ„ด์œผ๋กœ ์ตœ์ข… ์ผ๊ด€์„ฑ ๋ณด์žฅํ•จ.
์กฐํšŒ์ˆ˜ ์ตœ์ข… ์ผ๊ด€์„ฑ,
๋‹ค๋งŒ, ์กฐํšŒ ์‹œ์ ์— Redis
์‹ค์‹œ๊ฐ„์œผ๋กœ ์ฐธ์กฐํ•จ.
์กฐํšŒ์ˆ˜ ํŠน์„ฑ์ƒ ์“ฐ๊ธฐ ๋นˆ๋„๊ฐ€ ๋งค์šฐ ๋†’์•„ ์ฝ๊ธฐ ๋ชจ๋ธ์— ํฌํ•จํ•  ๊ฒฝ์šฐ ์บ์‹œ ๋ฌดํšจํ™” ๋น„์šฉ์ด ๊ณผ๋‹คํ•˜๋ฏ€๋กœ, Redis๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•จ.
์ธ๊ธฐ๊ธ€ ์ตœ์ข… ์ผ๊ด€์„ฑ ์—ฌ๋Ÿฌ ๋„๋ฉ”์ธ์˜ ์ด๋ฒคํŠธ๋ฅผ ์†Œ๋น„ํ•˜์—ฌ ์Šค์ฝ”์–ด๋ง์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ๋ฐ์ดํ„ฐ ๋ฐ˜์˜์— ์ง€์—ฐ ๋ฐœ์ƒ.

๊ตฌํ˜„

๊ฐ•ํ•œ ์ผ๊ด€์„ฑ

  • @Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ(์นด์šดํŠธ), Outbox ๊ธฐ๋ก์„ ํ•˜๋‚˜์˜ ์›์ž์  ์ž‘์—…์œผ๋กœ ๋ฌถ์Œ.
  • ArticleLikeService ๋“ฑ์—์„œ ๋น„๊ด€์  ๋ฝ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผ ์ž์›์— ๋Œ€ํ•œ ๊ฒฝํ•ฉ ๋ฐœ์ƒ ์‹œ์—๋„ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์„ ๊ฐ•์ œํ•จ.

์ตœ์ข… ์ผ๊ด€์„ฑ

  • ์ด๋ฒคํŠธ ๋ฐœํ–‰์„ ์™ธ๋ถ€ ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค๊ฐ€ ์•„๋‹Œ ๋กœ์ปฌ DB์˜ Outbox ํ…Œ์ด๋ธ”์— ์œ„์ž„ํ•˜์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ์˜ ์›์ž์„ฑ์„ ํ™•๋ณดํ•จ.
  • AFTER_COMMIT ์‹œ์ ์˜ ์ฆ‰์‹œ ๋ฐœํ–‰๊ณผ ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ํ†ตํ•œ ๋ฏธ๋ฐœํ–‰ ๋ฐ์ดํ„ฐ ์žฌ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด, ๋„คํŠธ์›Œํฌ ์žฅ์•  ์ƒํ™ฉ์—์„œ๋„ At-least-once์„ ๋ณด์žฅํ•จ.

์ •๋ฆฌ

๋„๋ฉ”์ธ ํŠน์„ฑ๊ณผ ์„œ๋น„์Šค ๊ฐ„์˜ ํ†ต์‹  ์—ฌ๋ถ€ ๋“ฑ์— ๋”ฐ๋ผ, ์ผ๊ด€์„ฑ์˜ ์ˆ˜์ค€์„ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ์Œ.

๋ณ‘๋ชฉ์˜ ์‹๋ณ„ ์ „๋žต

๋ณ‘๋ชฉ์˜ ์ข…๋ฅ˜ #1

CPU ๋ณ‘๋ชฉ

  • ์„œ๋ฒ„์˜ ์—ฐ์‚ฐ๋Ÿ‰ ๊ณผ๋‹ค.
  • JSON ์ง๋ ฌํ™” ยท ์—ญ์ง๋ ฌํ™” ๋น„์šฉ ๋ˆ„์ .
  • ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง.

๋ฉ”๋ชจ๋ฆฌ ๋ณ‘๋ชฉ

  • ์บ์‹œ ๋ฏธ์Šค ์ฆ๊ฐ€.
  • GC ๋นˆ๋„ ์ฆ๊ฐ€.
  • ๊ณผ๋„ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ.

๋„คํŠธ์›Œํฌ ๋ณ‘๋ชฉ

  • ์žฆ์€ DB ํ˜ธ์ถœ.
  • ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๊ฐ„ ํ˜ธ์ถœ.
  • ์™ธ๋ถ€ API ํ˜ธ์ถœ.

๋””์Šคํฌ I/O ๋ณ‘๋ชฉ

  • ์ธ๋ฑ์Šค๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š๋Š” ์ฟผ๋ฆฌ.
  • ์ง‘๊ณ„ ์ฟผ๋ฆฌ ๊ณผ๋‹ค.
  • Full Table Scan

๋ณ‘๋ชฉ์˜ ์ข…๋ฅ˜ #2

์กฐํšŒ์ˆ˜ ์ฆ๊ฐ€ ๋กœ์ง

  • ๋งค ์š”์ฒญ๋งˆ๋‹ค UPDATE ์ฟผ๋ฆฌ ๋ฐœ์ƒ.
  • ๋‹ค์ˆ˜์˜ ๋…ธ๋“œ์—์„œ ๋™์ผํ•œ ํ–‰์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐœ์ƒ.

Redis ๊ธฐ๋ฐ˜ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ๋กœ ์™„ํ™” ๊ฐ€๋Šฅ.

์ธ๊ธฐ๊ธ€ ์ง‘๊ณ„ ์ฟผ๋ฆฌ

  • SELECT GROUP BY, ORDER BY, LIMIT ์ ˆ ์ฟผ๋ฆฌ ๋ฐœ์ƒ.
  • ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ ์Šค์บ”.
  • ๋””์Šคํฌ I/O ์ง‘์ค‘.

์ŠคํŠธ๋ฆผ ยท ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ ยท ๋น„์ •๊ทœํ™” ยท ์บ์‹ฑ ํ™œ์šฉํ•˜์—ฌ ์™„ํ™” ๊ฐ€๋Šฅ.

์ข‹์•„์š” ์ฒ˜๋ฆฌ

  • ์ค‘๋ณต ๋ฐฉ์ง€ ๋กœ์ง ํ•„์š”ํ•จ.
  • ํŠธ๋žœ์žญ์…˜ ์ถฉ๋Œ.
  • ์ธ๋ฑ์Šค ์„ค๊ณ„์— ๋”ฐ๋ผ ์„ฑ๋Šฅ ์ €ํ•˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ.

๋ณ‘๋ชฉ ์‹๋ณ„ ๋ฐฉ๋ฒ•

์ง€ํ‘œ ์ˆ˜์ง‘

  • CPU ์‚ฌ์šฉ๋ฅ .
  • ๋ฉ”๋ชจ๋ฆฌ ๋ถ€ํ•˜.
  • DB ์ปค๋„ฅ์…˜ ์ˆ˜.
  • SLOW QUERY ๋กœ๊ทธ.

๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ

  • TPS ยท QPS ์ธก์ •.
  • ์ž„๊ณ„์  ํŒŒ์•….

๋กœ๊ทธ ๊ธฐ๋ฐ˜ ๋ถ„์„

  • ํŠน์ • API์— ๋Œ€ํ•œ ์‘๋‹ต ์ง€์—ฐ.
  • ํƒ€์ž„์•„์›ƒ ๋ฐœ์ƒ ๊ตฌ๊ฐ„.
  • ์˜ˆ์™ธ ๋นˆ๋„.

์ •๋ฆฌ

ํ™•์žฅ ์ด์ „์— ๋ณ‘๋ชฉ ์ง€์  ์‹๋ณ„ ํ•„์š”ํ•จ.

์žฅ์•  ์ „ํŒŒ ๋ฐฉ์‹

์žฅ์•  ์ „ํŒŒ์˜ ์›์ธ

๋™๊ธฐ ํ˜ธ์ถœ ๊ตฌ์กฐ

A -> B -> C

  • C์˜ ์žฅ์• ๊ฐ€ A, B์—๊ฒŒ๋กœ ์ „ํŒŒ๋จ.
  • C์˜ ์žฅ์• ๊ฐ€ ์‹œ์Šคํ…œ ์ „์ฒด์˜ ์žฅ์• ๋กœ ์ด์–ด์ง.

์ปค๋„ฅ์…˜ ํ’€์˜ ๊ณ ๊ฐˆ

  • DB ์‘๋‹ต ์ง€์—ฐ.
  • ์™ธ๋ถ€ API ์ง€์—ฐ.
  • ์“ฐ๋ ˆ๋“œ ๋ธ”๋กœํ‚น ์ฆ๊ฐ€.
  • ์ปค๋„ฅ์…˜์ด ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์„ ๊ฒฝ์šฐ, ๋Œ€๊ธฐ ์š”์ฒญ์ด ์ฆ๊ฐ€ํ•ด ๊ฐ€์šฉ์„ฑ์ด ์ €ํ•˜๋จ.

์ž์› ๊ฒฝํ•ฉ

  • ๋‹จ์ผ DB
  • ๋‹จ์ผ ์บ์‹œ ์„œ๋ฒ„
  • ๊ณตํ†ต ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค
  • ํ•œ ์ง€์ ์˜ ์žฅ์• ๊ฐ€ ์ „์ฒด ๊ธฐ๋Šฅ์— ์˜ํ–ฅ์„ ์ฃผ๊ฒŒ ๋จ.

์ ์šฉ

์ธ๊ธฐ๊ธ€ ์ง‘๊ณ„์˜ ์ง€์—ฐ

  • ๋ฉ”์ธ ํŽ˜์ด์ง€์˜ ๋กœ๋”ฉ ์ง€์—ฐ.
  • DB ๋ถ€ํ•˜ ์ฆ๊ฐ€.
  • ์ „์ฒด ์กฐํšŒ API์— ์˜ํ–ฅ์„ ์คŒ.

์ธ๊ธฐ๊ธ€ ์ง‘๊ณ„๋ฅผ ๋น„๋™๊ธฐ๋กœ ๋ถ„๋ฆฌ.

์ข‹์•„์š” ์ฒ˜๋ฆฌ ์ง€์—ฐ

  • ํŠธ๋žœ์žญ์…˜ ๊ฐ„ ๋™์ผํ•œ ํ–‰์— ๋Œ€ํ•œ ๋ฝ ๊ฒฝํ•ฉ.
  • DB ์ปค๋„ฅ์…˜ ๋Œ€๊ธฐ ์ฆ๊ฐ€.
  • ์ „์ฒด API ์‘๋‹ต์†๋„ ์ €ํ•˜.

์žฅ์•  ์ „ํŒŒ ๋ฐฉ์ง€ ์ „๋žต

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ

  • ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜.
  • ๋ฉ”์‹œ์ง€ ํ ํ™œ์šฉ.

ํƒ€์ž„์•„์›ƒ ์„ค์ •

  • ์™ธ๋ถ€ ํ˜ธ์ถœ์— ๋Œ€ํ•œ ํƒ€์ž„์•„์›ƒ์„ ์„ค์ •.
  • ๋ฌดํ•œ ๋Œ€๊ธฐ ๋ฐฉ์ง€.

๊ฒฉ๋ฆฌ ์ „๋žต

  • ์ฝ๊ธฐ ยท ์“ฐ๊ธฐ ๋ถ„๋ฆฌ. -> CQRS
  • ๊ธฐ๋Šฅ ๋‹จ์œ„์˜ ๋ถ„๋ฆฌ.

์ •๋ฆฌ

์žฅ์• ๋ฅผ ๊ตญ์†Œํ™”ํ•˜์—ฌ, ์ „์ฒด์ ์ธ ๊ฐ€์šฉ์„ฑ์„ ํ™•๋ณด.

ํŠธ๋ž˜ํ”ฝ ํŠน์„ฑ์— ๋”ฐ๋ฅธ ์„ค๊ณ„ ์ „๋žต

์ฝ๊ธฐ ยท ์“ฐ๊ธฐ ํŠธ๋ž˜ํ”ฝ์ด ๋น„๋Œ€์นญ์ ์ธ ์ƒํ™ฉ์˜ ์„ค๊ณ„

์ฝ๊ธฐ ์ค‘์‹ฌ ์„œ๋น„์Šค์˜ ํŠน์„ฑ

  • ์กฐํšŒ ์š”์ฒญ > ์“ฐ๊ธฐ ์š”์ฒญ.
  • ๋™์ผ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ฐ˜๋ณต ์กฐํšŒ ๋นˆ๋„ ๋†’์Œ.
  • ์กฐํšŒ ์š”์ฒญ์ด ์ผ๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์ง‘์ค‘๋จ.

๋ฌธ์ œ์ 

  • ๋‹จ์ผ DB์— ๋Œ€ํ•œ ๋ถ€ํ•˜ ์ง‘์ค‘.
  • ์“ฐ๊ธฐ ๋ฝ์ด ์ฝ๊ธฐ ์ง€์—ฐ์œผ๋กœ ๋‚˜ํƒ€๋‚จ.
  • ํ™•์žฅ ๋ณต์žก๋„ ๋†’์Œ.

์„ค๊ณ„ ์ „๋žต

์บ์‹œ ๊ณ„์ธต ๋„์ž…

  • Redis ๊ธฐ๋ฐ˜ Cache-Aside ์ „๋žต ์ ์šฉ.
  • DB I/O ๊ฐ์†Œ.
  • ์‘๋‹ต ์†๋„ ๊ฐœ์„ .
  • ์บ์‹œ ๋ฌดํšจํ™” ์ „๋žต ํ•„์š”.
  • ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ๊ณ ๋ ค ํ•„์š”.

์ง‘๊ณ„ ๋ฐ์ดํ„ฐ ๋น„์ •๊ทœํ™”

  • ์กฐํšŒ์ˆ˜
  • ์ธ๊ธฐ๊ธ€
  • ํ†ต๊ณ„์„ฑ ๋ฐ์ดํ„ฐ -> ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„์ •๊ทœํ™”ํ•˜์—ฌ ์บ์‹ฑ.

์ •๋ฆฌ

ํŠธ๋ž˜ํ”ฝ์ด ์ง‘์ค‘๋˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ํ™•์žฅํ•œ๋‹ค.

CQRS

  • Command: ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” ์š”์ฒญ(์“ฐ๊ธฐ)
  • Query: ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ์š”์ฒญ(์ฝ๊ธฐ) -> ๋‘ ๋ชจ๋ธ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๋…๋ฆฝ์ ์œผ๋กœ ์„ค๊ณ„.

์ ์šฉ

Write Model

  • ์ •๊ทœํ™” ์œ ์ง€.
  • ํŠธ๋žœ์žญ์…˜ ์ค‘์‹ฌ ์„ค๊ณ„.
  • ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ์šฐ์„ .

Read Model

  • ์กฐํšŒ๊ฐ€ ์žฆ์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋น„์ •๊ทœํ™” ์ ์šฉ.
  • ์ง‘๊ณ„ ๋ฐ์ดํ„ฐ ํฌํ•จ.

์žฅ์ 

  • ์ฝ๊ธฐ ยท ์“ฐ๊ธฐ ๋…๋ฆฝ์ ์œผ๋กœ ํ™•์žฅ ๊ฐ€๋Šฅ.
  • ๋ณต์žก๋„๊ฐ€ ๊ฐ์†Œํ•จ.
  • ์žฅ์• ๊ฐ€ ์ „ํŒŒ๋˜๋Š” ๋ฒ”์œ„๊ฐ€ ์ถ•์†Œ๋จ.
  • ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ์Œ.

๋‹จ์ 

  • ๊ตฌํ˜„ ์ƒ์˜ ๋ณต์žก๋„ ์ฆ๊ฐ€.
  • ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ํ•„์š”ํ•จ.
  • ์ตœ์ข… ์ผ๊ด€์„ฑ ๊ณ ๋ ค ํ•„์š”.

์ ์šฉ ์ƒํ™ฉ

  • ์ฝ๊ธฐ ํŠธ๋ž˜ํ”ฝ์ด ์••๋„์ ์œผ๋กœ ๋†’์€ ๊ฒฝ์šฐ.
  • ์ง‘๊ณ„ ์กฐํšŒ๊ฐ€ ์žฆ์€ ๊ฒฝ์šฐ.

์ •๋ฆฌ

๋„๋ฉ”์ธ ํŠน์„ฑ์— ๋”ฐ๋ผ, ๋ชจ๋ธ์„ ๋ฐ”๊ฟ” ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Œ.

์บ์‹œ ์ „๋žต

๋ฐ์ดํ„ฐ์˜ ์‚ฌ๋ณธ์„ ๋ฉ”๋ชจ๋ฆฌ ๊ณ„์ธต์— ์ €์žฅํ•˜์—ฌ ๋””์Šคํฌ I/O๋ฅผ ์ค„์ด๊ณ , ์‘๋‹ต์†๋„๋ฅผ ๊ฐœ์„ ํ•˜์—ฌ ์ฝ๊ธฐ ํŠธ๋ž˜ํ”ฝ์œผ๋กœ ์ธํ•œ ๋ณ‘๋ชฉ์„ ์™„ํ™”ํ•˜๋Š” ์ „๋žต.

๋ชฉ์ 

  • DB ๋ถ€ํ•˜ ๊ฒฝ๊ฐ.
  • ์‘๋‹ต ์†๋„ ๊ฐœ์„ .
  • ๋ณ‘๋ชฉ ์™„ํ™”.
  • Hot-Data ๋ฐ˜๋ณต์กฐํšŒ ์ตœ์ ํ™”.

๋Œ€์ƒ

๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ ์กฐํšŒ

  • ๋™์ผํ•œ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ ๋ฐ˜๋ณต ์กฐํšŒ ๋นˆ๋„ ๋†’์Œ.
  • ๋ณ€๊ฒฝ ๋นˆ๋„ ๋‚ฎ์Œ.

๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก

  • ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ๋ฐœ์ƒ.
  • ์ธ๊ธฐ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ ์ง‘์ค‘ ํŠธ๋ž˜ํ”ฝ ๋ฐœ์ƒ.
  • ID ๋ชฉ๋ก๊ณผ, ๊ฐœ๋ณ„ ๊ฒŒ์‹œ๊ธ€์„ ์บ์‹ฑํ•˜์—ฌ ํŽ˜์ด์ง€ ์‚ฌ์ด์ฆˆ์˜ ๋ณ€๊ฒฝ, ๋ฌดํ•œ์Šคํฌ๋กค ๋ฐฉ์‹์—๋„ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.

์ธ๊ธฐ๊ธ€ ์ง‘๊ณ„

  • ์‹ค์‹œ๊ฐ„์„ฑ ๋‚ฎ์Œ.
  • ๋ฐ˜๋ณต ์กฐํšŒ ๋นˆ๋„ ๋†’์Œ.
  • ์ง‘๊ณ„ ์ฟผ๋ฆฌ(GROUP BY, ORDER BY)๋Š” ๊ธฐํƒ€ ์„œ๋น„์Šค์— ์ง€์†์ ์ธ I/O ์œ ๋ฐœํ•˜์—ฌ DB ๋ถ€ํ•˜๋ฅผ ๋ˆ„์ ์‹œํ‚ด.

์ข…๋ฅ˜

Cache-Aside

  1. ์บ์‹œ ์กฐํšŒ.
  2. ์—†์„ ๊ฒฝ์šฐ, DB ์กฐํšŒ.
  3. ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅ.
  4. ์‘๋‹ต ๋ฐ˜ํ™˜.
  • ๊ฒŒ์‹œํŒ ์กฐํšŒ์— ํ™œ์šฉ.
์žฅ์ 
  • ๊ตฌํ˜„์ด ๋‹จ์ˆœํ•จ.
  • ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์บ์‹œ๋จ.
๋‹จ์ 
  • ์บ์‹œ ๋ฏธ์Šค ์‹œ, DB ๋ถ€ํ•˜ ๋ฐœ์ƒ.
  • ๋ฌดํšจํ™” ์ „๋žต ์ถ”๊ฐ€ ํ•„์š”.

Write-Back

๋ฐ˜๋ณต์ ์ธ ์“ฐ๊ธฐ๋ฅผ ์บ์‹œํ•˜๊ณ , ๋ฐฐ์น˜ ๋‹จ์œ„๋กœ DB์— ์ €์žฅ. ์กฐํšŒ์ˆ˜ ์ง‘๊ณ„์— ํ™œ์šฉ.

์žฅ์ 
  • ์“ฐ๊ธฐ ์„ฑ๋Šฅ ํ–ฅ์ƒ.
  • DB ๋ถ€ํ•˜ ๊ฐ์†Œ.
๋‹จ์ 
  • ๋ฐ์ดํ„ฐ ์œ ์‹ค ๊ฐ€๋Šฅ.
  • ์ผ์‹œ์ ์ธ ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜ ๋ฐœ์ƒ.

๋ฌดํšจํ™” ์ „๋žต

TTL

์ผ์ • ์‹œ๊ฐ„ ํ›„, ์ž๋™์œผ๋กœ ์บ์‹œ๋ฅผ ์‚ญ์ œํ•จ.

์žฅ์ 
  • ๋‹จ์ˆœํ•˜๊ณ , ์•ˆ์ „ํ•จ.
๋‹จ์ 
  • ๋งŒ๋ฃŒ ์งํ›„์— ํŠธ๋ž˜ํ”ฝ์ด ์ง‘์ค‘๋  ๊ฒฝ์šฐ, ๋™์‹œ๋‹ค๋ฐœ์ ์ธ DB ์ ‘๊ทผ ๋ฐœ์ƒํ•จ.

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ฌดํšจํ™”

์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, ๊ด€๋ จ๋œ ์บ์‹œ๋ฅผ ๊ฐฑ์‹ ํ•จ.

์žฅ์ 
  • ์ผ๊ด€์„ฑ ์ œ์–ด ๊ฐ€๋Šฅ.
  • ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‹œ์ ๊ณผ ์บ์‹œ ๋ณ€๊ฒฝ ์‹œ์ ์„ ๋™๊ธฐํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ.
  • TTL ์˜์กด๋„ ์ €ํ•˜ ๊ฐ€๋Šฅ.
๋‹จ์ 
  • ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ณต์žก๋„.

์ •๋ฆฌ

์ฝ๊ธฐ ์ง‘์•ฝ์  ์„œ๋น„์Šค์—์„œ๋Š” ์บ์‹œ๊ฐ€ ์‹ค์งˆ์ ์œผ๋กœ 1์ฐจ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋กœ์„œ ๊ธฐ๋Šฅํ•จ. ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„ ๋‹จ๋ถ€ํ„ฐ์˜ ์œตํ™”๊ฐ€ ํ•„์š”ํ•จ.

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ

๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค๋ฅผ ๋งค๊ฐœ๋กœ, ์„œ๋น„์Šค ๊ฐ„์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๋ฐœํ–‰(Publish), ๊ตฌ๋…(Subscribe)ํ•˜์—ฌ ์ „ํŒŒํ•˜๊ณ , ์ด๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ์‹œ์Šคํ…œ ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋Š” ์„ค๊ณ„ ์ „๋žต.

๋ชฉ์ 

  • ์„œ๋น„์Šค ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(์˜ˆ: ๊ฒŒ์‹œ๊ธ€์˜ ์ €์žฅ)๊ณผ ์„œ๋น„์Šค๊ฐ€ ํ†ต์‹ ํ•˜๋ฉฐ ๋ฐœ์ƒํ•˜๋Š” ๋ถ€๊ฐ€์ ์ธ ์ž‘์—…(์˜ˆ: ์กฐํšŒ ๋ชจ๋ธ ๊ฐฑ์‹ , ์ง‘๊ณ„)์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์‘๋‹ต์†๋„๋ฅผ ๊ฐœ์„ ํ•จ.
  • ์ง์ ‘์ ์ธ API ํ˜ธ์ถœ์„ ์ œ๊ฑฐํ•˜๊ณ , ์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด ๋А์Šจํ•˜๊ฒŒ ๊ฒฐํ•ฉํ•˜์—ฌ ๊ฐ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค์˜ ๋…๋ฆฝ์ ์ธ ํ™•์žฅ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ.
  • Consumer ์„œ๋น„์Šค์˜ ์žฅ์• ๊ฐ€ Producer ์„œ๋น„์Šค์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ๋ณดํ˜ธํ•จ.

๊ตฌํ˜„

Transactional Outbox ํŒจํ„ด

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ DB ๋ณ€๊ฒฝ๊ณผ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์–ด ๋ฐ์ดํ„ฐ ์œ ์‹ค์„ ์ฐจ๋‹จ.

Kafka ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ๋ฉ”์‹œ์ง•

  • ํŠธ๋ž˜ํ”ฝ ํญ์ฆ ์‹œ ์ด๋ฒคํŠธ๋ฅผ Kafka์— ์ ์žฌํ•˜์—ฌ Consumer๊ฐ€ ์ž์‹ ์˜ ์ฒ˜๋ฆฌ ์†๋„์— ๋งž์ถฐ ์†Œ๋น„ํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ์‹œ์Šคํ…œ ์•ˆ์ •์„ฑ ์œ ์ง€.

๊ณ ๋ ค์‚ฌํ•ญ

  • ๋ฐœํ–‰๊ณผ ์†Œ๋น„ ์‚ฌ์ด ์‹œ๊ฐ„ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ์„ ์ธ์ง€ํ•˜๊ณ , ๋„๋ฉ”์ธ ํŠน์„ฑ์— ๋”ฐ๋ผ ๋ฐ˜์˜ํ•  ๊ฒƒ.
  • MessageRelay์˜ ์žฌ์‹œ๋„๋กœ ์ธํ•ด ๋™์ผํ•œ ์ด๋ฒคํŠธ๊ฐ€ ์ค‘๋ณต ์ˆ˜์‹ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, Consumer ์ธก์—์„œ ๋ฉฑ๋“ฑ์„ฑ ์„ค๊ณ„ํ•  ๊ฒƒ.

Projection ์„ค๊ณ„ ์ „๋žต

๊ฐœ๋…

์ปค๋งจ๋“œ ๋ชจ๋ธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ธฐ์— ์ตœ์ ํ™”๋œ ๊ตฌ์กฐ๋กœ ๋ณ€ํ™˜ํ•œ ๊ฒƒ. ์‘๋‹ต ์‹œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„์ •๊ทœํ™”ํ•˜์—ฌ ์ €์žฅํ•ด ๋‹ค๋ฅธ ์„œ๋น„์Šค๋กœ์˜ JOIN์„ ์ตœ์†Œํ™”ํ•˜๊ณ , ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ํŽธ์˜์„ฑ์„ ์ฆ๋Œ€ํ•จ.

์˜ˆ์‹œ | ArticleQueryModel

์ข…๋ฅ˜ ํ•„๋“œ/ ๋ฉ”์„œ๋“œ๋ช… ์ƒ์„ธ
Long articleId * ์ดํ•˜ Article ํด๋ž˜์Šค ํ•„๋“œ
String title ``
String content ``
Long boardId ``
Long writerId ``
LocalDateTime createdAt ``
LocalDateTime modifiedAt ``
Long articleCommentCount ArticleCommentCountRepository๋กœ๋ถ€ํ„ฐ fetchํ•œ ์ข‹์•„์š” ์ˆ˜.
Long articleLikeCount ArticleLikeCountRepository๋กœ๋ถ€ํ„ฐ fetchํ•œ ๋Œ“๊ธ€ ์ˆ˜.
ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ create Kafka๊ฐ€ ์ƒ์„ฑํ•œ ์ด๋ฒคํŠธ, ๋˜๋Š” DB์—์„œ fetchํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ArticleQueryModel์„ ์ƒ์„ฑํ•˜๋Š” ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ.
Setter updateBy Kafka๊ฐ€ ์ƒ์„ฑํ•œ ์ด๋ฒคํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ArticleQueryModel์„ ๊ฐฑ์‹ ํ•˜๋Š” ๋ฉ”์„œ๋“œ.
  • ์กฐํšŒ์ˆ˜ ์—ญ์‹œ ์กฐํšŒ ๋ชจ๋ธ ์ƒ์„ฑ์— ํ•„์š”ํ•˜์ง€๋งŒ,
    • ์‹ค์‹œ๊ฐ„์„ฑ์ด ๋†’์œผ๋ฉฐ,
    • Redis๋ฅผ ์ฃผ ์ €์žฅ์†Œ๋กœ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋น„์Šค ๋‹จ์—์„œ ์ง์ ‘ ๊ฒฐํ•ฉํ•˜๋Š” ํ˜•ํƒœ๋กœ ์„ค๊ณ„ํ•จ.

์„ค๊ณ„ ์›์น™

๋ถˆ๋ณ€์„ฑ

๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•œ ๋ชจ๋ธ์ด ์•„๋‹˜. ์™ธ๋ถ€์—์„œ ๊ฐ’์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์—†๊ฒŒํ•  ๊ฒƒ.

๊ฒฐํ•ฉ๋„ ๋ถ„๋ฆฌ

DB์˜ ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ๊ณผ ๋ชจ๋ธ์˜ ๋ณ€๊ฒฝ์„ ๋ถ„๋ฆฌํ•  ๊ฒƒ.

API ๋‹จ์œ„ ์„ค๊ณ„

์กฐํšŒ API์— ๋งž์ถฐ ์„ค๊ณ„ํ•  ๊ฒƒ.

JOIN ์ œ๊ฑฐ

ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋ฏธ๋ฆฌ ํฌํ•จํ•  ๊ฒƒ.

์ง‘๊ณ„ ๋น„์ •๊ทœํ™”

๋Œ“๊ธ€์ˆ˜, ์ข‹์•„์š”์ˆ˜, ์กฐํšŒ์ˆ˜ ๋“ฑ์˜ ์ง‘๊ณ„๊ฐ’์€ ๋ฏธ๋ฆฌ ํฌํ•จํ•  ๊ฒƒ.(* ๋ณ€๋™์„ฑ์ด ํฐ ๋ฐ์ดํ„ฐ๋Š” ๋ชจ๋ธ์—์„œ ์ œ์™ธํ•˜๊ณ , ์‹ค์‹œ๊ฐ„ ๋ณ‘ํ•ฉ ๋“ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.)

๋™๊ธฐํ™” ๋ฐฉ์‹

๋™๊ธฐ ์—…๋ฐ์ดํŠธ

  • ์“ฐ๊ธฐ ์‹œ, ์กฐํšŒ ๋ชจ๋ธ์„ ์ฆ‰์‹œ ์—…๋ฐ์ดํŠธํ•จ.
  • ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ.
  • ์“ฐ๊ธฐ ์„ฑ๋Šฅ ์ €ํ•˜๋  ์ˆ˜ ์žˆ์Œ.

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์—…๋ฐ์ดํŠธ

  • ์ด๋ฒคํŠธ๋ฅผ ์†Œ๋น„ํ•œ ๋’ค, ์กฐํšŒ ๋ชจ๋ธ์„ ์—…๋ฐ์ดํŠธํ•จ.
  • ์ตœ์ข… ์ผ๊ด€์„ฑ.

์žฅ์ 

  • ์ฝ๊ธฐ ์„ฑ๋Šฅ ์ตœ์ ํ™”.
  • DB ๋ถ€ํ•˜ ๊ฐ์†Œ.
  • API ๊ตฌ์กฐ ๋‹จ์ˆœํ™”.

๋‹จ์ 

  • ๋ฐ์ดํ„ฐ ์ค‘๋ณต ์ฆ๊ฐ€.
  • ๋™๊ธฐํ™” ๋ณต์žก๋„ ์ฆ๊ฐ€.
  • ์ผ์‹œ์ ์ธ ๋ถˆ์ผ์น˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ.

์ •๋ฆฌ

ํŠธ๋ž˜ํ”ฝ ํŠน์„ฑ์— ๋”ฐ๋ผ ์ •๊ทœํ™”์˜ ๊ฐ•๋„๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ์Œ.

์•„ํ‚คํ…์ฒ˜์˜ ์„ ํƒ

์‹œ์Šคํ…œ์˜ ๊ทœ๋ชจ, ํŒ€์˜ ๊ตฌ์กฐ, ๋„๋ฉ”์ธ ๋ณต์žก๋„์— ๋”ฐ๋ผ ๋น„์šฉ ๋Œ€๋น„ ์ตœ์ ์˜ ํšจ์œจ์„ ๋‚ผ ์ˆ˜ ์žˆ๋Š” ์•„ํ‚คํ…์ฒ˜๋ฅผ ์„ ํƒํ•ด์•ผ ํ•จ. ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ํ™•์žฅ์„ฑ, ๋„๋ฉ”์ธ ๊ฐ„ ๊ฒฉ๋ฆฌ๋ฅผ ์œ„ํ•ด MSA๋ฅผ ์ฑ„ํƒํ•จ.

๋ชจ๋†€๋ฆฌ์‹ vs. MSA

Scale-Up & Scale-Out

Scale-Up

  • ๊ฐœ๋ณ„ ์„œ๋ฒ„์˜ CPU, Memory, Disk ์„ฑ๋Šฅ ์ฆ๊ฐ€.
  • ๋ณ„๋„์˜ ๊ตฌ์กฐ ๋ณ€๊ฒฝ ์—†์Œ.
  • ๋ฌผ๋ฆฌ์ ์ธ ํ•œ๊ณ„ ์กด์žฌํ•จ.
  • ์ž„๊ณ„์  ์ดํ›„๋ถ€ํ„ฐ๋Š” ๋น„์šฉ ๋Œ€๋น„ ํšจ์œจ์ด ๊ธ‰๊ฒฉํžˆ ๊ฐ์†Œํ•จ.

Scale-Out

  • ์„œ๋ฒ„ ์ˆ˜์˜ ํšก์ ์ธ ์ฆ๊ฐ€๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋Ÿ‰์„ ํ™•์žฅํ•จ.
  • Load Balancer์™€ ๊ฐ™์€ ๋ณ„๊ฐœ์˜ ๋””๋ฐ”์ด์Šค๋ฅผ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์‚ฐํ•จ.
  • ์ถ”๊ฐ€์ ์ธ ๊ตฌ์กฐ ๋ณ€๊ฒฝ์ด ํ•„์ˆ˜์ ์œผ๋กœ ์ˆ˜๋ฐ˜๋จ.
  • ๋น„์šฉ ๋Œ€๋น„ ํšจ์œจ์ด Scale-Up ์ „๋žต๋ณด๋‹ค ์šฐ์ˆ˜ํ•จ.

๋ชจ๋†€๋ฆฌ์‹

  • ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ๋‹จ์ผ ์ฝ”๋“œ ๋ฒ ์ด์Šค์— ์žˆ์Œ.
  • ๊ฐœ๋ฐœ ยท ๋ฐฐํฌ๊ฐ€ ๊ฐ„๋‹จํ•จ.
  • ํŠน์ • ์ปดํฌ๋„ŒํŠธ์˜ ๋ถ€๋ถ„์ ์ธ ํ™•์žฅ์ด ๋ถˆ๊ฐ€๋Šฅํ•จ.
  • ๊ฐ๊ฐ์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋จ.
  • ํŠน์ • ์ปดํฌ๋„ŒํŠธ์˜ ์žฅ์• ๊ฐ€ ์‹œ์Šคํ…œ ์ „์ฒด๋กœ ์ „ํŒŒ๋จ.

MSA

  • ๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ์„œ๋น„์Šค๋ฅผ ๋ถ„๋ฆฌํ•จ.
  • ์„œ๋น„์Šค ๋ณ„๋กœ ๋…๋ฆฝ์ ์ธ ๋ฐฐํฌ๊ฐ€ ๊ฐ€๋Šฅํ•จ.
  • ํŠน์ • ์„œ๋น„์Šค๋งŒ ๊ฐœ๋ณ„์ ์œผ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Œ.
  • ๋„คํŠธ์›Œํฌ ๋น„์šฉ์ด ์ฆ๊ฐ€ํ•จ.
  • ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•จ.
  • ํ…Œ์ŠคํŠธ ยท ์šด์˜ ๋ณต์žก์„ฑ์ด ํฌ๊ฒŒ ์ฆ๊ฐ€ํ•จ.

MSA๋Š” ๋„๋ฉ”์ธ ๋ณต์žก๋„ ยท ํŠธ๋ž˜ํ”ฝ ยท ์กฐ์ง ๊ทœ๋ชจ๊ฐ€ ์ถฉ๋ถ„ํžˆ ํด ๋•Œ๋งŒ ์œ ์˜๋ฏธํ•œ ์•„ํ‚คํ…์ฒ˜์ž„. ๋ณต์žก์„ฑ๊ณผ ํ™•์žฅ์„ฑ์˜ Trade-Off.

์–ด๋–ค ์ƒํ™ฉ์— MSA๋ฅผ ์ ์šฉํ•˜๋Š”๊ฐ€?

  • ํŠน์ • ๊ธฐ๋Šฅ์— ํŠธ๋ž˜ํ”ฝ์ด ์ง‘์ค‘๋ผ, ํ•ด๋‹น ๋ชจ๋“ˆ๋งŒ ์ถ”๊ฐ€ ์ž์›์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ.
  • ๋‹จ์ผ ์ฝ”๋“œ ๋ฒ ์ด์Šค ๋‚ด์—์„œ, ๋ชจ๋“ˆ ๊ฐ„ ์ฐธ์กฐ๊ฐ€ ์–ฝํ˜€ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง€๊ณ , ์ž‘์€ ์ˆ˜์ •์ด ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๋ถ€์ž‘์šฉ์„ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ.
  • ๋‹ค์ˆ˜์˜ ๊ฐœ๋ฐœ ํŒ€์ด ์„œ๋กœ์˜ ๋ฐฐํฌ์ฃผ๊ธฐ์— ๊ฐ„์„ญ๋ฐ›์ง€ ์•Š๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ.

์–ด๋–ค ์ƒํ™ฉ์— MSA๋ฅผ ์ ์šฉํ•˜๋ฉด ์•ˆ๋˜๋Š”๊ฐ€?

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋ชจ๋ธ์ด ๊ณ ์ฐฉํ™”๋˜์ง€ ์•Š์•„ ์„œ๋น„์Šค ๊ฐ„์˜ ๊ฒฝ๊ณ„๊ฐ€ ๋ถˆ๋ถ„๋ช…ํ•œ ์ƒํ™ฉ์—์„œ๋Š”, ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์˜ ๋ณต์žก์„ฑ์ด ์ƒ์‚ฐ์„ฑ์„ ์ €ํ•ดํ•จ.
  • ๋ถ„์‚ฐ ํ™˜๊ฒฝ์˜ ๋ชจ๋‹ˆํ„ฐ๋ง, ๋กœ๊ทธ ์ถ”์ , CI/CD ์ธํ”„๋ผ๊ฐ€ ๋ฏธ๋น„ํ•œ ๊ฒฝ์šฐ ์šด์˜ ๋น„์šฉ์ด ํฌ๊ฒŒ ์ƒ์Šนํ•จ.
  • ๋‹จ์ผ ์„œ๋ฒ„์˜ Scale-Up๋งŒ์œผ๋กœ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ทœ๋ชจ์—์„œ๋Š” MSA ๋„์ž…์˜ ์ด๋“๋ณด๋‹ค ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋” ํผ.

์„œ๋น„์Šค ๊ฒฝ๊ณ„์˜ ํ™•์ •

  • ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์„ ๊ธฐ์ค€์œผ๋กœ ์‘์ง‘๋„๊ฐ€ ๋†’์€ ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์˜ ์„œ๋น„์Šค๋กœ ๋ฌถ์Œ.
    • ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€, ์ข‹์•„์š”, ์กฐํšŒ์ˆ˜๋ฅผ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์ธ ์„œ๋น„์Šค๋กœ ํš์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ์™€ ๋กœ์ง์„ ๊ฒฉ๋ฆฌํ•จ.
  • ๋ฐ์ดํ„ฐ ์‚ฐ์žฌ๋กœ ์ธํ•œ ์กฐํšŒ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด article-read์™€ ๊ฐ™์€ ์ฝ๊ธฐ ์ „์šฉ ์„œ๋น„์Šค๋ฅผ ๋ณ„๋„๋กœ ๋‘์–ด ๊ฒฝ๊ณ„๋ฅผ ์ตœ์ ํ™”ํ•จ.
์„œ๋น„์Šค ์—ญํ• 
service:article ๊ฒŒ์‹œ๊ธ€ ์ƒ๋ช…์ฃผ๊ธฐ ์ œ์–ด
service:comment ๋Œ“๊ธ€ ๊ณ„์ธต๊ตฌ์กฐ ์ •์˜ ยท ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
service:like ์ข‹์•„์š” ์ค‘๋ณต๋ฐฉ์ง€ ์ œ์–ด ยท ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
service:view Redis ์ค‘์‹ฌ ์กฐํšŒ์ˆ˜ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ
service:hot-article ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐ HotArticleScoreUpdater ์Šค์ฝ”์–ด๋ง
service:article-read CQRS Read ์ „์šฉ ์„œ๋น„์Šค

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ถ„๋ฆฌ ์ „๋žต

  • ๊ฐ ์„œ๋น„์Šค๋Š” ์ž์‹ ๋งŒ์ด ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ์ „์šฉ ์ €์žฅ์†Œ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•จ. ํƒ€ ์„œ๋น„์Šค์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ ๊ฒฐํ•ฉ๋„๋ฅผ ๋†’์ด๋ฏ€๋กœ ์ง€์–‘ํ•จ.
  • ๋„๋ฉ”์ธ ํŠน์„ฑ์— ๋”ฐ๋ผ view ์„œ๋น„์Šค๋Š” ๊ณ ์„ฑ๋Šฅ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด Redis์™€ RDB๋ฅผ ๋ณ‘ํ–‰ํ•˜๊ณ , article-read๋Š” ํ”„๋กœ์ ์…˜ ๋ชจ๋ธ์„ ์œ„ํ•ด Redis๋ฅผ ์ฃผ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋“ฑ ์„œ๋น„์Šค๋ณ„ ์ตœ์ ์˜ ์Šคํƒ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Œ.
  • ๋ถ„๋ฆฌ๋œ DB ๊ฐ„์˜ ์ผ๊ด€์„ฑ์€ MessageRelay์™€ Kafka๋ฅผ ํ™œ์šฉํ•œ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์ตœ์ข… ์ผ๊ด€์„ฑ์œผ๋กœ ํ•ด๊ฒฐํ•จ.

๋ฐ์ดํ„ฐ ๊ณ„์ธต ์„ค๏ฟฝ๊ณ„

RDB | MySQL

์Šคํ‚ค๋งˆ ์„ค๊ณ„

  • ์„œ๋น„์Šค ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€, ์ข‹์•„์š” ๋“ฑ ๊ฐ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋ณ„๋กœ ๋…๋ฆฝ์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ๋ฅผ ํ• ๋‹นํ•จ.
  • ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ์˜ ์œ ์ผ์„ฑ ๋ณด์žฅ ๋ฐ ์‹œ๊ฐ„ ์ˆœ ์ •๋ ฌ์„ ์œ„ํ•ด ๋ชจ๋“  ์ฃผ์š” ์—”ํ‹ฐํ‹ฐ์˜ ๊ธฐ๋ณธํ‚ค(PK)๋กœ Snowflake๋ฅผ ์ฑ„ํƒํ•จ. ์ด๋Š” Auto-increment์˜ ๋ณด์•ˆ ์ทจ์•ฝ์„ฑ๊ณผ UUID์˜ ์„ฑ๋Šฅ ์ €ํ•˜ ๋ฌธ์ œ๋ฅผ ๋™์‹œ์— ํ•ด๊ฒฐํ•จ.
  • ๊ณ ๋นˆ๋„ ์กฐํšŒ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒŒ์‹œ๊ธ€ ๋‹น ๋Œ“๊ธ€ ์ˆ˜, ์ข‹์•„์š” ์ˆ˜ ๋“ฑ์„ ์—”ํ‹ฐํ‹ฐ ๋‚ด์— ํ•„๋“œ๋กœ ๋‘์ง€ ์•Š๊ณ  BoardArticleCount, ArticleLikeCount ๋“ฑ ๋ณ„๋„ ํ†ต๊ณ„ ํ…Œ์ด๋ธ”๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•จ. ์ด๋Š” ๋ฉ”์ธ ํ…Œ์ด๋ธ”์˜ ์“ฐ๊ธฐ ์ž ๊ธˆ(Write Lock) ๊ฒฝํ•ฉ์„ ์ค„์ด๊ธฐ ์œ„ํ•จ์ž„.

๋Œ“๊ธ€ ๊ณ„์ธต ๊ตฌ์กฐ ๋ชจ๋ธ๋ง

  • V1: ๋ถ€๋ชจ ๋Œ“๊ธ€ ID๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ „ํ˜•์ ์ธ ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ๊ตฌํ˜„.
  • V2: CommentPath ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๋Œ“๊ธ€์˜ ๊ณ„์ธต ๊ฒฝ๋กœ๋ฅผ ๋ฌธ์ž์—ด ๋“ฑ์œผ๋กœ ๊ด€๋ฆฌ, ๋ณต์žกํ•œ ํŠธ๋ฆฌ ๊ตฌ์กฐ ์กฐํšŒ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”.

์ธ๋ฑ์‹ฑ ์ „๋žต

  • PK๋กœ Snowflake๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ๋ฐ์ดํ„ฐ ์‚ฝ์ž… ์‹œ ์‹œ๊ฐ„ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•จ. ์ด๋Š” ์‚ฝ์ž… ์‹œ ์ธ๋ฑ์Šค ํŽ˜์ด์ง€ ๋ถ„ํ• ์„ ์–ต์ œํ•˜๊ณ  ์“ฐ๊ธฐ ์„ฑ๋Šฅ์„ ๋ณด์กดํ•จ.
  • ์ง‘๊ณ„ ์ฟผ๋ฆฌ ๋ฐœ์ƒ ์‹œ, ์‹ค์ œ ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€์— ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ  ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ธ๋ฑ์Šค ๊ตฌ์„ฑ.

ํŽ˜์ด์ง• ์ตœ์ ํ™”

  • ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ๊ฐ€ ๋’ค๋กœ ๊ฐˆ์ˆ˜๋ก ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด PageLimitCalculator๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์Šค์บ” ๋ฒ”์œ„๋ฅผ ์ƒ์ˆ˜๋กœ ์ œํ•œํ•จ.
  • ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„, lastArticleId๋ฅผ ์กฐ๊ฑด์ ˆ์— ์‚ฌ์šฉํ•˜์—ฌ ์ธ๋ฑ์Šค ์ƒ์˜ ํ˜„์žฌ ์œ„์น˜๋ถ€ํ„ฐ ์ฆ‰์‹œ ์Šค์บ”์„ ์‹œ์ž‘ํ•˜๋„๋ก ์„ค๊ณ„ํ•˜์—ฌ ์ผ์ •ํ•œ ์กฐํšŒ ์„ฑ๋Šฅ์„ ํ™•๋ณดํ•จ.

๋ณตํ•ฉ ์ธ๋ฑ์Šค ๊ตฌ์„ฑ

  • ์ข‹์•„์š” ์ค‘๋ณต ์—ฌ๋ถ€ ํ™•์ธ(findByArticleIdAndUserId)์„ ์œ„ํ•ด articleId์™€ userId๋ฅผ ๋ฌถ๋Š” ์œ ๋‹ˆํฌ ๋ณตํ•ฉ ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•˜์—ฌ ๊ฒ€์ƒ‰ ๋ฐ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ ์†๋„๋ฅผ ๋†’์ž„.
  • ๊ฒŒ์‹œํŒ๋ณ„ ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ ์„ฑ๋Šฅ์„ ์œ„ํ•ด boardId์™€ articleId ์กฐํ•ฉ์— ๋Œ€ํ•œ ์ธ๋ฑ์Šค ๊ณ ๋ ค.

์ƒค๋”ฉ ์ „๋žต

๋ฐ์ดํ„ฐ ๊ทœ๋ชจ๊ฐ€ ๋‹จ์ผ ์žฅ๋น„์˜ ์ €์žฅ ์šฉ๋Ÿ‰, ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ(IOPS)๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ๋ถ„์‚ฐ ์ „๋žต.

์ข…๋ฅ˜

Horizontal Sharding (์ฑ„ํƒ)
  • ํ–‰ ๋‹จ์œ„ ๋ถ„๋ฆฌ.
  • ๋†’์€ ํ™•์žฅ์„ฑ.
  • JOIN, ํŠธ๋žœ์žญ์…˜ ๋ณต์žก๋„ ๋†’์Œ.
Vertical Sharding
  • ์—ด ๋‹จ์œ„ ๋ถ„๋ฆฌ.
  • ํ™•์žฅ์„ฑ์ด ์—ด์˜ ์ˆ˜์— ์˜ํ•ด ์ œํ•œ๋จ.
Shard Key
  • Range ๊ธฐ๋ฐ˜ -> ๋ฒ”์œ„ ์กฐํšŒ ์œ ๋ฆฌํ•จ. ๋ฐ์ดํ„ฐ๊ฐ€ ์ ๋ฆด ์ˆ˜ ์žˆ์Œ.
  • Hash ๊ธฐ๋ฐ˜ -> ๊ท ๋“ฑ ๋ถ„์‚ฐ. ๋ฒ”์œ„ ์กฐํšŒ์— ๋ถˆ๋ฆฌํ•จ.

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹จ์œ„ ์ƒค๋”ฉ | AssignShard

๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ DB์— ์ •์ƒ ๋ฐœํ–‰์— ์‹คํŒจํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚จ์•„ ์žˆ์œผ๋ฉฐ, ๋ณต์ˆ˜์˜ MessageRelay ์ธ์Šคํ„ด์Šค๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ, ๋ฐœํ–‰ ์ž‘์—…์˜ ์ค‘๋ณต์„ ๋ฐฉ์ง€ํ•˜๊ณ  ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•จ. | Load Balancer

  • ์ƒค๋“œ ์ฝ”๋””๋„ค์ดํ„ฐ | MessageRelayCoordinator
    • ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ MessageRelay๊ฐ€ ๋™์ผํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ค‘๋ณต ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋„๋ก ์ธ์Šคํ„ด์Šค๋ณ„ ์ฒ˜๋ฆฌ ๋ฒ”์œ„๋ฅผ ํ• ๋‹นํ•จ.
    • assignShards() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ”„๋กœ์„ธ์Šค ๋ณ„๋กœ ์ƒค๋“œ๋ฅผ ์ง€์ •ํ•˜์—ฌ ์‹œ์Šคํ…œ์˜ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์„ ํ˜•์ ์œผ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Œ.
    • 3์ดˆ๋งˆ๋‹ค ping() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ ์ธ์Šคํ„ด์Šค์˜ APP_ID, ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ๊ฐฑ์‹ ํ•จ.
    • 9์ดˆ๊ฐ„ ์‘๋‹ต์ด ์—†๋Š” ์ธ์Šคํ„ด์Šค๋Š” ์ž๋™์œผ๋กœ ๋ชฉ๋ก์—์„œ ์ œ๊ฑฐ๋จ.
  • ์ƒค๋“œ ๊ธฐ๋ฐ˜ ํด๋ง ๋ฐ ์ฒ˜๋ฆฌ | MessageRelay
    • @TransactionalEventListener(phase=TransactionPhase.BEFORE_COMMIT) ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด, ๊ฐ๊ฐ์˜ ์„œ๋น„์Šค๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰ํ•  ๊ฒฝ์šฐ, ๊ฐ ์„œ๋น„์Šค์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ์ด๋ฒคํŠธ์˜ ์ €์žฅ์„ ์›์žํ™”ํ•จ.
    • @Async("messageRelayPublishEventExecutor") @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) ์–ด๋…ธํ…Œ์ด์…˜์„ ํ™œ์šฉํ•ด, ํด๋ง์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰ํ•œ ๋’ค, ๏ฟฝKafka๋กœ ์ „์†กํ•˜๊ณ  ์‚ญ์ œํ•จ.
      • ์œ„ ๊ฒฝ๋กœ๋กœ ๋ฐœํ–‰๋œ ๊ฒฝ์šฐ, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ž์‹ ์ด ์ƒ์‚ฐํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— AssignShard๋ฅผ ํ• ๋‹น๋ฐ›์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ์ฒ˜๋ฆฌํ•จ.
      • ์œ„ ๊ฒฝ๋กœ๋กœ ๋ฐœํ–‰๋˜์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ,publishPendingEvent() ์“ฐ๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ At-least-once delivery๋ฅผ ๋ณด์žฅํ•จ. ์ด ๊ฒฝ์šฐ, ์—ฌ๋Ÿฌ MessageRelay๊ฐ€ ๊ณต๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— AssignShard๋ฅผ ํ• ๋‹น๋ฐ›์•„ ์ฒ˜๋ฆฌํ•จ.

๋ฌผ๋ฆฌ์  ์ƒค๋”ฉ | Shard Key

์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ์ฒ˜๋ฆฌ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•จ.

  • MessageRelay๋Š” Kafka๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ๋•Œ, shardKey๋ฅผ ๋ฉ”์‹œ์ง€ ํ‚ค๋กœ ์‚ฌ์šฉํ•จ.
  • ๋™์ผํ•œ shardKey๋ฅผ ๊ฐ€์ง„ ๋ฉ”์‹œ์ง€๋Š” ๋™์ผํ•œ Kafka ํŒŒํ‹ฐ์…˜์— ์ ์žฌ๋˜๋ฏ€๋กœ, Consumer๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์—ฌ ์ตœ์ข… ์ผ๊ด€์„ฑ์˜ ์ •ํ•ฉ์„ฑ์„ ๋†’์ž„.
    • ๋‹จ, publishPendingEvent() ์Šค์ผ€์ค„๋Ÿฌ๋กœ ๋ฐœํ–‰๋œ ๋ฉ”์‹œ์ง€์˜ ๊ฒฝ์šฐ, ์ˆœ์„œ๊ฐ€ ์–ด๊ธ‹๋‚  ์ˆ˜ ์žˆ์Œ.
์—”ํ‹ฐํ‹ฐ ์ƒค๋“œ ํ‚ค ์‚ฌ์œ 
service:article:Article,
BoardArticleCount
boardId ๊ฐœ๋ณ„ Article์€ Board ๋‹จ์œ„๋กœ ์กฐํšŒ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ฒŒ์‹œํŒ ๋‹จ์œ„๋กœ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•จ.
service:comment:CommentV2,
ArticleCommentCount
articleId ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ฐœ๋ณ„ Article์— ์ข…์†๋˜๊ธฐ ๋•Œ๋ฌธ์—, ํ†ต๊ณ„ ๊ฐฑ์‹  ๋ฐ ์กฐํšŒ ๋ชจ๋ธ๊ณผ์˜ ์ผ๊ด€์„ฑ์„ ๊ฒŒ์‹œ๊ธ€ ๋‹จ์œ„๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•จ.
service:like:ArticleLike,
ArticleLikeCount
articleId ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ฐœ๋ณ„ Article์— ์ข…์†๋˜๊ธฐ ๋•Œ๋ฌธ์—, ํ†ต๊ณ„ ๊ฐฑ์‹  ๋ฐ ์กฐํšŒ ๋ชจ๋ธ๊ณผ์˜ ์ผ๊ด€์„ฑ์„ ๊ฒŒ์‹œ๊ธ€ ๋‹จ์œ„๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•จ.
service:ArticleViewCount articleId ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ฐœ๋ณ„ Article์— ์ข…์†๋˜๊ธฐ ๋•Œ๋ฌธ์—, ํ†ต๊ณ„ ๊ฐฑ์‹  ๋ฐ ์กฐํšŒ ๋ชจ๋ธ๊ณผ์˜ ์ผ๊ด€์„ฑ์„ ๊ฒŒ์‹œ๊ธ€ ๋‹จ์œ„๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•จ.

๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ์˜ ์œ ์ผ์„ฑ ๋ณด์žฅ

Auto Increment

  • ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ ์œ ์ผ์„ฑ ๋ณด์žฅ ๋ชปํ•จ.
  • ๋ณด์•ˆ์ƒ ์ทจ์•ฝํ•จ.

UUID

  • ๋žœ๋ค I/O ์ฆ๊ฐ€ํ•จ.
  • Clustered Index ์„ฑ๋Šฅ ์ €ํ•˜.

Snowflake

  • ์‹œ๊ฐ„ ์ˆœ ์ •๋ ฌ
  • ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ ์œ ์ผ์„ฑ์„ ๋ณด์žฅํ•จ.
  • ID ์ƒ์œ„ ๋น„ํŠธ์— ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ๋ฐฐ์น˜ํ•˜์—ฌ, ํด๋Ÿฌ์Šคํ„ฐ๋“œ ์ธ๋ฑ์Šค๊ฐ€ ์‹œ๊ฐ„์ˆœ ์ •๋ ฌ๋กœ๋„ ๊ธฐ๋Šฅํ•จ.

ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€

์ˆ˜์ค€ Dirty Read
* ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ ์กฐํšŒ
Non-Repeatable Read
* ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์—์„œ, ๊ฐ™์€ ๊ฐ’์„ ์กฐํšŒํ•  ๋•Œ ๊ฐ™์€ ๊ฐ’์ด ์œ ์ง€๋˜๋Š”๊ฐ€?
Phantom Read
* ๊ฐ™์€ ์กฐ๊ฑด์œผ๋กœ ์žฌ์กฐํšŒํ–ˆ์„ ๋•Œ, ์ฒ˜์Œ์—๋Š” ์—†๋˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ํ˜„์ƒ
์ƒ์„ธ
Read Uncommitted O O O ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋„ ์ฝ์Œ.
Read Committed X O O ์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ๋งŒ ์ฝ์Œ.
Repeatable Read X X O ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ, SELECT๋ฅผ ๋ฐ˜๋ณตํ•˜๋”๋ผ๋„ ๊ฐ™์€ ๊ฐ’ ๋ณด์žฅ.
Serializable X X X ์™„๋ฒฝํ•˜๋‚˜, ๊ทน์‹ฌํ•œ ์„ฑ๋Šฅ ์ €ํ•˜.

MySQL ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€

  • ๊ธฐ๋ณธ์ ์œผ๋กœ, ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์—์„œ ๋™์ผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜๋ณต ์กฐํšŒํ•  ๋•Œ, ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅํ•จ. | Repeatable Read
  • MVCC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ€๋ถ€๋ถ„์˜ Phantom Read๋ฅผ ๋ฐฉ์ง€ํ•จ.
    • ์ฝ๊ธฐ ์ž‘์—… ์‹œ, ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์‹œ์ ์˜ ์Šค๋ƒ…์ƒท์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ์œผ๋ฉฐ, ๋ณ„๋„์˜ ๋ฝ ์—†์Œ.
    • ์“ฐ๊ธฐ ์ž‘์—… ์‹œ, Next-Key Lock์„ ํ†ตํ•ด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์‚ฝ์ž…์„ ๋ฐฉ์ง€ํ•จ.
    • SELECT FOR UPDATE, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์‚ฝ์ž…ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ UPDATEํ•˜๋Š” ๊ฒฝ์šฐ์™€ ๊ฐ™์€ ํŠน์ˆ˜ํ•œ ์ƒํ™ฉ์—์„œ Phantom Read ๋ฐœ์ƒ ๊ฐ€๋Šฅ.

๋™์‹œ์„ฑ ์ œ์–ด ์ „๋žต

  • ๋น„๊ด€์  ๋ฝ: ๋ฐ์ดํ„ฐ ์ˆ˜์ • ์‹œ์ ์— DB ๋ฝ์„ ํš๋“ํ•˜์—ฌ ์ •ํ•ฉ์„ฑ์„ ๊ฐ•์ œํ•จ.
  • ๋‚™๊ด€์  ๋ฝ: ๋ฒ„์ „ ์ •๋ณด ์นผ๋Ÿผ์„ ํ™œ์šฉํ•˜์—ฌ ์‹ค์ œ ์ˆ˜์ • ์‹œ์ ์— ์ถฉ๋Œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜์—ฌ ์ž ๊ธˆ ์œ ์ง€ ์‹œ๊ฐ„์„ ์ตœ์†Œํ™”ํ•จ.

๋ถ„์‚ฐ ํ™˜๊ฒฝ์˜ ํŠธ๋žœ์žญ์…˜ ํ•œ๊ณ„

  • Spring์˜ @Transactional ์–ด๋…ธํ…Œ์ด์…˜์€ ๋‹จ์ผ DB ์ธ์Šคํ„ด์Šค ๋‚ด๋ถ€์ ์ธ ์›์ž์„ฑ๋งŒ ๋ณด์žฅํ•จ.
  • ์„œ๋ฒ„๊ฐ€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ถ„์‚ฐ๋œ MSA ํ™˜๊ฒฝ์—์„œ๋Š” ๋ชจ๋“  ์„œ๋น„์Šค์˜ ์ƒํƒœ๋ฅผ ๋™์‹œ์— ์ œ์–ดํ•  ์ˆ˜ ์—†์Œ.

๋ถ„์‚ฐ ํ™˜๊ฒฝ์˜ ํŠธ๋žœ์žญ์…˜

  • 2PC ๋ฐฉ์‹์€ ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๋‚˜ ์ง€์—ฐ ์‹œ๊ฐ„, SPOF ๋ฌธ์ œ๋กœ ์ง€์–‘ํ•จ.
  • Transactional Outbox ํŒจํ„ด์„ ํ™œ์šฉํ•˜์—ฌ, ์•ฝ๊ฐ„์˜ ๋ถˆ์ผ์น˜๋ฅผ ๊ฐ์ˆ˜ํ•˜๊ณ  ์ตœ์ข… ์ผ๊ด€์„ฑ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•จ.

In-Memory | Redis

์บ์‹ฑ ๋Œ€์ƒ ๋ฐ์ดํ„ฐ ์„ ์ •

์œ ์˜์‚ฌํ•ญ

  • ๋ฉ”๋ชจ๋ฆฌ์˜ ์ €์žฅ๊ณต๊ฐ„์€ ๋””์Šคํฌ์˜ ์ €์žฅ๊ณต๊ฐ„์— ๋น„ํ•ด ์ž‘์Œ.
  • ์บ์‹œ์™€ ์›๋ณธ ์‚ฌ์ด์˜ ์ •ํ•ฉ์„ฑ์— ๊ด€ํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ถ”๊ฐ€์ ์œผ๋กœ ๋ฐœ์ƒํ•จ.

ํƒ€๊ฒŸ

  • ์กฐํšŒ ๋นˆ๋„๊ฐ€ ๋†’์€ ๋ฐ์ดํ„ฐ
  • ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋น„์œจ์ด ๋น„๋Œ€์นญ์ ์ธ ๋ฐ์ดํ„ฐ.
  • ์—ฐ์‚ฐ ๋น„์šฉ์ด ๋†’์€ ๋ฐ์ดํ„ฐ
  • ์ผ์‹œ์ ์ธ ๋ถˆ์ผ์น˜๊ฐ€ ํ—ˆ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ

์ ์šฉ

์ฝ๊ธฐ ์ „์šฉ ๋ชจ๋ธ | ArticleQueryModel
  • CQRS ํŒจํ„ด์— ๋”ฐ๋ผ ๊ฒŒ์‹œ๊ธ€, ์ข‹์•„์š” ์ˆ˜, ๋Œ“๊ธ€ ์ˆ˜ ๋“ฑ์„ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด ์บ์‹ฑ.
  • ์„œ๋น„์Šค ๊ฐ„์˜ API ํ˜ธ์ถœ ๋น„์šฉ, ๋ฐ์ดํ„ฐ ์กฐ๋ฆฝ ๋น„์šฉ์„ ์ œ๊ฑฐํ•˜์—ฌ ์กฐํšŒ ์„ฑ๋Šฅ ๊ทน๋Œ€ํ™”ํ•จ.
๊ฒŒ์‹œ๊ธ€ ID ๋ชฉ๋ก ยท ํŽ˜์ด์ง• ๋ฐ์ดํ„ฐ | ArticleIDList
  • ๊ฐ์ฒด ์ „์ฒด๊ฐ€ ์•„๋‹Œ PK ๋ชฉ๋ก๋งŒ์„ ์บ์‹ฑ.
  • ํŽ˜์ด์ง€ ์‚ฌ์ด์ฆˆ ๋ณ€๊ฒฝ, ๋ฐ์ดํ„ฐ ์ˆ˜์ • ์‹œ ์บ์‹œ ๋ฌดํšจํ™” ๋ฒ”์œ„๋ฅผ ์ตœ์†Œํ™”ํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ, ์œ ์—ฐ์„ฑ์„ ํ™•๋ณดํ•จ.
๊ณ ๋นˆ๋„ ์“ฐ๊ธฐ ๋ฐ์ดํ„ฐ | ArticleViewCount
  • DB ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋Œ€์‹ , Redis์— ๋จผ์ € ๊ธฐ๋กํ•˜๊ณ  ๋ฐฐ์น˜ ๋‹จ์œ„๋กœ DB์— ๋ฐ˜์˜ํ•˜๋Š” Write-Back ์ „๋žต.
  • RDB ๋ฝ์„ ์ตœ์†Œํ™”ํ•˜์—ฌ ์“ฐ๊ธฐ ๋ณ‘๋ชฉ์„ ํ•ด๊ฒฐํ•จ.
์‹ค์‹œ๊ฐ„ ์ง‘๊ณ„ ๋ฐ์ดํ„ฐ | HotArticleList
  • ๊ฐ€์ค‘์น˜์— ๋”ฐ๋ฅธ ์Šค์ฝ”์–ด๋ง ๊ฒฐ๊ณผ๋ฅผ ZSet์„ ์ด์šฉํ•ด ๊ด€๋ฆฌํ•จ.
  • ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€์ ์ธ ์ง‘๊ณ„ ์ฟผ๋ฆฌ, I/O ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ฑฐํ•จ.

๊ณ ๋ ค์‚ฌํ•ญ

Cache Stampede

TTL ๋งŒ๋ฃŒ ์งํ›„ ๋™์‹œ๋‹ค๋ฐœ์ ์ธ DB ์ ‘๊ทผ์ด ๋ฐœ์ƒํ•ด ์‹œ์Šคํ…œ์ด ๋งˆ๋น„๋˜๋Š” ํ˜„์ƒ.

๋ชฉํ‘œ
  • ๋…ผ๋ฆฌ์ ์ธ TTL๊ณผ ์‹ค์ œ TTL์„ ๋ถ„๋ฆฌํ•˜์—ฌ, ๋…ผ๋ฆฌ์ ์ธ TTL์€ ๋งŒ๋ฃŒ๋˜์—ˆ์œผ๋‚˜ ๋ฌผ๋ฆฌ์ ์ธ TTL์€ ๋‚จ๋Š” ๊ตฌ๊ฐ„์„ ๋‘์–ด, ๋ฐ์ดํ„ฐ๊ฐ€ ์™„์ „ํžˆ ๋งŒ๋ฃŒ๋˜๊ธฐ ์ „์— ๊ฐฑ์‹ ํ•  ๊ธฐํšŒ๋ฅผ ํ™•๋ณดํ•จ.
  • ๋ถ„์‚ฐ ๋ฝ์„ ํš๋“ํ•œ ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ DB์— ์ ‘๊ทผํ•˜์—ฌ ์บ์‹œ๋ฅผ ์ตœ์‹ ํ™”ํ•จ.
  • ๋ฝ ํš๋“์— ์‹คํŒจํ•œ ๋‚˜๋จธ์ง€ ์š”์ฒญ์˜ ๊ฒฝ์šฐ, ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ  ๊ณผ๊ฑฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์‘๋‹ต์„ฑ์„ ์œ ์ง€ํ•จ.

๊ตฌํ˜„

Cache Stampede

  • OptimizedCacheTTL: ๋…ผ๋ฆฌ์  TTL๊ณผ ์‹ค์ œTTL์„ ๋ถ„๋ฆฌํ•จ.
  • @OptimizedCacheable: ์บ์‹œ ๋Œ€์ƒ ๋ฉ”์„œ๋“œ์— ์ ์šฉํ•˜๋Š” ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜. ์ข…๋ฅ˜์™€ ๋…ผ๋ฆฌ์  TTL ์„ค์ •.
  • OptimizedCacheAspect: @OptimizedCacheable๊ฐ€ ์„ ์–ธ๋œ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์‹œ, OptimizedCacheManager๋กœ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„.
  • OptimizedCacheManager: Redis๋ฅผ ์šฐ์„  ์กฐํšŒํ•˜์—ฌ,
    • ์บ์‹œ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ๋˜๋Š” ๋ฌผ๋ฆฌ์  ๋งŒ๋ฃŒ ์‹œ, ์›๋ณธ DB๋ฅผ ์กฐํšŒํ•˜๊ณ  Redis์— ์ €์žฅํ•จ.
    • ๋…ผ๋ฆฌ์ ์œผ๋กœ ์œ ํšจํ•  ๊ฒฝ์šฐ, ์ฆ‰์‹œ ๋ฐ˜ํ™˜.
    • ๋…ผ๋ฆฌ์  ๋งŒ๋ฃŒ ์‹œ, OptimizedCacheLockProvider ๋กœ ๋ฝ์„ ์š”์ฒญ.
      • ํš๋“ํ•œ ๊ฒฝ์šฐ, ์›๋ณธ DB๋ฅผ ์กฐํšŒํ•˜๊ณ  ์บ์‹œ๋ฅผ ๊ฐฑ์‹ ํ•จ.
      • ํš๋“ํ•˜์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ, ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ์—์„œ ๊ฐฑ์‹  ์ค‘์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ  ๊ณผ๊ฑฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•จ.
์žฅ์ 
  • ๋ถ„์‚ฐ ๋ฝ์„ ํ†ตํ•ด, ๋…ผ๋ฆฌ์  ๋งŒ๋ฃŒ ์ดํ›„์˜ ๋™์‹œ๋‹ค๋ฐœ์ ์ธ ์š”์ฒญ์„ ๋ฐฉ์ง€ํ•จ.
  • ์žฅ์•  ์ƒํ™ฉ์—์„œ๋„ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋‚จ์•„์žˆ๋Š” ์ž๋ฃŒ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ, ๊ฐ€์šฉ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•จ.

Message Broker | Kafka

๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์˜ ์—ญํ• 

  • Producer๊ฐ€ ์ƒ์‚ฐํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ ์ ˆํ•œ Consumer์—๊ฒŒ ์ „๋‹ฌํ•จ.
  • Producer, Consumer ์‚ฌ์ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„ํผ๋งํ•˜๋ฉฐ, ๋‘˜ ์‚ฌ์ด์˜ ์ž…์ถœ๋ ฅ ์†๋„ ์ฐจ์ด์— ์˜ํ•œ ๋ณ‘๋ชฉ์„ ์™„ํ™”ํ•จ.
  • ์†Œ๋น„ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฆ‰์‹œ ์‚ญ์ œํ•˜์ง€ ์•Š๊ณ  ๋ณด๊ด€ํ•˜์—ฌ ์žฅ์•  ๋ณต๊ตฌ ์‹œ ์žฌ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•จ.
  • ๋ฉ”์‹œ์ง€๋ฅผ ํŒŒํ‹ฐ์…˜ ๋ณ„๋กœ ๋ถ„๋ฐฐํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ˆœ์„œ์˜ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅํ•˜๊ณ  ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ.

๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์˜ ํ•„์š”์„ฑ

  • ์„œ๋น„์Šค๊ฐ„ ๋””์ปคํ”Œ๋ง
    • Producer๋Š” Consumer์˜ ์ƒํƒœ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰ํ•  ์ˆ˜ ์žˆ์Œ.
    • ์‹œ์Šคํ…œ ํ™•์žฅ ์‹œ, Consumer์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์œ ์—ฐํ•˜๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ.
  • ์žฅ์•  ์ „ํŒŒ ๋ฐฉ์ง€
    • Producer๊ฐ€ Consumer์˜ ์žฅ์• ๋กœ๋ถ€ํ„ฐ ์ž์œ ๋กœ์›Œ์ง.
    • ์žฅ์•  ๋ณต๊ตฌ ์ดํ›„ ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค์‹œ ์†Œ๋น„ํ•˜์—ฌ, ์ตœ์ข… ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Œ.
  • ํŠธ๋ž˜ํ”ฝ ์„œ์ง€ ๋Œ€์‘
    • ํŠธ๋ž˜ํ”ฝ์ด ํญ์ฆํ•˜๋Š” ์ƒํ™ฉ์—์„œ, ๋ฉ”์‹œ์ง€๋ฅผ Kafka์— ๋ณด๊ด€ํ•˜์—ฌ Consumer์˜ ์ฒ˜๋ฆฌ ๋Šฅ๋ ฅ์„ ์ดˆ๊ณผํ•˜๋Š” ๋ถ€ํ•˜๋กœ๋ถ€ํ„ฐ ์‹œ์Šคํ…œ์„ ๋ณดํ˜ธํ•จ.

์ „์†ก ๋ณด์žฅ ์ˆ˜์ค€

At-Least-Once Delivery

  • ๋ฉ”์‹œ์ง€๊ฐ€ ์œ ์‹ค๋˜์ง€ ์•Š์Œ์„ ๋ณด์žฅํ•จ.
  • ์ค‘๋ณต ๋ฐœํ–‰๋  ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ.

Exactly-Once

  • ๋ฉ”์‹œ์ง€๊ฐ€ ์ค‘๋ณต ์—†์ด ์ •ํ™•ํ•˜๊ฒŒ ํ•œ๋ฒˆ๋งŒ ์ฒ˜๋ฆฌ๋จ์„ ๋ณด์žฅํ•จ.
  • ์‹œ์Šคํ…œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ํฌ๊ณ , ๊ตฌํ˜„ ๋ณต์žก๋„๊ฐ€ ๋†’์Œ.

Transactional Outbox ๊ตฌํ˜„

ํ๋ฆ„

  1. ์ด๋ฒคํŠธ ์บก์ณ: ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰ ์ค‘์—OutboxEventPublisher::publish() ํ˜ธ์ถœ -> ApplicationEvent ๋ฐœ์ƒ.
  2. BEFORE_COMMIT: MessageRelay::createOutbox()๊ฐ€ DB์˜ Outbox ํ…Œ์ด๋ธ”์— ๊ธฐ๋กํ•จ.
    • . @TransactionalEventListener(phase = BEFORE_COMMIT) ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ปค๋ฐ‹ ์ง์ „์— ์ˆ˜ํ–‰๋จ์œผ๋กœ์จ ์›์ž์„ฑ์„ ๋ณด์žฅํ•จ.
  3. AFTER_COMMIT: MessageRelay::publishEvent() ์“ฐ๋ ˆ๋“œ๊ฐ€, ์ปค๋ฐ‹ ํ›„ Kafka๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•จ.
    • @Async()์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๋ณ„๋„ ์“ฐ๋ ˆ๋“œ์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌํ•จ. ์‘๋‹ต์„ฑ์„ ๋ณด์กดํ•˜๊ณ  ์ง€์—ฐ์„ ์ตœ์†Œํ™”ํ•จ.
    • ์ „์†ก์— ์„ฑ๊ณตํ•œ ๊ฒฝ์šฐ, Outbox ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•จ.
  4. ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์„œ๋ฒ„ ์ค‘๋‹จ์œผ๋กœ ๋‚จ์€ ๋ฐ์ดํ„ฐ๋Š” MessageRelay::publishPendingEvent() ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์ฃผ๊ธฐ์ ์œผ๋กœ ์žฌ๋ฐœํ–‰ํ•จ.

๊ตฌ์„ฑ

OutboxEventPublisher

  • ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์ ์œผ๋กœ ํ˜ธ์ถœํ•จ.
  • ๋‚ด๋ถ€์ ์œผ๋กœ ApplicationEventListener๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ Spring ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ด.

MessageRelay

  • @TransactionalEventListener์–ด๋…ธํ…Œ์ด์…˜์˜ phase ์„ค์ •์„ ํ†ตํ•ด DB ์ปค๋ฐ‹ ์ง์ „๊ณผ ์งํ›„์— ๋ฉ”์‹œ์ง€๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ฐœํ–‰ํ•จ.
  • AFTER_COMMIT ์‹œ์ ์˜ ๋ฐœํ–‰์€ ๋ณ„๋„์˜ ๋น„๋™๊ธฐ ์“ฐ๋ ˆ๋“œ(messageRelayPublishEventExecutor)์—์„œ ์ฒ˜๋ฆฌํ•˜์—ฌ, ์„œ๋ฒ„์˜ ์‘๋‹ต์„ฑ์„ ๋ณด์กดํ•จ. ์ถ”๊ฐ€์ ์œผ๋กœ, ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ฉ”์‹œ์ง€ ๋ฐœํ–‰ ๊ฐ„์˜ ์ง€์—ฐ์„ ์ตœ์†Œํ™”ํ•จ.
  • publishPendingEvent() ๋ฉ”์„œ๋“œ๊ฐ€ MessageRelayCoordinator๋กœ๋ถ€ํ„ฐ ํ• ๋‹น๋ฐ›์€ ์ƒค๋“œ ๋‚ด์˜ ๋ฏธ๋ฐœํ–‰ ๋ฉ”์‹œ์ง€๋ฅผ ์กฐํšŒํ•˜์—ฌ At-least-once delivery๋ฅผ ๊ตฌํ˜„ํ•จ. MessageRelayCoordinator
  • ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค์™€ ์ฃผ๊ธฐ์ ์œผ๋กœ ping() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด, ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค์˜ ์ƒ์กด ์—ฌ๋ถ€๋ฅผ ๊ด€๋ฆฌํ•จ.

ํŠน์ง•

  • ๋ฐœํ–‰ ์™„๋ฃŒ๋œ ๋ฐ์ดํ„ฐ๋Š” ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋Œ€์‹  ์‚ญ์ œํ•จ. Outbox ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ๋ฅผ ์ผ์ • ์ดํ•˜๋กœ ์œ ์ง€ํ•จ.
  • shardKey๋ฅผ Kafka ์ „์†ก ์‹œ ํŒŒํ‹ฐ์…˜ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜์—ฌ, ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•จ.
  • MessageRelay::publishPendingEvent()์— ์˜ํ•ด ๋™์ผ ๋ฉ”์‹œ์ง€๊ฐ€ ์ค‘๋ณต ๋ฐœํ–‰๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, Consumer์—๋Š” ๋ฉฑ๋“ฑ์„ฑ ์ฒ˜๋ฆฌ๊ฐ€ ์š”๊ตฌ๋จ.

์ •ํ•ฉ์„ฑ ์ „๋žต

Consumer ๋ฉฑ๋“ฑ์„ฑ ์„ค๊ณ„

Consumer์—๊ฒŒ ๋™์ผํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ์ „๋‹ฌ๋˜๋”๋ผ๋„, ์‹œ์Šคํ…œ์˜ ์ƒํƒœ๊ฐ€ ์ตœ์ดˆ 1ํšŒ ์ฒ˜๋ฆฌ๋œ ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜๋„๋ก ํ•˜๋Š” ์„ค๊ณ„.

์ค‘๋ณต ๋ฐœ์ƒ์˜ ์›์ธ

  • MessageRelay๋Š” ๋ฉ”์‹œ์ง€ ์ „์†ก ํ›„, ์ˆ˜์‹  ํ™•์ธ์„ ๋ฐ›์ง€ ๋ชปํ•  ๊ฒฝ์šฐ ์„ฑ๊ณตํ•  ๋•Œ๊นŒ์ง€ ์žฌ์ „์†กํ•จ. ์ด ๊ณผ์ •์—์„œ ๋„คํŠธ์›Œํฌ ์ง€์—ฐ ๋“ฑ์œผ๋กœ ์ธํ•ด ๋™์ผํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ์ค‘๋ณต ๋ฐœํ–‰๋  ์ˆ˜ ์žˆ์Œ.
  • Kafka Consumer ๊ทธ๋ฃน ๋‚ด์—์„œ ํŒŒํ‹ฐ์…˜ ์†Œ์œ ๊ถŒ์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ, ๋งˆ์ง€๋ง‰์œผ๋กœ ์ปค๋ฐ‹๋œ ์˜คํ”„์…‹ ์ดํ›„ ๋ฉ”์‹œ์ง€๊ฐ€ ์ค‘๋ณต ์†Œ๋น„๋  ์ˆ˜ ์žˆ์Œ.

๋ฉฑ๋“ฑ์„ฑ ํ™•๋ณด ์ „๋žต

Unique Key Constraint

  • ArticleCreatedHandler
  • ArticleQueryModelRepository๊ฐ€ Key๋กœ articleId๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฎ์–ด์“ฐ๋„๋ก ์„ค๊ณ„๋จ.
  • ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ์ˆœ์„œ๊ฐ€ ๋’ค๋ฐ”๋€Œ๋Š” Out-of-Order ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋‚˜, ํ”„๋กœ์ ์…˜ ๋ชจ๋ธ ํŠน์„ฑ์ƒ ์น˜๋ช…์ ์ธ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จํ•จ.

Unique Index Constraint

  • ArticleLikeCountRepository
  • DB์˜ UNIQUE INDEX ์ œ์•ฝ ์กฐ๊ฑด ํ™œ์šฉํ•จ.
  • DB ์—”์ง„์— ์ข…์†์ ์ž„.

์ƒํƒœ ๊ธฐ๋ฐ˜ ์—…๋ฐ์ดํŠธ

  • ArticleViewCountBackUpProcessor
  • ์ˆ˜์น˜๋ฅผ ๋”ํ•˜๋Š” ์—ฐ์‚ฐ ๋Œ€์‹ , ์ง‘๊ณ„๋œ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฎ์–ด์“ฐ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉฑ๋“ฑ์„ฑ์„ ์œ ์ง€ํ•จ.

๊ณ ๋ ค์‚ฌํ•ญ

  • ๋ช…์‹œ์ ์ธ ๋ฉฑ๋“ฑ์„ฑ ์ œ์–ด ๋Œ€์‹ , ์ธํ”„๋ผ์˜ ์ œ์•ฝ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•จ.
  • service:hot-article, service:article-read๊ณผ ๊ฐ™์€ ๋ถ€๊ฐ€์ ์ธ ๋ฐ์ดํ„ฐ, ๋˜๋Š” ํ”„๋กœ์ ์…˜ ๋ชจ๋ธ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋Š” ๊ธฐํƒ€ ์„œ๋น„์Šค์— ๋น„ํ•ด ์ค‘์š”๋„๊ฐ€ ๋‚ฎ๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ณ  ์ธํ”„๋ผ ์ˆ˜์ค€์—์„œ๋งŒ ์ œ์–ดํ•จ.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages