๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd๐ŸŒฑ/DB & SQL

Redis์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…, ๋ช…๋ น์–ด์™€ ํ™œ์šฉ ์‚ฌ๋ก€

by ์•ˆ์ฃผํ˜• 2023. 9. 5.

๊ฐ„๋‹จ ์š”์•ฝ

๋ฐ์ดํ„ฐ ํƒ€์ž… ๋ช…๋ น์–ด ์„ค๋ช… ์˜ˆ์ œ
Strings   SET   ๊ฐ’ ์ €์žฅ  `$ SET key value`
  GET   ๊ฐ’ ์กฐํšŒ  `$ GET key`
Lists   LPUSH   ์™ผ์ชฝ๋ถ€ํ„ฐ ๊ฐ’ ์ถ”๊ฐ€  `$ LPUSH mylist value`
  LPOP   ์™ผ์ชฝ์—์„œ ๊ฐ’ ์ œ๊ฑฐ  `$ LPOP mylist`
  LINDEX   ํŠน์ • ์œ„์น˜์˜ ๊ฐ’ ์กฐํšŒ  `$ LINDEX mylist 0`
Sets   SADD   ๊ฐ’ ์ถ”๊ฐ€  `$ SADD myset value`
  SMEMBERS   ๋ชจ๋“  ๋ฉค๋ฒ„ ์กฐํšŒ  `$ SMEMBERS myset`
Sorted Sets(ZSets)   ZADD   ๊ฐ’ ๋ฐ ์ ์ˆ˜ ์ถ”๊ฐ€  `$ ZADD myzset score member`
  ZRANK   ํŠน์ • ๋ฉค๋ฒ„์˜ ์ˆœ์œ„ ์กฐํšŒ  `$ ZRANK myzset member`
  ZRANGE   ์ ์ˆ˜ ๋ฒ”์œ„๋กœ ๋ฉค๋ฒ„ ์กฐํšŒ  `$ ZRANGE myzset start stop`
Hashes   HSET   ํ•„๋“œ์™€ ๊ฐ’์„ ์„ค์ •  `$ HSET myhash field value`
  HGET   ํ•„๋“œ์˜ ๊ฐ’์„ ์กฐํšŒ  `$ HGET myhash field`
  HGETALL   ํ•ด์‹œ์˜ ๋ชจ๋“  ํ•„๋“œ์™€ ๊ฐ’ ์กฐํšŒ  `$ HGETALL myhash`
Streams   XADD   ์ŠคํŠธ๋ฆผ์— ๋ฉ”์‹œ์ง€ ์ถ”๊ฐ€  `$ XADD mystream * field value`
  XREAD   ์ŠคํŠธ๋ฆผ์—์„œ ๋ฉ”์‹œ์ง€ ์ฝ๊ธฐ  `$ XREAD COUNT count STREAMS mystream start`
Bits(Bitmaps)   SETBIT   ๋น„ํŠธ ์„ค์ •  `$ SETBIT key offset value`
  GETBIT   ํŠน์ • ๋น„ํŠธ ์กฐํšŒ  `$ GETBIT key offset`
HyperLogLog(PF)   PFADD   ์š”์†Œ ์ถ”๊ฐ€  `$ PFADD myhyperloglog value1 value2`
  PFCOUNT   ์ค‘๋ณต ์—†๋Š” ์š”์†Œ์˜ ์ˆ˜ ์กฐํšŒ  `$ PFCOUNT myhyperloglog`
GEO(geospatial)   GEOADD   ์œ„์น˜ ์ •๋ณด ์ถ”๊ฐ€  `$ GEOADD mygeo long lat member`
  GEOPOS   ๋ฉค๋ฒ„์˜ ์œ„์น˜ ์ •๋ณด ์กฐํšŒ  `$ GEOPOS mygeo member`
  GEODIST   ๋‘ ๋ฉค๋ฒ„ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ ์กฐํšŒ  `$ GEODIST mygeo member1 member2`
BloomFilter   BF.ADD   ์š”์†Œ ์ถ”๊ฐ€  `$ BF.ADD myfilter value`
  BF.MADD   ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ํ•œ ๋ฒˆ์— ์ถ”๊ฐ€  `$ BF.MADD myfilter value1 value2`

 

 

 

Strings

Redis์˜ Strings ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ๋ฐ”์ดํŠธ ๋ฐฐ์—ด๋กœ ๊ตฌ์„ฑ๋˜์–ด, ๋‹จ์ˆœํ•œ ๋ฌธ์ž์—ด๋ถ€ํ„ฐ ์ด๋ฏธ์ง€, ์ง๋ ฌํ™”๋œ ๊ฐ์ฒด, ์ด์ง„ ๋ฐ์ดํ„ฐ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Strings ํƒ€์ž…์—์„œ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ ๋ฌธ์ž์—ด์˜ ํฌ๊ธฐ๋Š” ์ตœ๋Œ€ 512MB์ž…๋‹ˆ๋‹ค.

SET

์ง€์ •๋œ ํ‚ค์— ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

$ SET key value

$ SET contury korea

GET

์ง€์ •๋œ ํ‚ค์˜ ๊ฐ’์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

$ GET key

$ GET contury

MSET

์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ‚ค์™€ ๊ฐ’์„ ๋™์‹œ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

$ MSET key1 value1 key2 value2...

$ MSET contury korea city seoul

MGET

์—ฌ๋Ÿฌ ํ‚ค์˜ ๊ฐ’์„ ํ•œ ๋ฒˆ์— ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

$ MGET key1 key...

$ MGET contury city

INCR

ํ‚ค์˜ ๊ฐ’์ด ์ •์ˆ˜์ด๋ฉด, ๊ฐ’์„ 1 ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.

$ INCR key

$ INCR length

DECR

ํ‚ค์˜ ๊ฐ’์ด ์ •์ˆ˜์ด๋ฉด, ๊ฐ’์„ 1 ๊ฐ์†Œ์‹œํ‚ต๋‹ˆ๋‹ค.

$ DECR key

$ DECR length

APPEND

์ง€์ •๋œ ํ‚ค์˜ ํ˜„์žฌ ๊ฐ’ ๋’ค์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

$ APPEND key value

$ APPEND job programmer

 

ํ™œ์šฉ ์‚ฌ๋ก€

1. Session Management(์„ธ์…˜ ๊ด€๋ฆฌ)

Redis๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜ ์ •๋ณด๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Redis์˜ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ์„ค์ • ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ์„ธ์…˜์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ๊ด€๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

$ SET user:dkswnkk:session "SessionID123" EX 3600  # 1์‹œ๊ฐ„ ํ›„์— ๋งŒ๋ฃŒ๋˜๋Š” ์„ธ์…˜ ์ •๋ณด ์ €์žฅ

