Redis

jiholeeยท2022๋…„ 10์›” 5์ผ
0

๐ŸŒˆ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 
๋‚˜์ค‘์— ์š”์ฒญ์˜ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฏธ๋ฆฌ ์ €์žฅํ•ด๋‘์—ˆ๋‹ค๊ฐ€ ๋น ๋ฅด๊ฒŒ ์„œ๋น„์Šค๋ฅผ ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์บ์‹œ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋””์Šคํฌ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ณด๋‹ค ๋น ๋ฅด๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ… ์บ์‹œ ๋Œ€์ƒ์ด ๋˜๋Š” ๋ฐ์ดํ„ฐ

  • ๋‹จ์ˆœํ•œ ์ •๋ณด
  • ๋ฐ˜๋ณต์ ์œผ๋กœ ๋™์ผํ•˜๊ฒŒ ์ œ๊ณต๋˜๋Š” ์ •๋ณด
  • ์ •๋ณด์˜ ๋ณ€๊ฒฝ์ฃผ๊ธฐ๊ฐ€ ๋นˆ๋ฒˆํ•˜์ง€ ์•Š๊ณ , ๋‹จ์œ„์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ์ •๋ณด
  • ์ •๋ณด์˜ ์ตœ์‹ ํ™”๊ฐ€ ๋ฐ˜๋“œ์‹œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ด๋ค„์ง€์ง€ ์•Š์•„๋„ ์„œ๋น„์Šค ํ’ˆ์งˆ์— ์˜ํ–ฅ์„ ๊ฑฐ์˜ ์ฃผ์ง€ ์•Š๋Š” ์ •๋ณด

๋ฐฐ์น˜์ „๋žต

๋Œ€ํ‘œ์ ์œผ๋กœ Look aside ํŒจํ„ด๊ณผ Write Back ํŒจํ„ด์ด ๋งŽ์ด ์“ฐ์ธ๋‹ค.

Look aside Cache

๋ฐ˜๋ณต์ ์ธ ์ฝ๊ธฐ์— ์ ํ•ฉ
๋ ˆ๋””์Šค์— ์žฅ์• ๊ฐ€ ์ƒ๊ธฐ๋”๋ผ๋„ DB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ.
Cache์™€ DB์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ.
์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ๋Š” ํŒจํ„ด

Write Back

๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹œ์— ๋จผ์ € ์“ฐ๊ณ  ํŠน์ • ์‹œ๊ฐ„ ๋งˆ๋‹ค DB์— ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹
๋‹จ์ : ์บ์‹œ ์žฅ์•  ์‹œ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ๋ผ์งˆ ๊ฐ€๋Šฅ์„ฑ
์œ ์šฉํ•œ ๊ฒฝ์šฐ: ๋กœ๊ทธ ์ €์žฅ ์‹œ ์บ์‹œ์— ๋จผ์ € ๋ฐ€์–ด๋„ฃ๊ณ  ํŠน์ • ์‹œ๊ฐ„๋งˆ๋‹ค DB์— ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ

Write Through

DB์— ์ž‘์„ฑํ•  ๋•Œ๋งˆ๋‹ค ์บ์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ์‹
์บ์‹œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ญ์ƒ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๊นŒ์ง€ ์บ์‹œ์— ์ €์žฅ๋˜์–ด ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„์™€ write ์ž‘์—… ๋ถ€ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด TTL์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๋Š”๊ฒƒ์ด ์ข‹๋‹ค.

Read Through

Look aside ๋ฐฉ์‹๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ DB์—์„œ ์ง์ ‘ Cache Store๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.

Collection

๋ ˆ๋””์Šค๋Š” ๋‹ค์–‘ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ง€์›ํ•œ๋‹ค. ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ Atomic ํ•˜๊ธฐ ๋Œ€๋ฌธ์— Race Condition์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.(๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์€ ์žˆ์Œ.)

