๐Ÿ“Œ ์‚ฌ์šฉ ๊ณ„๊ธฐ

์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ DB์— ์ ‘๊ทผํ•˜์—ฌ ์กฐํšŒ ๋ฐ ๋ช…๋ น(์ˆ˜์ •,์‚ญ์ œ) ๋ฅผ ํ•˜๋Š” ๋ถ€๋ถ„๋“ค์ด ์„œ๋น„์Šค ๋กœ์ง์— ๋งŽ์ด ์„ž์—ฌ ์˜์กดํ•˜๋Š” ๊ด€๊ณ„๋ฅผ ํ˜•์„ฑํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ์ด๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ์‹ถ์–ด CQRS ํŒจํ„ด์„ ๊ณต๋ถ€ํ•˜๊ณ  ์ ์šฉํ•ด๋ณด๊ณ ์ž ์ •๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

 

๐Ÿ“ŒCQRS ํŒจํ„ด์ด๋ž€?  

Command and Query Responsibility Segregation ์˜ ์•ฝ์ž๋กœ ๋ช…๋ น ์˜์—ญ๊ณผ ์กฐํšŒ ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด์„ ๋งํ•œ๋‹ค.  

์„œ๋กœ์˜ ์ฑ…์ž„์„ ๋‚˜๋ˆ„์–ด ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด CQRS์ธ๋ฐ ๊ทธ๋Ÿผ ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ๋ช…๋ น๊ณผ ์กฐํšŒ๋Š” ๋ฌด์—‡์ผ๊นŒ?

 

๐Ÿ“๋ช…๋ น๊ณผ ์กฐํšŒ

์šฐ๋ฆฌ๋Š” DB๋ฅผ ๋‹ค๋ฃฐ๋•Œ CRUD ( Create / Read / Update / Delete ) ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทผ๋ฐ CQRS๋Š” ์—ฌ๊ธฐ์„œ ๊ตณ์ด Read๋งŒ ๋นผ์„œ ์กฐํšŒ๋ผ๊ณ  ํ•˜๊ณ  ๋‚˜๋จธ์ง€๋ฅผ ๋ช…๋ น์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค. ์™œ?

 

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

 

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

๋”ฐ๋ผ์„œ ๋ชจ๋ธ์ด ๋ณ€ํ•จ์— ๋”ฐ๋ผ ์ €์žฅ, ์ˆ˜์ •, ์‚ญ์ œ์— ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ธ๊ณผ ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ธ ๊ฐ„์˜ ์ฐจ๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋˜์—ˆ๊ณ  ๊ทธ๋ž˜์„œ ์ด๋ฅผ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด์„œ ๋“ฑ์žฅํ•œ๊ฒŒ CQRS๋‹ค.

 

 

๐Ÿ“ํ•˜๋ฉด ๋ญ๊ฐ€ ์ข‹์€๋ฐ ?

์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ„๋ฉด ๋ญ๊ฐ€ ์ข‹์„๊นŒ? 

  • ์ฒซ์งธ, ๋„๋ฉ”์ธ ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค

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

  • ๋‘˜์งธ, Command ์ชฝ๊ณผ Query ์ชฝ์˜ ๊ฐ์ž์— ๋งž๋Š” ๋‹ค๋ฅธ ์ธํ”„๋ผ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. 

๋งŒ์•ฝ Command DB์™€ Query DB๋ฅผ ๋‚˜๋ˆ„๋Š” ๋ฐฉ์‹์„ ์ฑ„ํƒํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ๊ฐ์— ๋งž๋Š” ์ธํ”„๋ผ๋ฅผ ์„ ํƒํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด, ์„ฑ๋Šฅ์ ์œผ๋กœ ํ–ฅ์ƒ์„ ๊ธฐ๋Œ€ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Read์™€ Write์˜ ๋น„์œจ์ด 1000 : 1 ์ด๋ผ๊ณ  ํ•˜๋‹ˆ ๋งŽ์€ ์š”์ฒญ ์ •๋„์— ๋”ฐ๋ผ์„œ๋„ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

 