$ GET user:dkswnkk:session  # ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜ ์ •๋ณด ์กฐํšŒ

Redis์—์„œ๋Š” ':' ๊ตฌ๋ถ„์ž๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ‚ค์˜ ๊ณ„์ธต์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฅผ ํ†ตํ•ด ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ๊ตฌ์กฐ์ ์œผ๋กœ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. Contures(๊ฐ„๋‹จํ•œ ์นด์šดํ„ฐ ๊ตฌํ˜„)

์›น ํŽ˜์ด์ง€์˜ ์กฐํšŒ์ˆ˜๋‚˜ ์–ด๋–ค ์ž์›์˜ ์‚ฌ์šฉ ํšŸ์ˆ˜์™€ ๊ฐ™์€ ์ •๋ณด๋ฅผ ์นด์šดํŠธํ•  ๋•Œ, Redis์˜ String ํƒ€์ž…๊ณผ INCR, DECR ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งค์šฐ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ SET page_views 0  # ํŽ˜์ด์ง€ ์กฐํšŒ์ˆ˜ ์ดˆ๊ธฐํ™”

$ INCR page_views  # ํŽ˜์ด์ง€ ์กฐํšŒ ์‹œ๋งˆ๋‹ค ์ฆ๊ฐ€

$ INCR page_views

๊ฐ„๋‹จํ•œ ์นด์šดํ„ฐ๋Š” Redis์˜ ๋†’์€ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ๋น ๋ฅด๊ฒŒ ์ฆ๊ฐ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. Caching(์บ์‹ฑ)

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋‚˜ ๋ณต์žกํ•œ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์บ์‹œ๋กœ ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‘๋‹ต ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ๋‹จ์ถ•์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Redis๋Š” In-meory DB๋กœ์จ ๋น ๋ฅธ ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ์„ฑ๋Šฅ์„ ์ž๋ž‘ํ•˜๋ฏ€๋กœ ์ด๋Ÿฌํ•œ ์บ์‹ฑ ์šฉ๋„๋กœ ๋งค์šฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

$ SET product:123:details "{ 'name': 'Laptop', 'price': '1000$' }" EX 600  # ์ƒํ’ˆ ์ •๋ณด๋ฅผ 10๋ถ„ ๋™์•ˆ ์บ์‹œ๋กœ ์ €์žฅ

$ GET product:123:details  # ์บ์‹œ๋œ ์ƒํ’ˆ ์ •๋ณด ๋น ๋ฅด๊ฒŒ ์กฐํšŒ

์บ์‹œ ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ ์–ธ์ œ๋“ ์ง€ ์žฌ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Redis์˜ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ์„ค์ • ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ์บ์‹œ ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ ๊ธฐ๊ฐ„์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค

 

 

Lists

Redis์˜ Lists ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Linked List)๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์œผ๋ฉฐ, ๋ฆฌ์ŠคํŠธ์˜ ์•ž, ๋’ค, ์–‘ ๋์—์„œ ์•„์ดํ…œ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ๋•Œ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์ด์šฉ๋ฉ๋‹ˆ๋‹ค.

LPUSH

๋ฆฌ์ŠคํŠธ์˜ ์•ž์ชฝ(์™ผ์ชฝ)์— ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ฐ’๋“ค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

$ LPUSH fruits apple

$ LPUSH fruits banana orange

RPUSH

๋ฆฌ์ŠคํŠธ์˜ ๋’ค์ชฝ(์˜ค๋ฅธ์ชฝ)์— ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ฐ’๋“ค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

$ RPUSH fruits kiwi

$ RPUSH fruits grape melon

LPOP

๋ฆฌ์ŠคํŠธ์˜ ์•ž์ชฝ(์™ผ์ชฝ) ๊ฐ’์„ ์ œ๊ฑฐํ•˜๊ณ  ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ LPOP fruits

RPOP

๋ฆฌ์ŠคํŠธ์˜ ๋’ค์ชฝ(์˜ค๋ฅธ์ชฝ) ๊ฐ’์„ ์ œ๊ฑฐํ•˜๊ณ  ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ RPOP fruits

LRANGE

๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ๋ฒ”์œ„์˜ ์š”์†Œ๋“ค์„ ์กฐํšŒํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. LRANGE key start stop ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ, start์™€ stop์€ ์ธ๋ฑ์Šค๋กœ๋ถ€์„œ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์Œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๋ฆฌ์ŠคํŠธ์˜ ๋์—์„œ๋ถ€ํ„ฐ ์—ญ์ˆœ์œผ๋กœ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.

ex) ์ฒซ ๋ฒˆ์งธ๋ถ€ํ„ฐ ์„ธ ๋ฒˆ์งธ ์š”์†Œ๊นŒ์ง€ ์กฐํšŒ

$ LPUSH mylist "three" "two" "one"
$ LRANGE mylist 0 2

> "one", "two", "three"

ex) ๋ฆฌ์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰ ์„ธ ์š”์†Œ ์กฐํšŒ

$ LRANGE mylist -3 -1

> "one", "two", "three"

ex) ์ „์ฒด ๋ฆฌ์ŠคํŠธ ์กฐํšŒ

$ LRANGE mylist 0 -1

> "one", "two", "three"

LINDEX

๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ์œ„์น˜์˜ ์š”์†Œ๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. LINDEX key index ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ex) ์ฒซ ๋ฒˆ์งธ ์š”์†Œ ์กฐํšŒ

$ LPUSH mylist "three" "two" "one"
$ LINDEX mylist 0

> "one"

ex) ์„ธ ๋ฒˆ์งธ ์š”์†Œ ์กฐํšŒ

$ LPUSH mylist "three" "two" "one"
$ LINDEX mylist 2

> "three"

ex) ๋งˆ์ง€๋ง‰ ์š”์†Œ ์กฐํšŒ

$ LPUSH mylist "three" "two" "one"
$ LINDEX mylist -1

> "three"

 

ํ™œ์šฉ ์‚ฌ๋ก€

1. Task Queue(์ž‘์—… ๋Œ€๊ธฐ์—ด)

