Cache

์บ์‹œ(cache)๋ž€?

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

ํ•˜๋“œ๋””์Šคํฌ๋Š” ์šฉ๋Ÿ‰์ด ์•„์ฃผ ํฌ์ง€๋งŒ ์†๋„๊ฐ€ ๋А๋ฆฌ๊ณ , ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ(RAM)์˜ ์šฉ๋Ÿ‰์€ 1/100์ •๋„๋กœ ์ž‘์ง€๋งŒ ์†๋„๋Š” ์‹ญ๋งŒ๋ฐฐ ์ •๋„ ๋น ๋ฅด๋‹ค. ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ๋Š” ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ(RAM)์˜ 1/100 ์ •๋„ ์šฉ๋Ÿ‰์ด์ง€๋งŒ ์†๋„๋Š” ํ›จ์”ฌ ๋น ๋ฅด๋‹ค.

์ฆ‰, ์‚ฌ์šฉ๋˜์—ˆ๋˜ ๋ฐ์ดํ„ฐ๋Š” ๋‹ค์‹œ ์‚ฌ์šฉ๋˜์–ด์งˆ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค๋Š” ๊ฐœ๋… ์„ ์ด์šฉํ•˜์—ฌ, ๋‹ค์‹œ ์‚ฌ์šฉ๋  ํ™•๋ฅ ์ด ๋†’์€ ๊ฒƒ์€ ๋” ๋น ๋ฅด๊ฒŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฐœ๋…์ด๋‹ค.

์–ธ์ œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„๊นŒ?

  1. ๋‹จ์ˆœํ•œ ๋ฐ์ดํ„ฐ(์ •๋ณด)

  2. ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ œ๊ณตํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ

  3. ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ฃผ๊ธฐ๊ฐ€ ๋นˆ๋ฒˆํ•˜์ง€ ์•Š๊ณ , ๋‹จ์œ„ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ

  4. ๋ฐ์ดํ„ฐ์˜ ์ตœ์‹ ํ™”๊ฐ€ ๋ฐ˜๋“œ์‹œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ด๋ค„์ง€์ง€ ์•Š์•„๋„ ์„œ๋น„์Šค ํ’ˆ์งˆ์— ์˜ํ–ฅ์„ ๊ฑฐ์˜ ์ฃผ์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ

์ด๋ ‡๊ฒŒ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„๊ฐ„ ๋ถˆํ•„์š”ํ•œ ํŠธ๋ž˜ํ”ฝ์„ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ทธ๋กœ ์ธํ•ด ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์˜ ๋ถ€ํ•˜๊ฐ€ ๊ฐ์†Œ๋œ๋‹ค. ๋˜ํ•œ ์บ์‹œ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฝ์–ด์™€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ณ ๊ฐ์—๊ฒŒ ์พŒ์ ํ•œ ์„œ๋น„์Šค ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.

์›น์„œ๋ฒ„

์›น์— ์š”์ฒญ์„ ๋‚ ๋ฆฌ๋ฉด, ์š”์ฒญ์€ ์›น ๋ธŒ๋ผ์šฐ์ €๋กœ๋ถ€ํ„ฐ ํ•˜๋“œ ๋””์Šคํฌ์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์— ์žˆ๋Š” ์ •์  ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์›น ์„œ๋ฒ„๋กœ ์ „๋‹ฌ๋œ๋‹ค.

์ฒซ ๋ฒˆ์งธ ์š”์ฒญ์—์„œ๋Š” ํ•˜๋“œ ๋””์Šคํฌ๋Š” ์บ์‹œ๋ฅผ ํ™•์ธํ•˜์—ฌ ์บ์‹œ ๋ฏธ์Šค(cache miss)๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•˜๋“œ ๋“œ๋ผ์ด๋ธŒ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์ถ”ํ›„์— ๋‹ค์‹œ ์š”์ฒญ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ์„ ๊ฐ€์ •ํ•˜๊ณ  ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.