๋งŽ์ด ์“ฐ์ด๋Š” ๊ณณ

  • ์ธ์ฆ ํ† ํฐ๋“ฑ์„ ์ €์žฅ(Strings ๋˜๋Š” Hash)
  • Ranking ๋ณด๋“œ(Sorted Set)
  • ์œ ์ € API Limit

Strings

๐Ÿ“Œ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ํ˜•ํƒœ๋กœ, key - value๋กœ ์ €์žฅํ•˜๋Š” ํ˜•ํƒœ์ด๋‹ค.
์‚ฌ์šฉ๋ฒ•

set <key> <value>
get <key>

mset <key1> <value1> <key2> <value2> ...
mget <key1> <key2> ... <keyN>

List

์ฒ˜์Œ๊ณผ ๋์— ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๊ณ  ๋นผ๋Š” ์†๋„๊ฐ€ ๋น ๋ฅด์ง€๋งŒ ์ค‘๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๊ฒŒ ์ข‹๋‹ค.

Lpush <key> <A>
Rpush <key> <B>
Lpush <key> <C>
Rpush <key> <D, A>

-> Key: (C, A ,B, D, A)

LPOP <key>
RPOP <key>

Set

๐Ÿ“Œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€ ์ฒดํฌํ•˜๋Š” ์šฉ๋„์ด๋‹ค. (ํŠน์ • ์œ ์ €๋ฅผ follow ํ•˜๋Š” ๋ชฉ๋ก์„ ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ ์œ ๋‹ˆํฌํ•œ value๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๊ธฐ ์šฉ์ด)

SADD <key> <value> # value๊ฐ€ ์ด๋ฏธ key์— ์žˆ์œผ๋ฉด ์ถ”๊ฐ€x
SMEMBERS <key>  # ๋ชจ๋“  value๋ฅผ ๋Œ๋ ค์คŒ
SISMEMBER <key> <value> # value๊ฐ€ ์กด์žฌํ•˜๋ฉด 1, ์•„๋‹ˆ๋ฉด 0

Sorted Sets

๐Ÿ“Œ ๋žญํ‚น์— ๋”ฐ๋ผ์„œ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ๊ธธ ๋ฐ”๋ž„ ๋•Œ
์œ ์ € ๋žญํ‚น ๋ณด๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.

ZADD <key> <score> <value>

# ํ•ด๋‹น index ๋ฒ”์œ„๊ฐ’ ๋ชจ๋‘ ๋Œ๋ ค์คŒ
# Zrange key 0 -1  ๋ชจ๋“  ๋ฒ”์œ„
ZRANGE <key> <startindex> <endindex>

Zreverange <key> <startindex> <endindex>

ZrangeByscore

โ—๏ธscore๋Š” double ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์ด ์ •ํ™•ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

Hash

key ๋ฐ‘์— sub key๊ฐ€ ์กด์žฌ

Hget <key> <subkey>
Hgetall <key>
Hmset <key> <subkey1> <value1> <subkey2> <value2>