Redis์˜ List ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ FIFO(FIrst-In-FIrst-Out)์˜ ํŠน์„ฑ์„ ๊ฐ€์ง€๋ฏ€๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…๋“ค์„ ๋Œ€๊ธฐ์—ด์— ๋„ฃ์–ด๋‘๊ณ , ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋‚˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฐจ๋ก€๋Œ€๋กœ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ LPUSH taskQueue "send email"  # ์ด๋ฉ”์ผ ๋ณด๋‚ด๊ธฐ ์ž‘์—…์„ ๋Œ€๊ธฐ์—ด์˜ ๋งจ ์•ž์— ์ถ”๊ฐ€
$ LPUSH taskQueue "resize image"  # ์ด๋ฏธ์ง€ ๋ฆฌ์‚ฌ์ด์ง• ์ž‘์—…์„ ๋Œ€๊ธฐ์—ด์˜ ๋งจ ์•ž์— ์ถ”๊ฐ€

$ RPOP taskQueue  # ๋Œ€๊ธฐ์—ด์—์„œ ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ์ž‘์—…(๊ฐ€์žฅ ๋’ค์ชฝ์— ์žˆ๋Š” ์ž‘์—…)์„ ๊ฐ€์ ธ์™€ ์ฒ˜๋ฆฌ

2. Activity Stream(ํ™œ๋™ ๊ธฐ๋ก)

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

$ LPUSH user:1234:activity "logged in"  # ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ๋กœ๊ทธ ๊ธฐ๋ก
$ LPUSH user:1234:activity "viewed profile"  # ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์กฐํšŒ ๋กœ๊ทธ ๊ธฐ๋ก
$ LPUSH user:1234:timeline "Posted a new photo"  # ์‚ฌ์ง„ ์—…๋กœ๋“œ ๋กœ๊ทธ ๊ธฐ๋ก
$ LPUSH user:1234:timeline "Updated profile"  # ํ”„๋กœํ•„ ์—…๋ฐ์ดํŠธ ๋กœ๊ทธ ๊ธฐ๋ก
...
$ LRANGE user:1234:timeline 0 9  # ์‚ฌ์šฉ์ž์˜ ์ตœ๊ทผ 10๊ฐœ ๋กœ๊ทธ ์กฐํšŒ

3. Pagination(ํŽ˜์ด์ง€๋„ค์ด์…˜)

List์˜ ์ผ๋ถ€๋ถ„์„ LRANGE๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ ธ์˜ค๋Š” ํŠน์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์›น ํŽ˜์ด์ง€๋‚˜ ์•ฑ์—์„œ ๋ฐ์ดํ„ฐ์˜ ์ผ๋ถ€๋ถ„๋งŒ์„ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ LPUSH articles "article3"  # ์„ธ ๋ฒˆ์งธ ๊ธฐ์‚ฌ๋ฅผ ๋งจ ์•ž์— ์ถ”๊ฐ€
$ LPUSH articles "article2"  # ๋‘ ๋ฒˆ์งธ ๊ธฐ์‚ฌ๋ฅผ ๋งจ ์•ž์— ์ถ”๊ฐ€
$ LPUSH articles "article1"  # ์ฒซ ๋ฒˆ์งธ ๊ธฐ์‚ฌ๋ฅผ ๋งจ ์•ž์— ์ถ”๊ฐ€

$ LRANGE articles 0 2  # ์ฒ˜์Œ๋ถ€ํ„ฐ ์„ธ ๋ฒˆ์งธ ๊ธฐ์‚ฌ๊นŒ์ง€ ์กฐํšŒ

4. Real-time Chat History(์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ๊ธฐ๋ก)

์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์—์„œ๋Š” ์‚ฌ์šฉ์ž๋“ค ์‚ฌ์ด์˜ ๋Œ€ํ™” ๋‚ด์šฉ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ €์žฅํ•˜๊ณ , ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๊ฐ€ ์ฑ„ํŒ…๋ฐฉ์— ๋“ค์–ด์™”์„ ๋•Œ ์ตœ๊ทผ ๋Œ€ํ™” ๋‚ด์šฉ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

Sets

Redis์˜ Sets ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์ค‘๋ณต์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ž์—ด ์ง‘ํ•ฉ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. Set์€ ์ถ”๊ฐ€, ์‚ญ์ œ ๋ฐ ์กด์žฌํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ์—ฐ์‚ฐ์„ O(1)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

SADD

Set์— ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ฐ’๋“ค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด๋ฏธ Set์— ์กด์žฌํ•˜๋Š” ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ๋‹ค๋ฉด ํ•ด๋‹น ์—ฐ์‚ฐ์€ ๋ฌด์‹œ๋˜๋ฉฐ, ์„ฑ๊ณตํ•œ๋‹ค๋ฉด ์ถ”๊ฐ€๋œ ๊ฐ’์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ SADD myset "value1"
> (integer) 1

$ SADD myset "value2" "value3"
> (integer) 2

$ SADD myset "value3"
> (integer) 0

SMEMBERS

Set์— ํฌํ•จ๋œ ๋ชจ๋“  ๊ฐ’์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

$ SMEMBERS myset
> "value1", "value2", "value3"

SREM

Set์—์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ฐ’์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๊ฐ’์€ ์ œ๊ฑฐ๋œ ๊ฐ’์˜ ์ˆ˜์ž…๋‹ˆ๋‹ค.

$ SREM myset "value1"
> (integer) 1

$ SREM myset "value2" "value3"
> (integer) 2

SISMEMBER

ํŠน์ • ๊ฐ’์ด Set์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์žˆ๋‹ค๋ฉด 1, ์—†๋‹ค๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ SISMEMBER myset "value1"
> (integer) 1

$ SISMEMBER myset "value4"
> (integer) 0

SCARD

Set์˜ ๊ฐ’ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ SCARD myset
> (integer) 2

SDIFF

๋‘ Set ๊ฐ„์˜ ์ฐจ์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ SADD set1 "a" "b" "c"
> (integer) 3

$ SADD set2 "b" "c" "d"
> (integer) 3

$ SDIFF set1 set2
> "a"

SINTER

๋‘ Set ๊ฐ„์˜ ๊ต์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ SINTER set1 set2
> "b", "c"

SUNION

๋‘ Set ๊ฐ„์˜ ํ•ฉ์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ SUNION set1 set2
> "a", "b", "c", "d"

 

ํ™œ์šฉ ์‚ฌ๋ก€

1. Unique Item Collection(๊ณ ์œ ํ•œ ํ•ญ๋ชฉ์˜ ์ง‘ํ•ฉ)

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

$ SADD article:tags "news" "tech" "redis"
> (integer) 3

$ SMEMBERS article:tags
> "news", "tech", "redis"

2. User Tracking(์‚ฌ์šฉ์ž ์ถ”์ )