์ดํ›„ ์š”์ฒญ๋ถ€ํ„ฐ๋Š” ์บ์‹œ ์กฐํšŒ์‹œ ์บ์‹œ ํžˆํŠธ(cache hit)๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋Š” ์บ์‹œ ๋ฏธ์Šค๋ฅผ ์ผ์œผํ‚ค๊ธฐ ์ „๊นŒ์ง€ ๋ฒ„ํผ์—์„œ ์ œ๊ณต๋œ๋‹ค.

Cache Miss

CPU๊ฐ€ ์ฐธ์กฐํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์บ์‹œ์— ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ

Cache Hit

CPU๊ฐ€ ์ฐธ์กฐํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์บ์‹œ์— ์กด์žฌํ•  ๋•Œ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์บ์‹ฑ

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

์‘๋‹ต ์บ์‹ฑ

์›น ์„œ๋ฒ„์˜ ์‘๋‹ต์€ ๋ฉ”๋ชจ๋ฆฌ์— ์บ์‹ฑ๋œ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์บ์‹œ๋Š” ๋กœ์ปฌ ์ธ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜๊ฑฐ๋‚˜ ์บ์‹œ ์„œ๋ฒ„ ์œ„์—์„œ ์‹คํ–‰๋˜๋Š” redis์™€ ๊ฐ™์€ ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

HTTP ํ—ค๋”๋ฅผ ํ†ตํ•œ ๋ธŒ๋ผ์šฐ์ € ์บ์‹ฑ

๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €๋Š” HTML, JS, CSS, ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ํŒŒ์ผ๋“ค์„ ์ž„์‹œ ์ €์žฅ์„ ์œ„ํ•ด HTTP ์บ์‹œ(์›น ์บ์‹œ)์˜ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค. ์„œ๋ฒ„ ์‘๋‹ต์ด ์˜ฌ๋ฐ”๋ฅธ HTTP ํ—ค๋” ์ง€์‹œ์ž๋ฅผ ์ œ๊ณตํ•ด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‘๋‹ต์„ ์บ์‹ฑํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ธฐ์™€ ์ง€์† ๊ธฐ๊ฐ„์„ ์ง€์‹œํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๋ฆฌ์†Œ์Šค๊ฐ€ ๋กœ์ปฌ ์บ์‹œ๋กœ๋ถ€ํ„ฐ ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ํ–ฅ์ƒ๋œ๋‹ค.

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ ๋ฐ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๋‹ค๋ฅธ ๊ตฌ์„ฑ์š”์†Œ์— ๋Œ€ํ•œ ๋ถ€ํ•˜๊ฐ€ ์ค„์–ด๋“ ๋‹ค.

  • ๋ถˆํ•„์š”ํ•œ ๋Œ€์—ญํญ์— ๋Œ€ํ•œ ์ง€๋ถˆ๋น„์šฉ์ด ์ค„์–ด๋“ ๋‹ค.

redis๋ž€?

REmote DIctionary Server์˜ ์•ฝ์ž๋กœ ๋Œ€์šฉ๋Ÿ‰ ์ฒ˜๋ฆฌ ๊ด€๋ จ ๊ธฐ์ˆ ์ด๋‹ค.

  • ๋ฉ”๋ชจ๋ฆฌ ์œ„์—์„œ ๋™์ž‘ํ•˜๋Š” Key/value ์ €์žฅ์†Œ(Store)์ธ Redis๋Š” NoSQL DBMS๋กœ ๋ถ„๋ฅ˜๋˜๋ฉฐ ๋™์‹œ์— Memcached์™€ ๊ฐ™์€ ์ธ๋ฉ”๋ชจ๋ฆฌ(In-memory) ์†”๋ฃจ์…˜์œผ๋กœ ๋ถ„๋ฆฌ๋œ๋‹ค.

  • ๋ช…์‹œ์ ์œผ๋กœ ์‚ญ์ œ, expire๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐ์ดํ„ฐ๋Š” ์‚ญ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค.(์˜๊ตฌ ๋ณด์กด)

  • ์—ฌ๋Ÿฌ๋Œ€์˜ ์„œ๋ฒ„ ๊ตฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ธ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ(In-memory Cache)๋ž€?

