๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
CS

Redis String vs Set vs Bitmap ๋ฉ”๋ชจ๋ฆฌ ๋น„๊ต

by ์ฃผ๋ฐœ2 2025. 11. 1.
๋ฐ˜์‘ํ˜•

 

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

 

์ด ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด Redis์˜ String, Set, Bitmap ์ค‘ ์–ด๋–ค ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ ํ•ฉํ• ๊นŒ?

๊ฐ ํƒ€์ž…์˜ ํŠน์ง•๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋“ฑ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.

(๊ฒŒ์‹œ๊ธ€ ID๋Š” 15๊ฐœ, ์œ ์ € ID๋Š” 1~300๋งŒ, ํ•˜๋‚˜์˜ ๊ฒŒ์‹œ๊ธ€์ด ์—ฌ๋Ÿฌ ์œ ์ €์—๊ฒŒ ๋ฐœ์†ก์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.)

 

์•„๋ž˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” INFO memory ๋ช…๋ น์–ด์˜ Redis ๋ฉ”๋ชจ๋ฆฌ ํ•„๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ํ•„๋“œ ์„ค๋ช…
used_memory ํ˜„์žฌ Redis์—์„œ ์‚ฌ์šฉ์ค‘์ธ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ฐ”์ดํŠธ ์ˆ˜
used_memory_human used_memory์— ๋Œ€ํ•ด ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ํ˜•์‹์œผ๋กœ ํ‘œ์‹œํ•œ ๊ฐ’
used_memory_peak Redis์—์„œ ์‚ฌ์šฉ๋œ ์ตœ๊ณ ์น˜ ๋ฉ”๋ชจ๋ฆฌ 
used_memory_peak_perc ํ”ผํฌ ์‚ฌ์šฉ๋Ÿ‰ ์ค‘ ํ˜„์žฌ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์˜ ๋น„์œจ
used_memory_overhead Redis ์˜ค๋ฒ„ํ—ค๋“œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰
(์‹ค์ œ ๋ฐ์ดํ„ฐ ์™ธ key, metadata ๋“ฑ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ)
used_memory_dataset ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์–‘
(used_memory - used_memory_overhead)
used_memory_dataset_perc ์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ์ค‘ ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋น„์œจ

 

 

String

String ํƒ€์ž…์€ ํ…์ŠคํŠธ, ์ง๋ ฌํ™”๋œ ๊ฐ์ฒด, ์ด์ง„ ๋ฐฐ์—ด, ๋ฐ”์ดํŠธ ์‹œํ€€์Šค ๋“ฑ์„ ์ €์žฅํ•˜๋Š” Redis์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

์ฃผ๋กœ ์บ์‹ฑ์— ์‚ฌ์šฉ๋˜์ง€๋งŒ, ์นด์šดํ„ฐ ๊ตฌํ˜„์ด๋‚˜ ๋น„ํŠธ ์—ฐ์‚ฐ ๋“ฑ์˜ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ๋„ ์ง€์›ํ•œ๋‹ค.

String ํƒ€์ž…์—๋Š” GET, SET, MGET, MSET, SETNX, INCR ๋“ฑ์˜ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊ฒŒ์‹œ๊ธ€ ๋ณ„๋กœ ์œ ์ €๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ผ€์ด์Šค

  • key: community:post:{post_id}
  • value: {user_id}

 

300๋งŒ์˜ ๋ฐ์ดํ„ฐ๋ฅผ String ํƒ€์ž…์œผ๋กœ ๋„ฃ์€ ๊ฒฐ๊ณผ

  • used_memory_human: 201.16MB
  • used_memory_peak_perc: 4.14%
  • used_memory_dataset: 63,423,592 bytes(60.48MB)
  • used_memory_overhead: 147,512,176 bytes(140.71MB)
  • used_memory_dataset_perc: 30.21%

 

์œ ์ € ๋ณ„ ๊ฒŒ์‹œ๊ธ€์„ ๊ด€๋ฆฌํ•˜๋Š” ์ผ€์ด์Šค

  • key: community:post:{user_id}
  • value: {post_id}

 

300๋งŒ์˜ ๋ฐ์ดํ„ฐ๋ฅผ String ํƒ€์ž…์œผ๋กœ ๋„ฃ์€ ๊ฒฐ๊ณผ

  • used_memory_human: 192.87MB
  • used_memory_peak_perc: 3.97%
  • used_memory_dataset: 54,743,408 bytes(52.20MB)
  • used_memory_overhead: 147,493,744 bytes(140.66MB)
  • used_memory_dataset_perc: 27.20%

 

๋ถ„์„

๊ฒŒ์‹œ๊ธ€ ID์™€ ์œ ์ € ID ์ค‘ ์–ด๋– ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ key๋กœ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์€ ์œ ์‚ฌํ•˜๋‹ค.

๋”ฐ๋ผ์„œ String ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ key์˜ ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๋“ฏ ํ•˜๋‹ค.

 

 

Set

Set์€ ์–ธ์–ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์™€ ๋™์ผํ•˜๊ฒŒ ์ค‘๋ณต์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ๊ณ ์œ ํ•œ ๊ฐ’๋“ค์„ ์ €์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‹ค.

Set ํƒ€์ž…์—์„œ๋Š” SADD, SCARD, SMEMBERS, SREM ๋“ฑ์˜ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

Redis์— ์ €์žฅ๋˜๋Š” key-value ๊ตฌ์กฐ

  • key: community:post:{post_id}
  • value: {user_ids}

 

  • used_memory_human: 100.69MB
  • used_memory_peak_perc: 2.07%
  • used_memory_dataset: 103,127,040 bytes(98.35MB)
  • used_memory_overhead: 2,459,176 bytes(2.34MB)
  • used_memory_dataset_perc: 98.61%

 