์›น ์‚ฌ์ดํŠธ์— ๋ฐฉ๋ฌธํ•œ ์‚ฌ์šฉ์ž์˜ IP ์ฃผ์†Œ๋‚˜ ID ๋“ฑ์„ Set์— ์ €์žฅํ•˜์—ฌ, ํŠน์ • ๊ธฐ๊ฐ„ ๋™์•ˆ์˜ ๊ณ ์œ ํ•œ ๋ฐฉ๋ฌธ์ž ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ SADD visitors:today "192.168.0.1" "192.168.0.2"
> (integer) 2

$ SCARD visitors:today
> (integer) 2

 

 

Sorted Sets(ZSets)

Redis์˜ ZSets ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ Set๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์ค‘๋ณต์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉค๋ฒ„๋ฅผ ์ €์žฅํ•˜์ง€๋งŒ, ๊ฐ ๋ฉค๋ฒ„๋Š” ์—ฐ๊ด€๋œ ์ ์ˆ˜(score)๋ฅผ ๊ฐ€์ง€๋ฉฐ ์ด ์ ์ˆ˜์— ๋”ฐ๋ผ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฉค๋ฒ„ ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ Set์˜ ๋ชจ๋“  ์žฅ์ ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ZADD

ZSet์— ๋ฉค๋ฒ„์™€ ํ•ด๋‹น ๋ฉค๋ฒ„์˜ ์ ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

$ ZADD myzset 1 "one"
> (integer) 1

$ ZADD myzset 2 "two" 3 "three"
> (integer) 2

ZRANGE

ZSet์—์„œ ์ง€์ •๋œ ๋ฒ”์œ„์˜ ๋ฉค๋ฒ„๋ฅผ ์ ์ˆ˜์— ๋”ฐ๋ผ ์ •๋ ฌํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. WITHSCORES ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด, ๋ฐ˜ํ™˜๋œ ๋ฉค๋ฒ„ ์˜†์— ํ•ด๋‹น ๋ฉค๋ฒ„์˜ ์ ์ˆ˜๋„ ํ•จ๊ป˜ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

$ ZRANGE myzset 0 -1
> "one", "two", "three"

$ ZRANGE myzset 0 -1 WITHSCORES
> "one", "1", "two", "2", "three", "3"

ZREM

ZSet์—์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฉค๋ฒ„๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

$ ZREM myzset "one"
> (integer) 1

ZCARD

ZSet์— ์žˆ๋Š” ๋ฉค๋ฒ„์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ ZCARD myzset
> (integer) 2

ZSCORE

ํŠน์ • ๋ฉค๋ฒ„์˜ ์ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ ZSCORE myzset "three"
> "3"

ZRANK

ํŠน์ • ๋ฉค๋ฒ„๊ฐ€ ZSet ๋‚ด์—์„œ ๊ฐ€์ง„ ์ˆœ์œ„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ˆœ์œ„๋Š” 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

$ ZRANK myzset "two"
> (integer) 1

ZREVRANK

์ ์ˆ˜๊ฐ€ ๋†’์€ ์ˆœ์œผ๋กœ ์ •๋ ฌํ–ˆ์„ ๋•Œ์˜ ํŠน์ • ๋ฉค๋ฒ„์˜ ์ˆœ์œ„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ ZREVRANK myzset "two"
> (integer) 0

 

ํ™œ์šฉ ์‚ฌ๋ก€

1. Leaderboards(๋ฆฌ๋”๋ณด๋“œ)

์‚ฌ์šฉ์ž์˜ ์ ์ˆ˜๋‚˜ ์„ฑ๊ณผ๋ฅผ ๊ธฐ๋กํ•˜๊ณ , ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋“ค๊ณผ์˜ ๋žญํ‚น์„ ๋น„๊ตํ•  ๋•Œ ZSets๋Š” ์•„์ฃผ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์ ์ˆ˜๋Š” Score๋กœ ์ €์žฅ๋˜๋ฉฐ, ZSets์˜ ์ •๋ ฌ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ๋žญํ‚น์„ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ ZADD leaderboard 1500 "user123"  # user123์˜ ์ ์ˆ˜๋ฅผ 1500์œผ๋กœ ์ €์žฅ
$ ZADD leaderboard 1700 "user456"  # user456์˜ ์ ์ˆ˜๋ฅผ 1700์œผ๋กœ ์ €์žฅ

$ ZRANGE leaderboard 0 -1 WITHSCORES  # ๋ชจ๋“  ์‚ฌ์šฉ์ž์˜ ๋žญํ‚น๊ณผ ์ ์ˆ˜๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ํ™•์ธ

2. ์‹œ๊ฐ„์— ๋”ฐ๋ฅธ ๋กœ๊ทธ ๊ด€๋ฆฌ

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

$ ZADD eventLog 1630755600 "User logged in"  # ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ์ด๋ฒคํŠธ ๊ธฐ๋ก
$ ZADD eventLog 1630758600 "User uploaded a file"  # ํŒŒ์ผ ์—…๋กœ๋“œ ์ด๋ฒคํŠธ ๊ธฐ๋ก

$ ZRANGE eventLog 0 -1 WITHSCORES  # ๋ชจ๋“  ๋กœ๊ทธ์™€ ๊ทธ ๋ฐœ์ƒ ์‹œ๊ฐ„์„ ์กฐํšŒ

3. ์ ‘์†์ž ์ˆœ์„œ ๋ฐ ์ ‘์† ์‹œ๊ฐ„ ๊ธฐ๋ก

์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ‘์†ํ•  ๋•Œ๋งˆ๋‹ค, ์ ‘์†ํ•œ ์‹œ๊ฐ„์„ ์ ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ZSets์— ์ €์žฅํ•˜๋ฉด, ์ตœ๊ทผ ์ ‘์†์ž๋‚˜ ๊ฐ€์žฅ ์˜ค๋žซ๋™์•ˆ ์ ‘์†ํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž ๋“ฑ์˜ ์ •๋ณด๋ฅผ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ ZADD lastAccess 1630755600 "user123"  # user123์˜ ๋งˆ์ง€๋ง‰ ์ ‘์† ์‹œ๊ฐ„ ๊ธฐ๋ก
$ ZADD lastAccess 1630758600 "user456"  # user456์˜ ๋งˆ์ง€๋ง‰ ์ ‘์† ์‹œ๊ฐ„ ๊ธฐ๋ก

$ ZREVRANGE lastAccess 0 4 WITHSCORES  # ๋งˆ์ง€๋ง‰์œผ๋กœ ์ ‘์†ํ•œ 5๋ช…์˜ ์‚ฌ์šฉ์ž์™€ ๊ทธ ์ ‘์† ์‹œ๊ฐ„์„ ์กฐํšŒ

 

 

Hashes