์ธ ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ(RAM)์—๋งŒ ์˜ฌ๋ ค๋†“๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ผ์ข…์ด๋‹ค. ์ผ๋ฐ˜์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(RDBMS)๋Š” ๋””์Šคํฌ(HDD, SSD)์— ๋ฐ์ดํ„ฐ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅํ•ด๋†“๊ณ , ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์ฝ์–ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

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

Varnish ๋ž€?

https://www.eurovps.com/blog/wp-content/uploads/2012/10/varnish-diagram.jpg

Varnish๋Š” BSD ๋ผ์ด์„ ์Šค๋ฅผ ๋”ฐ๋ฅด๋Š” ์˜คํ”ˆ ์†Œ์Šค ์›น ์บ์‹œ ์†Œํ”„ํŠธ์›จ์–ด์ด๋‹ค.

์ฃผ๋กœ nginx ์•ž๋‹จ์—์„œ url ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ผํ•œ url์ด ๋“ค์–ด์˜ค๋ฉด ์‘๋‹ต๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋ณด๋‚ด์ค„๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

VCL

Varnish๋Š” ์„ค์ •์„ ์œ„ํ•ด VCL์ด๋ผ๋Š” ๋ณ„๋„์˜ DSL(Domain-Specific Language)์„ ์ œ๊ณตํ•œ๋‹ค. ์‚ฌ์šฉ์ž๋Š” VCL์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ • ํŒŒ์ผ์„ ์ž‘์„ฑํ•œ๋‹ค. VCL๋กœ ์ž‘์„ฑ๋œ ์„ค์ • ํŒŒ์ผ์˜ ๋‚ด์šฉ์€ C ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ๋ณ€ํ™˜๋˜์—ˆ๋‹ค๊ฐ€ ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ปดํŒŒ์ผ๋œ๋‹ค. Varnish๋Š” ์‹œ์ž‘ํ•  ๋•Œ๋‚˜ ์‹คํ–‰ ์ค‘์ผ ๋•Œ ์ด ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒŒ์ผ์„ ๋กœ๋“œํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค. ๋™์‹œ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์„ค์ •์„ ๋กœ๋“œํ•œ ํ›„์— Varnish ์‹คํ–‰ ์ค‘์— ์„ค์ •์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

https://www.varnish-software.com/static/book/VCL_Basics.html

๋‹ค์Œ ๊ทธ๋ฆผ์€ Varnish๊ฐ€ ์›น ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณผ์ •์„ ๊ฐ„๋žตํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ด๋‹ค.

purge

purge๋Š” ์บ์‹ฑ๋˜์–ด ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ TTL(Time - To - Live)์ด ์ง€๋‚˜๊ฐ€๊ธฐ์ „์— ๊ฐ•์ œ๋กœ ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‘๊ฐ€์ง€ ํ˜•ํƒœ๋กœ purge ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

  1. ํŠน์ • url์„ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น ๋ฐ์ดํ„ฐ ์‚ญ์ œ

  2. ์ •๊ทœํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•ด ํ•ด๋‹น ํŒจํ„ด์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•

    • ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜์ง€๋Š” ์•Š๊ธฐ ๋•Œ๋ฌธ์— ban ์ด๋ผ๊ณ  ํ•œ๋‹ค.

๋‘ ๋ฒˆ์งธ๋Š” ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜์ง€๋Š” ์•Š๊ธฐ ๋•Œ๋ฌธ์— ban์ด๋ผ๊ณ  ํ•œ๋‹ค. ์บ์‹œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ban์œผ๋กœ ์ง€์ •๋œ ์ •๊ทœ ํ‘œํ˜„์‹์— ํ•ด๋‹นํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค. ์ •๊ทœ ํ‘œํ˜„์‹์„ ์ถ”๊ฐ€ํ•  ๋•Œ์—๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ •๊ทœ ํ‘œํ˜„์‹์— ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์ƒˆ๋กœ์ด ์ถ”๊ฐ€๋œ ban ์กฐ๊ฑด์„ ๊ฒ€์‚ฌํ•˜์—ฌ, ์กฐ๊ฑด์„ ๋งŒ์กฑ์‹œํ‚ค๋ฉด ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