๐Ÿ“๊ทธ๋ž˜์„œ ์ ์šฉ์€?

CQRS๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ 3๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค.

 

1) Simple CQRS Architecture

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋Š” ๋ถ„๋ฆฌํ•˜์ง€ ์•Š๊ณ  ๋ชจ๋ธ ๊ณ„์ธต๋งŒ ๋ถ„๋ฆฌํ•œ๋‹ค. ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋Š” ๋ถ„๋ฆฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ƒ ๋ณ€ํ™”๋Š” ์—†๋‹ค.

 

2) CQRS with separated persistence mechanisms

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ Command(๋ช…๋ น)์šฉ, Query(์กฐํšŒ)์šฉ DB๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ทธ ์‚ฌ์ด์— ๋ณ„๋„ ๋ธŒ๋กœ์ปค๋ฅผ ๋‘์–ด ๋‘ DB๊ฐ„์— ๋™๊ธฐํ™”์‹œํ‚ค๋Š” ๋ฐฉ์‹. ์‹ฌ์ง€์–ด ์กฐํšŒ์šฉ DB๋ฅผ ๋ณ„๋„์˜ ๋‹ค๋ฅธ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชจ๋ธ์— ๋งž๊ฒŒ ์กฐ์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ค‘๊ฐ„์—์„œ ๋™๊ธฐํ™”์— ๊ด€์—ฌํ•˜๋Š” ๋ธŒ๋กœ์ปค์˜ ์„ฑ๋Šฅ๊ณผ ์‹ ๋ขฐ์„ฑ์ด ๋งค์šฐ ๋†’์•„์•ผ ํ•œ๋‹ค๋Š” ์กฐ๊ฑด์ด ๋ถ™๊ฒŒ๋œ๋‹ค. 

 

3) CQRS ์™€ Event Sourcing

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

 

 

๐Ÿ“ํ•ด๋ณผ ๋ฐฉ๋ฒ•์€?

์•„์ง์€ CQRS์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์ ๊ณ , ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ ํ•˜๋‚˜๋งŒ ๋‘๊ณ  ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๋Š” ์ž‘์—…๋งŒ ํ•ด๋ณผ ๊ฑฐ๊ธฐ ๋•Œ๋ฌธ์— 1๋ฒˆ Simple CQRS Architecture๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค. 

 


โž• ๊ณต๋ถ€์ž๋ฃŒ

 

CQRS ํŒจํ„ด ์•Œ์•„๋ณด๊ธฐ

๋“ค์–ด๊ฐ€๋ฉฐ Event Driven Architecture์— ๋Œ€ํ•œ ๊ฒฝํ—˜์ด ์žˆ์œผ์‹œ๊ฑฐ๋‚˜, ํ˜น์€ ๊ทธ๊ฒƒ์— ๊ด€์‹ฌ์ด ์žˆ์œผ์‹  ๋ถ„์ด๋ผ๋ฉด ์ข…์ข… CQRS๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋“ฃ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ € ๋˜ํ•œ ์ข…์ข… ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ •ํ™•ํ•˜๊ฒŒ CQRS๊ฐ€ ์–ด๋–ค ๊ฒƒ์ธ์ง€

always-kimkim.tistory.com

 

[CQRS] CQRS๋Š” ์–ด๋–ป๊ฒŒ ์ ์šฉํ• ๊นŒ?

์–ด๋–ป๊ฒŒ ์ ์šฉํ• ๊นŒ? ์ „ํ†ต์ ์ธ CRUD ์‹œ์Šคํ…œ์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์‹œ์Šคํ…œ ๊ตฌ์กฐ์— CQRS๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ 3๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. (1) Simple CQRS Architecture ๋ฐ์ดํ„ฐ

kellis.tistory.com

 

'Computer Science > Design Pattern' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด(Factory Method Pattern)  (1) 2022.12.24

+ Recent posts