Redis์˜ Hash ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ํ•„๋“œ์™€ ๊ฐ’์„ ๊ฐ€์ง„ ๋งต์œผ๋กœ, ๊ฐ ํ•„๋“œ๋Š” ๋ฌธ์ž์—ด ๊ฐ’์„ ๊นŒ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Hash๋Š” ๊ฐ์ฒด์™€ ๋น„์Šทํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์—ฌ๋Ÿฌ ํ•„๋“œ์™€ ๊ฐ’์„ ๋™์‹œ์— ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๊ฐ ํ•„๋“œ์˜ ํฌ๊ธฐ๋Š” ์ž‘์€ ๋ฐ์ดํ„ฐ๋ถ€ํ„ฐ ํฐ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Hash๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๊ฐ„ ํฌ๊ธฐ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

HSET

ํ•˜๋‚˜ ์ด์ƒ์˜ key-value ์Œ์„ Hash์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ํ•ด๋‹น ํ•„๋“œ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๋ฉด, ๊ทธ ๊ฐ’์€ ๋ฎ์–ด์”Œ์›Œ์ง‘๋‹ˆ๋‹ค.

$ HSET user:1234 name "Juhyeong" age 26

HGET

Hash์—์„œ ์ €์žฅํ•œ ํ•„๋“œ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

$ HGET user:1234 name
> "Juhyeong"

HGETALL

Hash์˜ ๋ชจ๋“  ํ•„๋“œ์™€ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

$ HGETALL user:1234
> "name", "Juhyeong", "age", "26"

HMSET

์—ฌ๋Ÿฌ ํ•„๋“œ์™€ ๊ฐ’์„ ํ•œ ๋ฒˆ์— Hash์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

$ HMSET user:1234 name "Ahn" age "26" email "dkswnkk@example.com"

HMGET

์—ฌ๋Ÿฌ ํ•„๋“œ์™€ ๊ฐ’์„ ํ•œ ๋ฒˆ์— ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

$ HMGET user:1234 name email
> "Juhyeong", "dkswnkk@example.com"

HINCRBY

Hash์˜ ์ง€์ •ํ•œ ํ•„๋“œ์˜ ์ˆซ์ž ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.

$ HINCRBY user:1234 age 1
> 27

HDEL

Hash์—์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ํ•„๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

$ HDEL user:1234 age

HEXISTS

์ง€์ •ํ•œ ํ•„๋“œ๊ฐ€ Hash์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

$ HEXISTS user:1234 email
> (integer) 0 or 1

HLEN

Hash์˜ ํ•„๋“œ ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ HLEN user:1234
> 1

HKEYS

Hash์˜ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ HKEYS user:1234
> "name"

HVALS

Hash์˜ ๋ชจ๋“  ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ HVALS user:1234
> "dkswnkk"

 

ํ™œ์šฉ ์‚ฌ๋ก€

Strings ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ํ™œ์šฉ ์‚ฌ๋ก€์™€ ๊ฑฐ์˜ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

1. Object Storage(๊ฐ์ฒด ์ €์žฅ)

Redis์˜ Hashes๋Š” ๊ฐ์ฒด์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์•„์ฃผ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ํ”„๋กœํ•„, ์„ค์ •, ์ƒํƒœ ๋“ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ key-value ์Œ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ HSET user:1234 name "Ahn JuHyeong" age 26 email "dkswnkk@example.com"  # user:1234์˜ ์ •๋ณด๋ฅผ ์ €์žฅ
$ HSET user:5678 name "Kim Jenny" age 28 email "jenny@example.com"  # user:5678์˜ ์ •๋ณด๋ฅผ ์ €์žฅ

$ HGETALL user:1234  # user:1234์˜ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์กฐํšŒ

2. Real-time Counters(์‹ค์‹œ๊ฐ„ ์นด์šดํ„ฐ)

์‹ค์‹œ๊ฐ„์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๋Š” ์นด์šดํ„ฐ ๊ฐ’๋“ค์„ ์ €์žฅํ•˜๋Š”๋ฐ Hashes๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ์›น์‚ฌ์ดํŠธ์˜ ํŽ˜์ด์ง€๋ทฐ๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํด๋ฆญ ์ˆ˜ ๋“ฑ์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ HINCRBY pageViews homepage 1  # ํ™ˆํŽ˜์ด์ง€์˜ ํŽ˜์ด์ง€๋ทฐ๋ฅผ 1 ์ฆ๊ฐ€
$ HINCRBY pageViews productPage 1  # ์ œํ’ˆ ํŽ˜์ด์ง€์˜ ํŽ˜์ด์ง€๋ทฐ๋ฅผ 1 ์ฆ๊ฐ€

$ HGET pageViews homepage  # ํ™ˆํŽ˜์ด์ง€์˜ ํŽ˜์ด์ง€๋ทฐ ์กฐํšŒ

3. Configurations and Settings(๊ตฌ์„ฑ ๋ฐ ์„ค์ •)

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์„ฑ ๊ฐ’์ด๋‚˜ ์„ค์ •์„ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•˜๋Š” ๋ฐ Hashes๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ HSET appConfig theme "dark" fontSize "medium" notifications "on"  # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ • ์ €์žฅ

$ HGET appConfig theme  # ํ…Œ๋งˆ ์„ค์ • ๊ฐ’ ์กฐํšŒ

4. Caching(์บ์‹ฑ)

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ฐ€์ ธ์˜จ ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋‚˜ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ๋กœ ์ €์žฅํ•  ๋•Œ Hashes๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ๋™์ผํ•œ ์ฟผ๋ฆฌ๋‚˜ ๊ณ„์‚ฐ์„ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•  ํ•„์š” ์—†์ด ๋น ๋ฅด๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ HSET queryResult:5678 productCount 120 userCount 500  # ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์ €์žฅ

$ HGET queryResult:5678 productCount  # ์ฟผ๋ฆฌ๋กœ ์–ป์€ ์ œํ’ˆ ์ˆ˜ ์กฐํšŒ

 

 

Streams

Redis Streams๋Š” 2018๋…„์— Redis 5.0์— ๋„์ž…๋œ ์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ŠคํŠธ๋ฆผ์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ €์žฅํ•˜๊ณ , ๋ฉ”์‹œ์ง€๋Š” ํ•„๋“œ์™€ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ํ•ญ๋ชฉ์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ํ•ญ๋ชฉ์—๋Š” ์ˆœ์„œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ณ ์œ ํ•œ ID๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Entry ID: ๊ฐ ํ•ญ๋ชฉ์€ '-'์˜ ํ˜•์‹์œผ๋กœ ๊ณ ์œ ํ•œ ID๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด '1518951480106-0'์ž…๋‹ˆ๋‹ค.
  • Consumer Groups: ์—ฌ๋Ÿฌ ์†Œ๋น„์ž๊ฐ€ ์ŠคํŠธ๋ฆผ์„ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ์†Œ๋น„์ž ๊ทธ๋ฃน์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋™์ผํ•œ ์ŠคํŠธ๋ฆผ์„ ๋™์‹œ์— ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