Redis String vs Set

 

 

Bitmap

Bitmap์€ ์‹ค์ œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ์•„๋‹Œ, ๋น„ํŠธ ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•œ String ํƒ€์ž…์„ ํ™œ์šฉํ•œ ํ˜•์‹์ด๋‹ค.

String์˜ ์ตœ๋Œ€ ๊ธธ์ด๊ฐ€ 512MB์ด๋ฏ€๋กœ ์ตœ๋Œ€ 2^32๊ฐœ์˜ ๋น„ํŠธ๊นŒ์ง€ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

๋™์ผํ•œ key์— ๋Œ€ํ•ด ๋งŽ์€ ๋น„ํŠธ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Redis์— ์ €์žฅ๋˜๋Š” key-value ๊ตฌ์กฐ

  • key: community:post:{post_id}
  • value: bit(0 or 1, user_id์— bit 1 ๊ฐ’์œผ๋กœ ์„ค์ •)

์˜ˆ๋ฅผ ๋“ค์–ด์„œ, post_id๊ฐ€ 100์ธ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•ด user_id๊ฐ€ 1000, 2000์ธ ์œ ์ €๊ฐ€ ์•Œ๋ฆผ ๋ฐœ์†ก์„ ๋ฐ›์•˜๋‹ค๋ฉด

SETBIT community:post:100 1000 1  # user_id 1000๋ฒˆ ์œ„์น˜์— 1 ์„ค์ •
SETBIT community:post:100 2000 1  # user_id 2000๋ฒˆ ์œ„์น˜์— 1 ์„ค์ •
GETBIT community:post:100 1001    # user_id 1001๋ฒˆ ์œ„์น˜๋Š” 0 (๋ฏธ๋ฐœ์†ก)

 

  • used_memory_human: 6.29MB
  • used_memory_peak_perc: 0.13%
  • used_memory_dataset: 5,182,920 bytes(4.94MB)
  • used_memory_overhead: 1,416,160 bytes(1.35MB)
  • used_memory_dataset_perc: 92.57%

 

String vs Set vs Bitmap

 

Bitmap ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ถ„์„

์œ„์˜ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ, Bitmap์€ String์ด๋‚˜ Set์— ๋น„ํ•ด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ํ˜„์ €ํžˆ ์ ๋‹ค. ์–ด๋–ป๊ฒŒ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ• ๊นŒ?

์ฒซ ๋ฒˆ์งธ key(post_id = 10000)์™€ ๋งˆ์ง€๋ง‰ key(post_id = 24000)์ธ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

community:post:10000 ์˜ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰: 393256(์•ฝ 32KB)

  • ๋ฐ์ดํ„ฐ ์ˆ˜(BITCOUNT): 200,000
  • ํ•„์š”ํ•œ ์ตœ์†Œ ๋น„ํŠธ(1byte = 8bit): 200,000 bits = 25,000 bytes (25KB), ์˜ค๋ฒ„ํ—ค๋“œ ์•ฝ 7KB
  • Bitmap์—์„œ ๊ฐ€์žฅ ์ฒ˜์Œ bit๊ฐ€ 1์ธ ์œ„์น˜: 1

 

community:post:24000 ์˜ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰: 392356 (์•ฝ 384KB)

  • ๋ฐ์ดํ„ฐ ์ˆ˜(BITCOUNT): 200,000
  • ํ•„์š”ํ•œ ์ตœ์†Œ ๋น„ํŠธ(1byte = 8bit): 3,000,000 bits = 375,000 bytes (375KB), ์˜ค๋ฒ„ํ—ค๋“œ ์•ฝ 9KB
  • Bitmap์—์„œ ๊ฐ€์žฅ ์ฒ˜์Œ bit๊ฐ€ 1์ธ ์œ„์น˜: 2,800,001

 

์‹ค์ œ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋Š” ๋™์ผ(20๋งŒ ๊ฐœ)ํ•˜์ง€๋งŒ, Bitmap์ด ํ• ๋‹นํ•ด์•ผ ํ•˜๋Š” ๋น„ํŠธ ๋ฒ”์œ„๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‘ key์˜ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์€ ์•ฝ 10๋ฐฐ์˜ ์ฐจ์ด๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. (32KB, 384KB)

 

์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด BITCOUNT ๊ฐ’์€ 1์ด์ง€๋งŒ, ํ•„์š”ํ•œ ์ตœ์†Œ ๋น„ํŠธ๊ฐ€ 3,000,000 bits ์ด๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์ด 384KB๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

 

 

๊ฒฐ๋ก 

๋”ฐ๋ผ์„œ, Bitmap์˜ ๊ฒฝ์šฐ ํŠน์ • key ๋‚ด์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์กฐ๋ฐ€ํ•˜๊ฒŒ ๋ถ„ํฌ๋˜์–ด ์žˆ๋Š”์ง€์— ํฌ๊ฒŒ ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค.

๊ทธ๋ ‡๊ธฐ์— ๋™์ผํ•œ ์ƒํ™ฉ์—์„œ key๊ฐ€ ๋˜๋Š” post_id๊ฐ€ ๋งŽ์„์ˆ˜๋ก bitmap์€ ๋ฉ”๋ชจ๋ฆฌ ์ธก๋ฉด์—์„œ ๋” ๋น„ํšจ์œจ์ ์ธ ์„ ํƒ์ด ๋œ๋‹ค.

 

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€