ban req.http.host == "www.naver.com" && req.url ~ "\\.jpg$"

๋‹ค์Œ๊ณผ ๊ฐ™์ด ban์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ณ , ํ•ด๋‹น ํŒจํ„ด์— ํฌํ•จ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ์บ์‹ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์‡ผํ•‘๋ชฐ ์ƒํ’ˆ์ƒ์„ธ ํŽ˜์ด์ง€๋Š” ๋ณ€๊ฒฝ์ด ์ ์œผ๋‹ˆ url ๊ธฐ๋ฐ˜์œผ๋กœ varnish cache๋ฅผ ํƒœ์›Œ ์„œ๋ฒ„๊นŒ์ง€ ์•ˆ๋ณด๋‚ด๊ณ , redis๋Š” ์„œ๋น„์Šค ์š”์ฒญ์ด ๋Š˜์–ด๋‚˜๋Š” ๊ฒฝ์šฐ DB ๋ถ€ํ•˜๊ฐ€ ๊ฐ€์ค‘๋˜๋Š” API์— ๊ฑธ์–ด์„œ ๋ฉ”๋ชจ๋ฆฌ์— ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ €์žฅ์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค.

Spring Cache

Spring Caching Abstraction๋Š” ๋‹ค๋ฅธ ์บ์‹œ ์†”๋ฃจ์…˜์„ Spring CacheManager๋ฅผ ํ†ตํ•ด์„œ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. Spring Caching Abstraction๋Š” ์ž๋ฐ” ๋ฉ”์†Œ๋“œ์— ์บ์‹ฑ์„ ์ ์šฉํ•˜๋ฉฐ, ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋  ๋•Œ ๋„˜์–ด์˜จ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์— ๋”ฐ๋ผ์„œ ์บ์‹œ๋ฅผ ์ ์šฉํ•œ๋‹ค.

์‚ฌ์šฉ๋ฐฉ๋ฒ•

  • pom.xml

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

pom.xml์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•œ ํ›„ @EnableCaching ์–ด๋…ธํ…Œ์ด์…˜์„ ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด Spring Container์— ๋นˆ์ด ๋“ฑ๋ก๋œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ConcurrentMapCacheManager ๊ฐ€ ๋“ฑ๋ก๋˜๋ฉฐ, ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋‹ค๋ฅธ ์บ์‹œ ๊ตฌํ˜„์ฒด๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ EHCache, Redis ๋“ฑ ์„œ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ์„ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋ฉด, EHCacheManager, RedisCacheManager ๋ฅผ Bean์œผ๋กœ ๋“ฑ๋กํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ ์šฉํ•˜๊ณ  ์‹ถ์€ ๋ฉ”์†Œ๋“œ์— @Cacheable ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด ์ ์šฉ๋œ๋‹ค.

Cache Annotation

์–ด๋…ธํ…Œ์ด์…˜

์„ค๋ช…

@Cacheable

๋ฉ”์†Œ๋“œ์— ์บ์‹œ ํŠธ๋ฆฌ๊ฑฐ ์„ค์ •

@CachePut

๋ฉ”์†Œ๋“œ ์‹คํ–‰๊ณผ ๋ฐฉํ•ด์—†์ด ์บ์‹œ ๊ฐฑ์‹ 

@CacheEvict

์บ์‹œ๋˜์–ด์žˆ๋Š” ๋ฐ์ดํ„ฐ ์ง€์šฐ๊ธฐ

@CacheConfig

์บ์‹œ ๊ด€๋ จ ์„ค์ •

@EnableCaching

์Šคํ”„๋ง ์บ์‹œํ™œ์„ฑํ™”

Annotation ์†์„ฑ

์–ด๋…ธํ…Œ์ด์…˜

์„ค๋ช…

value

์บ์‹œ์˜ ์ด๋ฆ„

key

์บ์‹œํ•  ํ‚ค๋ฅผ ์„ค์ •(๊ธฐ๋ณธ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์„ค์ •๋จ)

condition

ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ ์บ์‹œ๋ฅผ ํ• ์ง€ ์•Š์„์ง€ ๊ฒฐ์ •