XADD

Stream์— ์ƒˆ๋กœ์šด ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. '\*'๋Š” Redis์—๊ฒŒ ID๋ฅผ ์ž๋™ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค.

$ XADD mystream * sensor-id 1234 temperature 19.8

XRANGE & XREVRANGE

์ง€์ •๋œ ID ๋ฒ”์œ„์˜ ํ•ญ๋ชฉ์„ ์ˆœ์„œ๋Œ€๋กœ ๋˜๋Š” ์—ญ์ˆœ์œผ๋กœ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

$ XRANGE mystream - + COUNT 10

์œ„ ๋ช…๋ น์€ Stream์˜ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ตœ๋Œ€ 10๊ฐœ์˜ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

XDEL

XDEL์„ ์‚ฌ์šฉํ•˜์—ฌ Redis Streams์˜ ํŠน์ • ํ•ญ๋ชฉ์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ XADD mystream * name Juhyeong
-> "1617856879455-0"

$ XDEL mystream 1617856879455-0
-> (integer) 1

Stream์—์„œ ํ•ญ๋ชฉ์„ ์‚ญ์ œํ•ด๋„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ‰์‹œ ๊ฐ์†Œํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Redis๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์žฌํ™œ์šฉํ•˜๋ฏ€๋กœ, ์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์˜ ๊ฐ์†Œ๋Š” ์‚ญ์ œ ํ›„ ์–ด๋Š ์ •๋„ ์‹œ๊ฐ„์ด ์ง€๋‚˜์•ผ ๊ด€์ฐฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ™œ์šฉ์‚ฌ๋ก€

1. Event Sourcing(์ด๋ฒคํŠธ ์†Œ์‹ฑ)

์ด๋ฒคํŠธ ์†Œ์‹ฑ์€ ์ƒํƒœ๊ฐ€ ์•„๋‹Œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ(์ด๋ฒคํŠธ)์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์€ํ–‰ ๊ณ„์ขŒ์˜ ์ž”์•ก ๋Œ€์‹  ์ž…๊ธˆ ๋ฐ ์ถœ๊ธˆ ํŠธ๋žœ์žญ์…˜์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ณผ๊ฑฐ์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ถ”์ ํ•˜๊ณ  ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์žฌ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Redis Streams๋Š” ์ด๋Ÿฌํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

$ XADD transactions * type deposit amount 100
$ XADD transactions * type withdraw amount 50

2. ๋กœ๊น… ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

์‹œ์Šคํ…œ์˜ ๋‹ค์–‘ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋กœ๊ทธ ๋˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ์ €์žฅํ•˜๋ ค๋Š” ๊ฒฝ์šฐ Redis Streams๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ XADD logs * level error message "Database connection failed"
$ XADD logs * level info message "User logged in"

3. ์‹ค์‹œ๊ฐ„ ๋Œ€์‹œ๋ณด๋“œ ๋ฐ ๋ถ„์„

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‹ค์‹œ๊ฐ„ ์‚ฌ์šฉ ํ˜„ํ™ฉ, ์„ฑ๋Šฅ ์ง€ํ‘œ, ์‚ฌ์šฉ์ž ํ™œ๋™ ๋“ฑ์„ ์‹ค์‹œ๊ฐ„ ๋Œ€์‹œ๋ณด๋“œ์— ํ‘œ์‹œํ•˜๋ ค๋ฉด Redis Streams๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ์บก์ฒ˜ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ XADD user_activity * action login user_id 1234
$ XADD system_metrics * cpu_usage 75 memory_usage 60

4. ๋ถ„์‚ฐ ํƒœ์Šคํฌ ํ

๋‹ค์–‘ํ•œ ์ž‘์—…์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด, ์ž‘์—… ํ•ญ๋ชฉ์„ Stream์— ์ถ”๊ฐ€ํ•˜๊ณ  ์—ฌ๋Ÿฌ ์ž‘์—…์ž ๋˜๋Š” ํ”„๋กœ์„ธ์„œ๊ฐ€ Stream์—์„œ ์ž‘์—…์„ ๊ฐ€์ ธ์™€ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ XADD tasks * task_type email payload "{...}"

5. ์‹œ๊ฐ„์ˆ˜ ์ด๋ฒคํŠธ ์ €์žฅ

์ด๋ฒคํŠธ๋ฅผ ์‹œ๊ฐ„์ˆœ์œผ๋กœ ์ €์žฅํ•˜๊ณ  ๋ถ„์„ํ•˜๋ ค๋ฉด Redis Streams์˜ ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์ธ๋ฑ์‹ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ XADD events * timestamp "2023-01-01T12:00:00" event_type "purchase" user_id 4567

 

 

Bits(Bitmaps)

Redis์˜ Bits, ๋˜๋Š” Bitmaps๋Š” ์ •์ˆ˜ ๋ฐฐ์—ด์— ๋น„ํŠธ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํŠน๋ณ„ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ๋น„ํŠธ๋ฅผ ์ €์žฅํ•˜๊ณ , ๊ฐ ๋น„ํŠธ์— ์ ‘๊ทผํ•˜์—ฌ ๊ฐ’์„ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Redis์—์„œ ๋น„ํŠธ๋Š” SETBIT, GETBIT, BITOP ๋“ฑ์˜ ๋ช…๋ น์„ ํ†ตํ•ด ์กฐ์ž‘๋ฉ๋‹ˆ๋‹ค.

SETBIT

์ง€์ •๋œ ํ‚ค์˜ ํŠน์ • ์œ„์น˜์— ์žˆ๋Š” ๋น„ํŠธ ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

$ SETBIT user:log-in:23-09-01 123 1  # '23-09-01' ๋‚ ์งœ์— ์‚ฌ์šฉ์ž ID '123'์ด ๋กœ๊ทธ์ธํ•œ ๊ฒƒ์„ ๋น„ํŠธ๋กœ ํ‘œ์‹œ

GETBIT

์ง€์ •๋œ ํ‚ค์˜ ํŠน์ • ์œ„์น˜์— ์žˆ๋Š” ๋น„ํŠธ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

$ GETBIT user:log-in:23-09-01 123  # '23-09-01' ๋‚ ์งœ์— ์‚ฌ์šฉ์ž ID '123'์ด ๋กœ๊ทธ์ธํ–ˆ๋Š”์ง€ ํ™•์ธ