์ฃผ์˜ ์‚ฌํ•ญ

  • ํ•˜๋‚˜์˜ ์ปฌ๋ Œ์…˜์— ๋„ˆ๋ฌด ๋งŽ์€ ์•„์ดํ…œ์„ ๋‹ด์œผ๋ฉด ์ข‹์ง€ ์•Š๋‹ค. -> 10000๊ฐœ ์ดํ•˜ ๋ช‡์ฒœ๊ฐœ ์ˆ˜์ค€์œผ๋กœ ์œ ์ง€ํ•˜๋Š”๊ฒŒ ์ข‹์Œ

  • Expire๋Š” Collection์˜ item ๊ฐœ๋ณ„๋กœ ๊ฑธ๋ฆฌ์ง€ ์•Š๊ณ  ์ „์ฒด์— ๋Œ€ํ•ด์„œ ๊ฑธ๋ฆผ
    ์ฆ‰ ํ•ด๋‹น 10000๊ฐœ์˜ ์•„์ดํ…œ์„ ๊ฐ€์ง„ Collection์— expire๊ฐ€ ๊ฑธ๋ ค์žˆ๋‹ค๋ฉด ๊ทธ ์‹œ๊ฐ„ ํ›„์— 10000๊ฐœ์˜ ์•„์ดํ…œ์ด ๋ชจ๋‘ ์‚ญ์ œ.

  • O(N) ๊ด€๋ จ ๋ช…๋ น์–ด๋Š” ์ฃผ์˜ํ•˜๊ธฐ

  • ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์ž˜ํ•˜์ž
    -> physical memory์ด์ƒ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ œ ๋ฐœ์ƒ, swap์ด ํ•œ๋ฒˆ์ด๋ผ๋„ ๋ฐœ์ƒํ•˜๋ฉด ๊ณ„์† swap์ด ์ผ์–ด๋‚˜์„œ ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ page ์ ‘๊ทผ์‹œ ๋งˆ๋‹ค ๋Šฆ์–ด์ง„๋‹ค. Maxmemory๋ฅผ ์„ค์ •ํ•˜๋”๋ผ๋„ ๋” ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.

    ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

  • ๋ฉ”๋ชจ๋ฆฌ ํŒŒํŽธํ™”๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.

  • ํฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” instance ํ•˜๋‚˜๋ณด๋‹ค๋Š” ์ ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” instance ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ์šด์˜์—๋Š” ์•ˆ์ „ํ•˜๋‹ค.

Spring์˜ Caching ๊ธฐ๋Šฅ

SpringBoot๊ธฐ๋ฐ˜ Redis Cache ์‚ฌ์šฉ๋ฒ•

  • ์Šคํ”„๋ง ๋ถ€ํŠธ ์˜์กด์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€
  • Redis ์ปค๋„ฅ์…˜ ์ •๋ณด ์„ค์ •
  • SpringBoot ๋ฉ”์ธ ํด๋ž˜์Šค์— ์บ์‹œ ์‚ฌ์šฉ ์•Œ๋ ค์ฃผ๊ธฐ
  • ์‚ฌ์šฉํ•œ method์— ์–ด๋…ธํ…Œ์ด์…˜ ๋‹ฌ์•„์ฃผ๊ธฐ

Spring Cache๋Š” AOP๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์บ์‹œ ๊ธฐ๋Šฅ์„ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

  • ์บ์‹œ ๋“ฑ๋ก / ์กฐํšŒ: @Cachable
    ๋ณดํ†ต ๋ฉ”์†Œ๋“œ ๋‹จ์œ„๋กœ ์ ์šฉํ•œ๋‹ค. ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ์—๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด ๋ฉ”์„œ๋“œ ๋กœ์ง์„ ์‹คํ–‰ํ•œ ํ›„ ์บ์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ์บ์‹ฑ ใ…”๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด ์บ์‹œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ์บ์‹œ ์ €์žฅ: @CachePut
    ๋ฉ”์„œ๋“œ์˜ ๋กœ์ง์„ ์‹คํ–‰ํ•˜๊ณ  ์‹คํ–‰๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.

  • ์บ์‹œ ์‚ญ์ œ: @CacheEvict
    ์บ์‹œ ์ด๋ฆ„์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰ ๋  ๋•Œ ์บ์‹œ์˜ ๋‚ด์šฉ์ด ์ œ๊ฑฐ๋œ๋‹ค. ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ allEntries๋Š” ์ „์ฒด ์บ์‹œ๋ฅผ ์ง€์šธ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค.


    ์šฐ์•„ํ•œ ๋ ˆ๋””์Šค ์„ธ๋ฏธ๋‚˜ ์˜์ƒ

    Redis๋ž€ ๋ฌด์—‡์ผ๊นŒ?

    ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ๋ ˆ๋””์Šค ํŠœํ† ๋ฆฌ์–ผ

0๊ฐœ์˜ ๋Œ“๊ธ€