cacheManager

ํ•ด๋‹น ์บ์‹œ ๋งค๋‹ˆ์ € ์„ค์ •๊ฐ€๋Šฅ

EHCache

EHCache๋ž€?

  • EHCache๋Š” ์˜คํ”ˆ ์†Œ์Šค ๊ธฐ๋ฐ˜์˜ Local Cache

  • ์†๋„๊ฐ€ ๋น ๋ฅด๋ฉฐ, ๊ฒฝ๋Ÿ‰ Cache ์ด๋‹ค.

  • Disk, Memory ์ €์žฅ์ด ๊ฐ€๋Šฅ

  • ์„œ๋ฒ„ ๊ฐ„ ๋ถ„์‚ฐ ์บ์‹œ๋ฅผ ์ง€์›

  • JSR107 JCache ํ‘œ์ค€์„ ์ง€์›ํ•œ๋‹ค. JCache์—์„œ ์ œ๊ณตํ•˜๋Š” Annotation์„ ํ†ตํ•ด ์ด๋ฏธ ์ž‘์„ฑ๋œ ์ฝ”๋“œ์— ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • JSR(Java Specification Requests) : ์‚ฌ์–‘ ๋ฐ ๊ธฐ์ˆ ์  ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ •์‹ ์ œ์•ˆ ๋ฌธ์„œ. ๊ฐœ์ธ ๋ฐ ์กฐ์ง์€ JCP (Java Community Process)์˜ ํšŒ์›์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ JSR์— ์–ธ๊ธ‰ ๋œ ์ŠคํŽ™์— ๋”ฐ๋ผ ์ฝ”๋“œ๋ฅผ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐœ๋ฐœ ๋œ ๊ธฐ์ˆ ์  ๋ณ€ํ™”๋Š” JCP ํšŒ์›๋“ค์˜ ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณ ์Šน์ธ๋œ๋‹ค.

  • JSR-107(JCACHE โ€“ Java Temporary Caching API) : ๊ฐ์ฒด ์ƒ์„ฑ, ๊ณต์œ  ์•ก์„ธ์Šค, ์Šคํ’€๋ง, ๋ฌดํšจํ™” ๋ฐ JVM ์ „๋ฐ˜์— ๊ฑธ์นœ ์ผ๊ด€์„ฑ์„ ํฌํ•จํ•˜์—ฌ Java ๊ฐ์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ ์บ์‹ฑ์—์„œ ์‚ฌ์šฉํ•  API ์— ๋Œ€ํ•œ ๊ธฐ์ค€์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น Spec ์œผ๋กœ ๊ตฌํ˜„๋œ cache๋กœ๋Š” EhCache๊ฐ€ ์œ ๋ช…ํ•˜๋ฉฐ, Hazelcast, Infinispan, Couchbase, Redis, Caffeine ๋“ฑ๋„ ํ•ด๋‹น ๊ธฐ์ค€์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ๋‹ค.

์„ค์ • ๋ฐฉ๋ฒ•

  • pom.xml

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<!-- ehcache -->
<dependency>
  <groupId>org.ehcache</groupId>
  <artifactId>ehcache</artifactId>
</dependency>        

<!-- JS107 -->
<dependency>
  <groupId>javax.cache</groupId>
  <artifactId>cache-api</artifactId>
</dependency>

EHCache๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์—๋Š” pom.xml ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„œ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ์„ ์ถ”๊ฐ€ํ•˜๋ฉด๋œ๋‹ค.

  • @EnableCaching

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

// Configuration : IoC container(application context)๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”ํƒ€์ •๋ณด
// EnableCaching์„ ํ†ตํ•ด ์Šคํ”„๋ง ์บ์‹œ๋ฅผ ํ™œ์„ฑํ™” ์‹œ์ผœ์ค€๋‹ค.
@Configuration
@EnableCaching
public class CacheConfig {

}