BITOP

์—ฌ๋Ÿฌ ํ‚ค์— ์ €์žฅ๋œ ๋น„ํŠธ๋งต๋“ค ์‚ฌ์ด์˜ ๋น„ํŠธ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. AND, OR, XOR, NOT ์—ฐ์‚ฐ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

$ SETBIT user:1:log-in:January 1 1
$ SETBIT user:1:log-in:January 3 1
$ SETBIT user:2:log-in:January 1 1
$ SETBIT user:2:log-in:January 2 1

# 1๋ฒˆ ์‚ฌ์šฉ์ž์™€ 2๋ฒˆ ์‚ฌ์šฉ์ž ๋ชจ๋‘ ๊ฐ™์€ ๋‚ ์— ๋กœ๊ทธ์ธํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์„ ๋•Œ AND ์—ฐ์‚ฐ์„ ์‚ฌ์šฉ
$ BITOP AND both-logged-in:January user:1:log-in:January user:2:log-in:January

# ์œ„์˜ ๋‘ ์‚ฌ์šฉ์ž ์ค‘ ์–ด๋Š ํ•œ ๋ช…์ด๋ผ๋„ ๋กœ๊ทธ์ธํ•œ ๋‚ ์˜ ๊ธฐ๋ก์„ ์–ป๊ณ  ์‹ถ๋‹ค๋ฉด OR ์—ฐ์‚ฐ์„ ์‚ฌ์šฉ
$ BITOP OR any-logged-in:January user:1:log-in:January user:2:log-in:January

# ๋‘ ์‚ฌ์šฉ์ž๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ๋‚ ์— ๋กœ๊ทธ์ธํ•œ ๋‚ ๋งŒ ๊ธฐ๋กํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด XOR ์—ฐ์‚ฐ์„ ์‚ฌ์šฉ
$ BITOP XOR diff-logged-in:January user:1:log-in:January user:2:log-in:January

#1๋ฒˆ ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ๋‚ ์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด NOT ์—ฐ์‚ฐ์„ ์‚ฌ์šฉ
$ BITOP NOT user:1:not-logged-in:January user:1:log-in:January

BITCOUNT

์ฃผ์–ด์ง„ ๋ฒ”์œ„ ๋‚ด์—์„œ ์ง€์ •๋œ ํ‚ค์— ์„ค์ •๋œ ๋น„ํŠธ์˜ ์ˆ˜๋ฅผ ์นด์šดํŠธํ•ฉ๋‹ˆ๋‹ค.

$ BITCOUNT user:log-in:23-09-01  # '23-09-01'์— ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž ์ˆ˜๋ฅผ ์นด์šดํŠธ

BITOPS

์ง€์ •๋œ ๊ฐ’(0 ๋˜๋Š” 1)์˜ ์ฒซ ๋ฒˆ์งธ ๋น„ํŠธ ์œ„์น˜๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

$ BITPOS user:log-in:23-09-01 1  # '23-09-01'์— ์ฒ˜์Œ์œผ๋กœ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ID์˜ ์œ„์น˜๋ฅผ ์ฐพ์Œ

 

ํ™œ์šฉ ์‚ฌ๋ก€

1. ์ผ๋ณ„ ์‚ฌ์šฉ์ž ํ–‰๋™ ์ถ”์ 

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

$ SETBIT user:log-in:23-01-01 123 1

$ SETBIT user:purchase:23-01-01 123 1

 

 

HyperLogLog(PF)

Redis์˜ HyperLogLog๋Š” ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์—์„œ ๊ณ ์œ ํ•œ ํ•ญ๋ชฉ์˜ ์ˆ˜๋ฅผ ์ถ”์ •ํ•˜๊ธฐ ์œ„ํ•œ ํšจ์œจ์ ์ธ ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ •ํ™•ํ•œ ์นด์šดํŠธ๊ฐ€ ์•„๋‹Œ "์ถ”์ •์น˜"๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์ด๋Ÿฌํ•œ ํŠน์„ฑ ๋•๋ถ„์— HyperLogLog๋Š” ๋งค์šฐ ์ ์€ ๋ฉ”๋ชจ๋ฆฌ(์•ฝ 12KB)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜์‹ญ์–ต ๊ฐœ์˜ ์•„์ดํ…œ ์นด๋””๋„๋ฆฌํ‹ฐ๋ฅผ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ํŠน์ง•

  • ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ: ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์นด๋””๋„๋ฆฌํ‹ฐ๋ฅผ ์ถ”์ •ํ•  ๋•Œ ๊ณ ์ •๋œ ์†Œ๋Ÿ‰์˜ ๋ฉ”๋ชจ๋ฆฌ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํ•ฉ๋ณ‘ ๊ฐ€๋Šฅ: ์—ฌ๋Ÿฌ HyperLogLog ๊ตฌ์กฐ๋ฅผ ํ•˜๋‚˜๋กœ ํ•ฉ์ณ์„œ ์ถ”์ •์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ •ํ™•๋„: ํฐ ๋ฐ์ดํ„ฐ ์…‹์˜ ๊ฒฝ์šฐ ์•ฝ 0.81%์˜ ํ‘œ์ค€ ์˜ค์ฐจ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

PFADD

ํŠน์ • HyperLogLog์— ํ•˜๋‚˜ ์ด์ƒ์˜ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

$ PFADD users:visited user123 user456 user789

> (integer)1

PFADD์˜ ๋ฐ˜ํ™˜๊ฐ’์€ HyperLogLog์˜ ๋‚ด๋ถ€ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. 1์€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„, 0์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

PFCOUNT

HyperLogLog์—์„œ ๊ณ ์œ ํ•œ ์š”์†Œ์˜ ๊ฐœ์ˆ˜๋ฅผ ์ถ”์ •ํ•ฉ๋‹ˆ๋‹ค.

$ PFCOUNT users:visited

> (integer)3

PFMERGE

๋‘ ๊ฐœ ์ด์ƒ์˜ HyperLogLogs๋ฅผ ๋ณ‘ํ•ฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ํ•˜๋‚˜์˜ HyperLogLog๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

$ PFMERGE combinedUsers users:visitedJan users:visitedFeb

> OK

 

๋ฉ”๋ชจ๋ฆฌ ๋น„๊ต

์‹ค์ œ๋กœ 1000๊ฐœ์˜ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ SADD์™€ FADD์˜ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

$ SADD myset value1 value2 ... value1000
> (integer) 1000

$ MEMORY USAGE myset
> (integer) 48304

$ PFADD myhll value1 value2 ... value1000
> (integer) 1

$ MEMORY USAGE myhll
> (integer) 2104

 