Spring์˜ auto-configuration์€ EHCache์˜ JSR-107์„ ์ฐพ์ง€๋งŒ ๊ธฐ๋ณธ(default)๋กœ๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ehcache.xml ์„ ์ฐพ์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ, ehcache๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„ค์ •์„ ํ•ด์ค˜์•ผํ•œ๋‹ค.

  • application.yml : ์Šคํ”„๋ง์ด ๊ตฌ๋™๋  ๋•Œ ์ž๋™์œผ๋กœ ๋กœ๋”ฉํ•˜๋Š” ํ”„๋กœํผํ‹ฐํŒŒ์ผ(application.properties๋กœ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ) ์Šคํ”„๋ง์˜ ๊ทœ์•ฝ๊ณผ ๊ฐ™์Œ.

spring:
  cache:
    jcache:
      config: classpath:ehcache.xml     # JSR-107(jcache) config ์„ค์ •
  • ehcache.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.ehcache.org/v3"
    xmlns:jsr107="http://www.ehcache.org/v3/jsr107">

     <service>
        <jsr107:defaults enable-statistics="true"/>
    </service>
    <!-- testCache ์„ค์ • expiry none์œผ๋กœ ์„ค์ •ํ•ด ์บ์‹œ ์‚ญ์ œ์ „๊นŒ์ง€ ์œ ์ง€ -->
    <cache alias="paymentMasterCache">

        <key-type copier="org.ehcache.impl.copy.SerializingCopier">java.lang.String</key-type>
        <value-type copier="org.ehcache.impl.copy.SerializingCopier">java.util.ArrayList</value-type>
        <expiry>
            <none/>
        </expiry>
        <resources>
            <heap unit="entries">100</heap>
        </resources>
    </cache>

 </config>

๊ทธ๋Ÿฌ๋ฉด ํ™˜๊ฒฝ ์„ค์ •์€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค.

import java.util.List;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.example.cacheExample.entity.PaymentMaster;

/**
 * PaymentMasterRepository
 * JPA CrudRepository ์ƒ์†
 * 
 * ๋ณ€๊ฒฝ์ด ์ž์ฃผ์•ˆ๋˜๋Š” ๋ฐ์ดํ„ฐ๋กœ ์ตœ์ดˆ ํ•œ๋ฒˆ ๊ฐ€์ ธ์˜จ ํ›„ paymentMasterCache๋กœ Ehcache์— ์ €์žฅํ•ด๋‘”๋‹ค.
 * ์ด๋•Œ ๋งŒ๋ฃŒ๊ธฐํ•œ(expiry)๋Š” ์—†์Œ(์‚ญ์ œ์‹œ๊นŒ์ง€ ์œ ์ง€)
 *  
 * ์ˆ˜์ •/์ถ”๊ฐ€/์‚ญ์ œ๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ์—๋Š” CacheEvict์œผ๋กœ paymentMasterCache๋ฅผ ์‚ญ์ œ
 * 
 * Ehcache ์„ค์ •์ •๋ณด๋Š” ehcache.xml์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
 *
 */

@Repository
public interface PaymentMasterRepository extends CrudRepository<PaymentMaster,String>{

    @Cacheable(value="paymentMasterCache", key="#root.methodName")
    List<PaymentMaster> findAll();

    @CacheEvict(value="paymentMasterCache", allEntries=true)
    <S extends PaymentMaster> S save(S entity);

    @CacheEvict(value="paymentMasterCache", allEntries=true)    
    void deleteById(String pmtCode);

    @CacheEvict(value="paymentMasterCache", allEntries=true)
    void deleteAll();
}

์—ฌ๊ธฐ์„œ @CacheEvict์˜ allEntries=true๋Š” paymentMasterCache๋กœ ๋“ฑ๋ก๋œ ๋ชจ๋“  ์บ์‹œ๋ฅผ ์‚ญ์ œํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด findAll, findAll2 ๋‘๊ฐœ์˜ ํ‚ค๋กœ paymentMasterCache๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒฝ์šฐ์— allEntries๋ฅผ ์‚ฌ์šฉํ•ด ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ ๋‘ ๊ฐœ์˜ ์บ์‹œ๊ฐ€ ๋ชจ๋‘ ์‚ญ์ œ๋œ๋‹ค.

์ฐธ๊ณ 

Last updated

Was this helpful?