ํ™œ์šฉ ์‚ฌ๋ก€

1. ๋ฐฉ๋ฌธ์ž ์ˆ˜ ์ถ”์ •

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

 

 

GEO(Geospatial)

Redis์˜ Geospatial์€ ์œ„์น˜ ๊ธฐ๋ฐ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์ฟผ๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ Sorted Sets์„ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋ฉฐ, Geohash ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฝ๋„์™€ ์œ„๋„๋ฅผ ์ธ์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค.

GEOADD

์ง€์ •๋œ ํ‚ค์— ํ•˜๋‚˜ ์ด์ƒ์˜ ์œ„์น˜ ์š”์†Œ(๊ฒฝ๋„, ์œ„๋„ ์ด๋ฆ„)๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์œ„์น˜๋Š” ๊ฒฝ๋„, ์œ„๋„, ์ด๋ฆ„ ์ˆœ์„œ๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค.

$ GEOADD company 127.056945 37.413294 "Kakao" 126.978400 37.566500 "Naver"
> (integer) 2

GEODIST

๋‘ ์œ„์น˜ ์š”์†Œ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฑฐ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ m(๋ฏธํ„ฐ)๋กœ ๋ฐ˜ํ™˜๋˜์ง€๋งŒ, m(๋ฏธํ„ฐ), km(ํ‚ฌ๋กœ๋ฏธํ„ฐ), mi(๋งˆ์ผ), ft(ํ”ผํŠธ)๋กœ ๋‹จ์œ„๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ GEODIST company "Kakao" "Naver"
> "8421.0275"

$ GEODIST companyHQs "Kakao" "Naver" km
> "8km"

GEOHASH

์ง€์ •๋œ ์œ„์น˜ ์š”์†Œ์˜ GeoHash ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. Geohash๋Š” ์œ„์น˜ ์ •๋ณด๋ฅผ ์งง์€ ๋ฌธ์ž์—ด๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

$ GEOHASH company "Kakao"
> "wydm4g2c1hrz"

GEOPOS

์ง€์ •๋œ ์œ„์น˜ ์š”์†Œ์˜ ๊ฒฝ๋„์™€ ์œ„๋„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ GEOPOS company "Kakao"
> 1) 1) "127.05694484710693" 2) "37.41329383850098"

GEORADIUS

์ฃผ์–ด์ง„ ์œ„์น˜๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ง€์ •๋œ ๋ฐ˜๊ฒฝ ๋‚ด์˜ ์œ„์น˜ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. WITHDIST, WITHHASH, WITHCOORD ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฑฐ๋ฆฌ, Geohash, ์ขŒํ‘œ์™€ ํ•จ๊ป˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ GEORADIUS company 127.056945 37.413294 5 km WITHDIST
> 1) 1) "Kakao" 2) "0.0002"

GEORADIUSBYMEMBER

ํŠน์ • ์œ„์น˜ ์š”์†Œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ง€์ •๋œ ๋ฐ˜๊ฒฝ ๋‚ด์˜ ๋‹ค๋ฅธ ์œ„์น˜ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋„ GEORADIUS์™€ ๋™์ผํ•œ ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ GEORADIUSBYMEMBER company "Kakao" 15 km
> 1) "Kakao" 2) "Naver"

 

ํ™œ์šฉ ์‚ฌ๋ก€

Redis์˜ Geospatial ๋ช…๋ น์–ด๋“ค์€ ์œ„์น˜ ๊ธฐ๋ฐ˜ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์‹ค์‹œ๊ฐ„ ์œ„์น˜์ถ”์ , ๊ทผ์ ‘ ์œ„์น˜ ๊ฒ€์ƒ‰, ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์œ„ํ•ด ์ด ๋ช…๋ น์–ด๋“ค์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

BloomFilter

Bloom Filter๋Š” ํ™•๋ฅ ์  ์ž๋ฃŒ ๊ตฌ์กฐ๋กœ์„œ, ์–ด๋–ค ์š”์†Œ๊ฐ€ ์ง‘ํ•ฉ ๋‚ด์— ์กด์žฌํ•˜๋Š”์ง€ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์ธ Bloom Filter๋Š” ์š”์†Œ๊ฐ€ ์ง‘ํ•ฉ ๋‚ด์— ์กด์žฌํ•˜๋Š”์ง€๋งŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•ด๋‹น ์š”์†Œ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Bloom Filter์˜ ์ฃผ์š” ์žฅ์ ์€ ๊ณต๊ฐ„ ํšจ์œจ์„ฑ๊ณผ ์‹œ๊ฐ„ ํšจ์œจ์„ฑ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ ์€ ์–‘์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งŽ์€ ์š”์†Œ๋“ค์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ™•๋ฅ ์ ์ธ ํŠน์„ฑ ๋•Œ๋ฌธ์— false positive(์—†๋Š” ๋ฐ ์žˆ๋‹ค๊ณ  ๋งํ•จ)์˜ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์–ด๋–ค ์š”์†Œ๊ฐ€ ์ง‘ํ•ฉ ๋‚ด์— ์กด์žฌํ•˜์ง€ ์•Š์Œ์—๋„ ์กด์žฌํ•œ๋‹ค๊ณ  ์ž˜๋ชป ํŒ๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ false negative(์žˆ๋Š”๋ฐ ์—†๋‹ค๊ณ  ๋งํ•จ)๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Redis์˜ ๊ฒฝ์šฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ Bloom Filter ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๋‚ด์žฅํ•˜๊ณ  ์žˆ์ง€ ์•Š์œผ๋ฉฐ, Redis ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ Bloom Filter ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. RedisBloom์ด๋ผ๋Š” ๋ชจ๋“ˆ์ด ์ด๋ฅผ ์œ„ํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

BF.ADD

Bloom Filter์— ํ•˜๋‚˜ ์ด์ƒ์˜ ์•„์ดํ…œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

$ BF.ADD myFilter "item1"

BF.MADD

Bloom Filter์— ์—ฌ๋Ÿฌ ์•„์ดํ…œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

$ BF.MADD myFilter "item1" "item2" "item3"

BF.EXISTS

Bloom Filter์—์„œ ํŠน์ • ์•„์ดํ…œ์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

$ BF.EXISTS myFilter "item1"

BF.MEXISTS

Bloom Filter์—์„œ ์—ฌ๋Ÿฌ ์•„์ดํ…œ์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

$ BF.MEXISTS myFilter "item1" "item2"

 

ํ™œ์šฉ ์‚ฌ๋ก€

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

 

 

์ฐธ๊ณ 

๋Œ“๊ธ€