๐ Redis Object ๊ฐ์
Redis ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฅ๊ณต๊ฐ์ผ๋ก ์ฌ์ฉํ๋ In-Memory Key-value ์คํ ์ด ์ด๋ค.
- ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋๋ฏ๋ก ๋น ๋ฅธ ์ฝ๊ธฐ/์ฐ๊ธฐ๊ฐ ๊ฐ๋ฅ
- ํ์ง๋ง ๋ฉ๋ชจ๋ฆฌ๋ ์ ํํ ์์์ด๋ฏ๋ก ํจ์จ์ ์ธ ๊ด๋ฆฌ๊ฐ ํ์์
๋ฉ๋ชจ๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋๋ก, Redis๋ ๋ฐ์ดํฐ๋ฅผ Object๋ก ์ ์ํ๊ณ ์๋ค.
Redis์ ๊ณ ์ฑ๋ฅ๊ณผ ํจ์จ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ๊ฐ๋ฅํ๊ธฐ ์ํด Object๋ ์๋์ ๊ฐ์ ์ญํ ์ ํ๋ค.
- ๋ฐ์ดํฐ ํํ
- ๋ชจ๋ ํค-๊ฐ ์์ RedisObject๋ก ํต์ผํ์ฌ ํํ
- ๋ค์ํ ๋ฐ์ดํฐ ํ์ (String, List, Hash ๋ฑ)์ ํ๋์ ๊ตฌ์กฐ๋ก ๊ด๋ฆฌ
- ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ
- ๋ฐ์ดํฐ ํน์ฑ์ ๋ฐ๋ผ ์ต์ ์ ์ธ์ฝ๋ฉ ๋ฐฉ์์ ์๋ ์ ํ
- ์์ ๋ฐ์ดํฐ๋ ์์ถ๋ ํํ๋ก ์ ์ฅ
- ์ค๋ณต ๋ฐ์ดํฐ๋ ์ฐธ์กฐ ๋ฐฉ์์ผ๋ก ์ ์ฅ
- ์ฑ๋ฅ ์ต์ ํ
- ๋ฐ์ดํฐ ์ ๊ทผ ํจํด ์ถ์ (LRU)
- ํจ์จ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ํ์ ์ ์ฑ ์ง์
- ๋ฐ์ดํฐ ํ์ ๋ณ ํนํ๋ ์ฐ์ฐ ์ง์
- ๋ฉ๋ชจ๋ฆฌ ๋จํธํ ๋ฐฉ์ง
๐ Redis Object ์ SDS (Simple Dynamic String)
โบ Object
Object๋ ์ค์ ๋ฐ์ดํฐ๊ฐ ์ด๋ป๊ฒ ์ ์ฅ๋ ์ง์ ๋ํ ์ ์์ด๋ฉฐ. ์๋์ ๊ฐ๋ค.
typedef struct redisObject {
unsigned type:4; // ๋ฐ์ดํฐ ํ์
(4๋นํธ)
unsigned encoding:4; // ์ธ์ฝ๋ฉ ๋ฐฉ์(4๋นํธ)
unsigned lru:24; // LRU ์๊ฐ์ ๋ณด (24๋นํธ)
int refcount; // ์ฐธ์กฐ์นด์ดํธ
void *ptr; // ์ค์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ
} robj;
- ํ๋ ์ค๋ช
- type: ์ค์ ๊ฐ(0:STRING, 1:LIST, 2:SET, 3:ZSET, 4:HASH)
- encoding: ์ค์ ์ฌ์ฉ๋๋ ์ธ์ฝ๋ฉ ๊ฐ๋ค (INT, EMBSTR, RAW, HASHTABLE, LISTPACK ๋ฑ)
- lru (Least Recently Used): LRU ์ ๋ณด, ์ฆ ๋ง์ง๋ง ์ ๊ทผ ์๊ฐ ์ ์ฅ (๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ ์ค๋๋ ๋ฐ์ดํฐ ์ญ์ ์ ์ด์ฉ)
- refcount: ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์ํ ์ฐธ์กฐ ์นด์ดํ (0์ด ๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ํด์ )
- refcount: ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ํ์ (๋ฉ๋ชจ๋ฆฌ๊ด๋ฆฌ๋ฅผ ์ํ ์นด์ดํฐ, 0๋๋ฉด ๋ฉ๋ชจ๋ฆฌ์์ ํด์ , ๋ฐ์ดํฐ ๊ณต์ ์ ์ฆ๊ฐ)
- ptr: ์ค์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ์์น๋ฅผ ๊ฐ๋ฆฌํด
โบ SDS (Simple Dynamic String)
SDS๋ Redis๊ฐ ๋ฌธ์์ด์ ์ ์ฅํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ฒด์ด๋ค.
๊ธธ์ด ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์์ผ๋ฉฐ, ๋ฒํผ ์ค๋ฒํ๋ก์ฐ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ฉ๋ชจ๋ฆฌ ๋จ์ ๊ณต๊ฐ์ ์ ์ฅํ๊ณ , ์๋์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ ํ ๋นํ ์ ์๋๋ก ํ๋ค.
struct sdshdr {
uint32_t len; // ๋ฒํผ์ ์ฌ์ฉ๋ ๊ธธ์ด
uint32_t free; // ๋จ์ ๋ฒํผ ๊ธธ์ด
char buf[]; // ์ค์ ๋ฌธ์์ด ๋ฐ์ดํฐ
}
Object ํ๋ ๋ด *ptr๋ถ๋ถ์์ SDS ํน์ ์ค์ ๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋ฅดํค๊ฒ ๋๋ค.
RedisObject (robj) โ โโโ ptr (pointer) โโ→ SDS โ โโโโโโโโ→ ์ค์ ๋ฌธ์์ด ๋ฐ์ดํฐ |
์ฆ, ์ด๋ค ๋ฐ์ดํฐํ์
์ด๋ ์ธ์ฝ๋ฉ์ ์ฌ์ฉํ๋๋์ ๋ฐ๋ผ SDS๋ฅผ ์ฌ์ฉํ์ง ์์์๋ ์๋ค.
Redis๋ ๊ฐ์ฅ ํจ์จ์ ์ธ ์ ์ฅ ๋ฐฉ์์ ์๋์ผ๋ก ์ ํํ๋ค.
###################################
# 1. ์ ์ (int)
# RedisObject
# type: STRING
# encoding: INT
# ptr โโ→ ์ง์ ์ ์๊ฐ ์ ์ฅ
127.0.0.1:6379> SET number 123
127.0.0.1:6379> OBJECT ENCODING number
"int" // SDS ์ฌ์ฉํ์ง ์์, ์ง์ ์ ์ ์ ์ฅ
###################################
# 2. ์์ ๋ฌธ์์ด (embstr)
# [RedisObject + SDS] (์ฐ์๋ ๋ฉ๋ชจ๋ฆฌ)
127.0.0.1:6379> SET name "john"
127.0.0.1:6379> OBJECT ENCODING name
"embstr" // RedisObject์ SDS๊ฐ ์ฐ์๋ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น
###################################
# 3. ํฐ ๋ฌธ์์ด (raw)
# RedisObject → SDS
127.0.0.1:6379> SET bigtext "very...long...text..."
127.0.0.1:6379> OBJECT ENCODING bigtext
"raw" // ์ผ๋ฐ์ ์ธ SDS ์ฌ์ฉ
###################################
# 4. ๋ฆฌ์คํธ
# RedisObject → ์๋ฃ๊ตฌ์กฐ → SDS๋ค
127.0.0.1:6379> RPUSH mylist "a" "b" "c"
127.0.0.1:6379> OBJECT ENCODING mylist
"quicklist" // ๋ด๋ถ์ ์ผ๋ก SDS ์ฌ์ฉ
###################################
# 5.Hash (listpack/hashtable)
# RedisObject
# type: HASH
# encoding: HASHTABLE
# ptr โโ→ HashTable โโ→ {
# key1: SDS1,
# key2: SDS2,
# ...
# }
127.0.0.1:6379> HSET user name "Tom" age "25"
127.0.0.1:6379> OBJECT ENCODING user
"listpack" // ์์ ๊ฒฝ์ฐ listpack, ํฐ ๊ฒฝ์ฐ hashtable
โบ Object, SDS, Datatype, Encoding ๊ด๊ณ
์ค์ ์ปดํฌ๋ํธ๋ค์ ์๋์ ๊ฐ์ ๊ด๊ณ๋ฅผ ๊ฐ์ง๋ค.
RedisObject → SDS
↓
Data Types (String, List, Hash, Set, Sorted Set)
↓
Encoding (Raw, Int, Embstr, Ziplist, Quicklist...)
๋น์ ๋ฅผ ํ์๋ฉด, Redis๊ฐ ๋ํ ์ ๋ฐ์ด๋ผ๋ฉด, Object๋ ์ฉ๋๋ณ๋ก ๊ตฌ๋ถ๋ ๊ณต๊ฐ, SDS๋ ์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ๋ฐ์ค๋ผ๊ณ ๋ณผ์์๋ค.
๊ตฌํ(Object)์ ์ปจํ
์ด๋(SDS)๋ฅผ ์ด๋ป๊ฒ ๋ฐฐ์นํ๊ณ ๊ด๋ฆฌํ ์ง ๊ฒฐ์ ํ๊ณ ,
์ปจํ
์ด๋(SDS)๋ ์ค์ ํ๋ฌผ(๋ฐ์ดํฐ)์ ์์ ํ๊ฒ ๋ณด๊ดํ๋ค.
๋ํ ์ ๋ฐ (Redis)
โ
โโโ ๊ตฌํ (RedisObject)
โ โ
โ โโโ ์ผ๋ฐ ๋ฌผํ ๋ณด๊ด์ (String Type)
โ โ โโโ ์ปจํ
์ด๋๋ค (SDS - raw/embstr)
โ โ โโโ ๋ฐ๋ฅ์ ๋์ธ ์์ ๋ฌผํ๋ค (์ ์ - int)
โ โ
โ โโโ ์ปจํ
์ด๋ ์ ๋ ฌ์ (List Type)
โ โ โโโ ์์๋๋ก ์ ๋ ฌ๋ ์ปจํ
์ด๋๋ค (QuickList → SDS๋ค)
โ โ
โ โโโ ์ปจํ
์ด๋ ๋ถ๋ฅ์ (Hash Type)
โ โ โโโ ๋ผ๋ฒจ๋ง๋ ์ปจํ
์ด๋๋ค (field-SDS, value-SDS ์)
โ โ
โ โโโ ์ปจํ
์ด๋ ์ค๋ณต์ ๊ฑฐ์ (Set Type)
โ โ โโโ ์ ๋ํฌํ ์ปจํ
์ด๋๋ค (SDS๋ค)
โ โ
โ โโโ ์ปจํ
์ด๋ ์ฐ์ ์์์ (Sorted Set Type)
โ โโโ ์ ์๊ฐ ๋งค๊ฒจ์ง ์ปจํ
์ด๋๋ค (score-SDS ์)
๐ Redis ์ค์ต ์ค๋นํ๊ธฐ
๋จผ์ ์ดํดํ๋ฉด์ ์ค์ตํ ์ ์๋๋ก Redis๋ฅผ ์ค๋นํด๋์ ๐ช๐ช
# Redis ์ต์ ๋ฒ์ ์คํ
docker run --name redis -p 6379:6379 -d redis
# Redis CLI ์ ์
docker exec -it redis redis-cli
๐ Redis Data Type
โบ ๋ฐ์ดํฐํ์ ์ดํดํ๊ธฐ
๋ฐ์ดํฐ ํ์
์ Object ๋ด์์ type์ผ๋ก ์ ์๋๋ฉฐ (unsigned type:4;) ์ซ์๋ก ํํ๋๋ค.
4๋นํธ๋ก ํํ๋๋ฏ๋ก ์ต๋ 16๊ฐ์ง ํ์
์ ํํํ ์ ์๋ค.
define OBJ_STRING 0 // ๋ฌธ์์ด
define OBJ_LIST 1 // ๋ฆฌ์คํธ
define OBJ_SET 2 // ์
define OBJ_ZSET 3 // ์ ๋ ฌ๋ ์
define OBJ_HASH 4 // ํด์
define OBJ_STREAM 6 // ์คํธ๋ฆผ
Redis Data Type์ ๊ธฐ๋ณธ(Core) ๋ฐ์ดํฐ ํ์
๊ณผ, ํน์ ๋ฐ์ดํฐํ์
์ด ์กด์ฌํ๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํด์ผํ ์ ์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ํ์
๋ค๋ง RedisObject์ 4๋นํธ typeํ๋๋ก ํํ๋๋ค๋๊ฒ์ด๋ค.
ํน์๋ฐ์ดํฐ ํ์ ์์๋ก ์๋์ ๊ฐ์ ํ์ ์ด ์๊ณ , ๋ชจ๋ ์์คํ ์ ํตํด ํ์ฅ ๋๊ฑฐ๋ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ํ์ ์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ๋๋ค.
- Bitmap: ์ค์ ๋ก๋ STRING ํ์ ์ ํน๋ณํ ์ฒ๋ฆฌ
- Geospatial: ๋ด๋ถ์ ์ผ๋ก๋ ZSET ์ฌ์ฉ
- HyperLogLog: STRING ํ์ ์ผ๋ก ๊ตฌํ
- Bloom filter: STRING ํ์ ๊ธฐ๋ฐ
- Time series: ํน๋ณํ ๋ชจ๋๋ก ๊ตฌํ
์๋ฅผ๋ค์๋ฉด, ์๋์ฒ๋ผ ๊ตฌํ๋๋ค.
# Bitmap์ ์ค์ ๋ก๋ STRING
SETBIT mykey 7 1 # ๋ด๋ถ์ ์ผ๋ก๋ STRING ํ์
# Geospatial์ ZSET ์ฌ์ฉ
GEOADD locations 13.361389 38.115556 "Palermo" # ๋ด๋ถ์ ์ผ๋ก๋ ZSET
# HyperLogLog๋ STRING
PFADD visitors "user1" # ๋ด๋ถ์ ์ผ๋ก๋ STRING
Redis์์๋ ๋ฐ์ดํฐํ์
์ ์ง์ ์ง์ ํ๋๊ฒ ์๋๋ผ ๋ช
๋ น์ด๋ฅผ ํตํด ๋ฐ์ดํฐ ํ์
์ด ๊ฒฐ์ ๋๋ค.
๋ช
๋ น์ด์ ์ฒซ ๊ธ์๋ก ์ด๋ค ๋ฐ์ดํฐ ํ์
์ ๋ค๋ฃจ๋์ง ์ ์ ์๋ค. ์์ธํ ๋ด์ฉ์ ์๋์์ ๋ค๋ฃฌ๋ค.
- String: ์ ๋์ด ์์ (SET, GET)
- List: L ๋๋ R
- Set: S
- Sorted Set: Z
- Hash: H
- Stream: X
๋ฐ์ดํฐ ํ์ ์ ํ์ธํ๋ ค๋ฉด ์๋ ๋ช ๋ น์ด๋ก ํ์ธํ ์ ์๋ค.
# ํ์
ํ์ธ ๋ช
๋ น์ด
TYPE key๋ช
โบ Core Data type
1. Strings (์คํธ๋ง/๋ฌธ์์ด)
- https://redis.io/docs/latest/develop/data-types/strings/
๋ฌธ์์ด ์ ํ์ ๊ฐ์ผ๋ก ๊ฐ์ง๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํฐ ํ์
์ด๋ค. (๊ฐ์ ์ต๋ 512MB, ํฐ๋ฌธ์์ด์ ๋ฉ๋ชจ๋ฆฌ ํํธํ ์ฃผ์)
์ผ๋ฐ ๋ฌธ์์ด ๋ฟ ๋ง ์๋๋ผ ์ซ์(์ ์/์ค์), JSON๋ฌธ์์ด, ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ ์ ์ฅ์ด ๊ฐ๋ฅํ๋ค.
๊ฐ์ฅ ๋ง์ด ํ์ฉ๋๋ ์ ํ์ผ๋ก, Redis๋ก ๊ฐ์ฅ ๋ง์ด ๊ตฌํ๋๋ ์บ์/์ธ์
์ผ๋ก ํ์ฉํ๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
SET key value # ๋ฌธ์์ด ์ ์ฅ SETNX # ํค๊ฐ ์กด์ฌํ์ง ์์๋๋ง ๋ฌธ์์ด ์ ์ฅ (SET if Not eXists"์ ์ฝ์, Lock๊ตฌํ์ ์ฐ์) GET key # ๋ฌธ์์ด ๊ฒ์ |
- ํ์ฉ์ฌ๋ก
- ์บ์ (์นํ์ด์ง, API์๋ต, SQL์ฟผ๋ฆฌ ์บ์ฑ)
- ์ธ์ ์ ์ฅ
- ์นด์ดํฐ (์กฐํ์, ์ข์์ ์)
- ๋ฝ(Lock) ๊ตฌํ
- API ๋ ์ดํธ ๋ฏธํฐ๋ง
๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ ์ฟผ๋ฆฌ ์บ์ฑ์ ์ฟผ๋ฆฌ๋ฅผ Hashingํ์ฌ Key๋ก ์ ์ฅํ๊ณ , ๊ฐ์ Value๋ก ์ ์ฅํ๋ ํํ๋ก ๊ตฌํํ๋ค.
์ฆ, ์ฟผ๋ฆฌ ์์ฒด๋ฅผ Hashํด์ ๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ฉด Hash๊ฐ์ ์กฐํํด์ ๊ฐ์ ๋ฆฌํดํ๋๋ก ํ๋ค.
Key = Hash(SQL)
Value = ์ฟผ๋ฆฌ๊ฒฐ๊ณผ
์ด๊ฑด ๋์ค์ ๊ธฐํ๊ฐ ์๋ค๋ฉด ๋ค์ํ๋ฒ ๋ค๋ฃจ๋๋ก ํ๋ค.
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ๊ธฐ๋ณธ์ ์ธ GET/GET ํ์ฉ
127.0.0.1:6379> set name "user01"
OK
127.0.0.1:6379> get name
"user01"
# ๊ฐ ํ์ธ
127.0.0.1:6379> EXISTS name
(integer) 1
# ํ์
์ ๊ฒ
127.0.0.1:6379> type name
string
# SETNX ํ์ฉ
127.0.0.1:6379> SETNX mykey "Hello"
(integer) 1 # ๋ฐํ๊ฐ: 1 (mykey๊ฐ ์กด์ฌํ์ง ์์์ ์ค์ ๋จ)
127.0.0.1:6379> SETNX mykey "World"
(integer) 0 # ๋ฐํ๊ฐ: 0 (mykey๊ฐ ์ด๋ฏธ ์กด์ฌํจ)
127.0.0.1:6379> GET mykey
"Hello"
# ๊ฐ์ JSON์ผ๋ก, TTL ์ถ๊ฐ
127.0.0.1:6379> SET session:user01 "{\"user_id\":user01,\"username\":\"lina\",\"login_time\":\"2024-12-07T10:00:00Z\"}" EX 100
OK
# TTL ํ์ธ
127.0.0.1:6379> TTL session:user01
(integer) 94
# TTL ์ฐ์ฅ
127.0.0.1:6379> EXPIRE session:user01 3600
(integer) 1
127.0.0.1:6379> TTL session:user01
(integer) 3598
# ๊ฐ ์ญ์
127.0.0.1:6379> DEL session:user01
(integer) 1
127.0.0.1:6379> GET session:user01
(nil)
2. Lists (๋ฆฌ์คํธ)
- https://redis.io/docs/latest/develop/data-types/lists/
List๋ ๋ฌธ์์ด์ ์์๋๋ก ์ ์ฅํ๋ ๋ฐ์ดํฐ ํ์
์ด๋ค.
์๋ฐฉํฅ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ก ๊ตฌ์ฑ๋์ด์์ด ์์ชฝ ๋์์ Push/Pop ๊ฐ๋ฅํ๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
LPUSH key value # ์ผ์ชฝ(head)์ ์ถ๊ฐ RPUSH key value # ์ค๋ฅธ์ชฝ(tail)์ ์ถ๊ฐ LPOP key # ์ผ์ชฝ์์ ์ ๊ฑฐ ๋ฐ ๋ฐํ RPOP key # ์ค๋ฅธ์ชฝ์์ ์ ๊ฑฐ ๋ฐ ๋ฐํ |
- ํ์ฉ์ฌ๋ก
- ๋ฉ์ธ์ง ํ, ์์ ๋๊ธฐ์ด
- ์ต๊ทผ ๊ฒ์๋ฌผ ๋ชฉ๋ก
- ์์ ๋ฏธ๋์ด ํ์๋ผ์ธ
Lists๋ FIFO(First in, First Out) ํ ์์คํ
์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
๋ฉ์ธ์ง ํ๋ก ํ์ฉํ ๋๋ ๋ธ๋กํนํ(BLPOP)์ ํ์ฉํ๋๊ฒ์ด ์ข์ผ๋ฉฐ, ์ด๋๋ ๋ณ๋๋ก ๊ณต๋ถํ๋๊ฒ์ด ์ข๋ค.
โ ๏ธ์ฃผ์์ฌํญโ ๏ธ
Redis๋ ๋ฐ์ดํฐ์ ๋ด๊ตฌ์ฑ์ ๋ณด์ฅํ์ง ์์ผ๋ฏ๋ก(์บ์ฑ ํนํ), ๋ฐ์ดํฐ๊ฐ ์์ค๋ ์ ์์์ ์ธ์งํด์ผํ๋ค.
Redis๋ In-memory ๊ธฐ๋ฐ์ ๋ฐ์ดํฐ ์ ์ฅ์์ด๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋งค์ฐ ๋น ๋ฅด๊ณ , ๋น๊ต์ ๊ฐ๋จํ๊ฒ ํ๋ฅผ ๊ตฌํํ ์ ์๋ค.
ํ์ง๋ง ์๋ฒ๊ฐ ์ฌ์์๋๊ฑฐ๋ ์ฅ์ ๊ฐ ๋ฐ์ ์ ๋ฐ์ดํฐ๊ฐ ์์ค๋ ์ ์์ผ๋ฉฐ, ๋ฉ์์ง ๋ธ๋ก์ปค๋ก์์ ๊ณ ๊ธ ๊ธฐ๋ฅ(์ฌ์๋ ๋ฑ)๋ ๋ถ์กฑํ๋ค.
๋ฐ๋ผ์, Redis๋ ๋น ๋ฅธ ์ฒ๋ฆฌ ์๋๊ฐ ํ์ํ๊ณ ๋ฐ์ดํฐ ์์ค์ด ํฐ ๋ฌธ์ ๊ฐ ๋์ง ์๋ ๊ฒฝ์ฐ์ ์ ํฉํ๋ฉฐ, ๋ด๊ตฌ์ฑ์ด ์ค์ํ ๊ฒฝ์ฐ์๋ Kafka์ ๊ฐ์ ๋ค๋ฅธ ์๋ฃจ์
์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ข๋ค.
Redis Database Backup(RDB), Append Only File(AOF) ์ค์ ์ ์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ๋์คํฌ์ ์ฐ๋๋ก ๊ตฌ์ฑํ ์๋ ์์ง๋ง,
RDB์ค์ ์ ๋ง์ง๋ง ์ค๋
์ท ์ดํ์ ๋ฐ์ดํฐ๊ฐ ์์ค๋ ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์๊ณ , AOF๋ appendfsync always๋ฅผ ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ์ ์ํฅ์ ์ฃผ๊ณ appendfsync everysec๋ฅผ ์ฌ์ฉํ์ฌ 1์ด๋ง๋ค ์ ์ฅํ๊ฒ ์ค์ ํ๋๋ผ๋ ์ต๋ 1์ด์ ๋ฐ์ดํฐ ์์ค์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
์ฆ, ์๋ฌด๋ฆฌ ์ค์ ํด๋ ์ ํต์ ์ธ RDBMS์ฒ๋ผ ๋ฐ์ดํฐ ๋ด๊ตฌ์ฑ(Durability)์ ๋ณด์ฅํ์ง ์๋๋ค.
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ๋ฆฌ์คํธ ์์ฑ
127.0.0.1:6379> RPUSH numbers 1 2 3 4 5
(integer) 5
# 1. ์ ์ฒด ๋ฒ์ ์กฐํ
127.0.0.1:6379> LRANGE numbers 0 -1 (0์ ์์์ธ๋ฑ์ค, -1์ ๋ง์ง๋ง ์ธ๋ฑ์ค๋ฅผ ๋ปํ๋ค)
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
# 2. ์ฒ์ 3๊ฐ๋ง ์กฐํ (0,1,2 ์ธ๋ฑ์ค)
127.0.0.1:6379> LRANGE numbers 0 2
1) "1"
2) "2"
3) "3"
# 3. 2๋ฒ์งธ๋ถํฐ 4๋ฒ์งธ๊น์ง ์กฐํ
127.0.0.1:6379> LRANGE numbers 1 3
1) "2"
2) "3"
3) "4"
# 4. ๋ง์ง๋ง 2๊ฐ ์กฐํ (์์ ์ธ๋ฑ์ค ์ฌ์ฉ)
127.0.0.1:6379> LRANGE numbers -2 -1
1) "4"
2) "5"
# ์ค๋ฅธ์ชฝ์ ๊ฐ ์ถ๊ฐ
127.0.0.1:6379> RPUSH numbers 6
(integer) 6
127.0.0.1:6379> LRANGE numbers 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
# ์ผ์ชฝ์ ๊ฐ ์ถ๊ฐ
127.0.0.1:6379> LPUSH numbers 7
(integer) 7
127.0.0.1:6379> LRANGE numbers 0 -1
1) "7"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
7) "6"
# ๋ฆฌ์คํธ ๊ธธ์ด ํ์ธ
127.0.0.1:6379> LLEN numbers
(integer) 7
# ํน์ ์ธ๋ฑ์ค ๊ฐ ์กฐํ
127.0.0.1:6379> LINDEX numbers 3
"3"
# ์ค๋ฅธ์ชฝ์ ๊ฐ ์ ๊ฑฐ
127.0.0.1:6379> RPOP numbers
"6"
127.0.0.1:6379> LRANGE numbers 0 -1
1) "7"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
# ์ผ์ชฝ์ ๊ฐ ์ ๊ฑฐ
127.0.0.1:6379> LPOP numbers
"7"
127.0.0.1:6379> LRANGE numbers 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
# ํน์ ๋ฒ์๋ง ๋จ๊ธฐ๊ณ ์ญ์
127.0.0.1:6379> LTRIM numbers 2 3
OK
127.0.0.1:6379> LRANGE numbers 0 -1
1) "3"
2) "4"
3. Sets (์ )
- https://redis.io/docs/latest/develop/data-types/sets/
Sets์ ์์๊ฐ ์๋ ๋ฌธ์์ด ๋ฐ์ดํฐ ํ์
์ด๋ฉฐ, ์ค๋ณต๋ฐ์ดํฐ๋ฅผ ํ์ฉํ์ง์๋๋ค.
๋ํ, Sets๋ ์งํฉ ์ฐ์ฐ(๊ต์งํฉ, ํฉ์งํฉ ๋ฑ)์ ์ง์ํ์ฌ, ๋ฐ์ดํฐ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ฝ๊ฒ ๋ถ์ํ ์ ์๋ค.
๋ฐ๋ผ์, ์์๋ ์ค์ํ์ง ์์ง๋ง ์ค๋ณต๋๋ฉด ์๋๋ ๋ฐ์ดํฐ๋ค์ ์ ์ฅํ๊ฑฐ๋ ์ผ๋ฐ์ ์ธ ์งํฉ์ฐ์ฐ(๊ต์งํฉ, ํฉ์งํฉ, ์ฐจ์งํฉ)์ ์ ํฉํ๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
SADD key member # ์ธํธ์ ์๋ก์ด ๋ฉค๋ฒ๋ฅผ ์ถ๊ฐ SREM key member # ์ง์ ๋ ๋ฉค๋ฒ๋ฅผ ์งํฉ์์ ์ ๊ฑฐ SISMEMBER key member # ๋ฌธ์์ด์ ์งํฉ ๋ฉค๋ฒ์ญ ํ ์คํธ SINTER key1 key2 ... # ๋ ๊ฐ ์ด์์ ์งํฉ์ด ๊ณตํต์ ์ผ๋ก ๊ฐ์ง๊ณ ์๋ ๋ฉค๋ฒ ์งํฉ(์ฆ, ๊ต์งํฉ) ๋ฐํ SCARD key # ์งํฉ์ ํฌ๊ธฐ(์ผ๋ช ์นด๋๋๋ฆฌํฐ) ๋ฐํ |
- ํ์ฉ์ฌ๋ก
- ํน์ ๋ธ๋ก๊ทธ ๊ฒ์๊ธ์ ์ก์ธ์ค ํ๋ IP๋ฆฌ์คํธ
- ํ๊ทธ ์์คํ (ํน์ ํ๊ทธ๋ก ์กฐํ ํด์ผํ ๋ ์งํฉ์ฐ์ฐ)
- ํ๋ก์ฐ/ํ๋ก์ ์์คํ
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ์ธํธ์ ์๋ก์ด ๊ฐ ์ ์ฅ
127.0.0.1:6379> SADD myset "apple"
(integer) 1
127.0.0.1:6379> SADD myset "banana"
(integer) 1
127.0.0.1:6379> SADD myset "cherry"
(integer) 1
# ์ธํธ ๋ฐ์ดํฐ ์กฐํ
127.0.0.1:6379> SMEMBERS myset
1) "apple"
2) "banana"
3) "cherry"
# ์ธํธ์ ๋ฐ์ดํฐ ์ ๊ฑฐ
127.0.0.1:6379> SREM myset "banana"
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "apple"
2) "cherry"
# ์ธํธ ์ญ์
127.0.0.1:6379> DEL myset
(integer) 1
127.0.0.1:6379> SMEMBERS myset
(empty array)
# ๊ต์งํฉ/ํฉ์งํฉ/์ฐจ์งํฉ
127.0.0.1:6379> SADD set1 "apple" "banana" "cherry"
(integer) 3
127.0.0.1:6379> SADD set2 "banana" "cherry" "melon"
(integer) 3
127.0.0.1:6379> SINTER set1 set2 # ๊ต์งํฉ (SINTER)
1) "banana"
2) "cherry"
127.0.0.1:6379> SUNION set1 set2 # ํฉ์งํฉ (SUNION)
1) "apple"
2) "banana"
3) "cherry"
4) "melon"
127.0.0.1:6379> SDIFF set1 set2 # ์ฐจ์งํฉ (SDIFF)
1) "apple"
127.0.0.1:6379> SDIFF set2 set1 # ์ฐจ์งํฉ (SDIFF)
1) "melon"
4. Sorted sets (์ํฐ๋ ์ )
- https://redis.io/docs/latest/develop/data-types/sorted-sets/
Sorted sets์ Sets๊ณผ ๋น์ทํ ํน์ง์ ๊ฐ์ง์ง๋ง ๊ฐ ๋งด๋ฒ๊ฐ Score๋ฅผ ๊ฐ์ง๋ฉฐ, Score๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋ ๋ฐ์ดํฐ ํ์
์ด๋ค.
์ฆ, ์ค๋ณต์ ๊ฑฐ๊ฐ ๊ฐ๋ฅํ๊ณ , ์งํฉ ์ฐ์ฐ์ ํนํ๋์ด ์์ผ๋ฉด์๋, Score๋ฅผ ๊ฐ์ง๋ ํน์ง์ ๊ฐ์ง๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
ZADD key score member # ์ ๋ ฌ๋ ์
์ ๋ฉค๋ฒ์ ์ ์๋ฅผ ์ถ๊ฐ ZREM key member # ์ง์ ๋ ๋ฉค๋ฒ๋ฅผ ์ ๋ ฌ๋ ์ ์์ ์ ๊ฑฐ ZSCORE key member # ํน์ ๋ฉค๋ฒ์ ์ ์๋ฅผ ๋ฐํ ZRANGE key start stop # ์ง์ ๋ ๋ฒ์์ ๋ฉค๋ฒ๋ฅผ ๋ฐํ (์ ์ ๊ธฐ์ค ์ค๋ฆ์ฐจ์) ZREVRANGE key start stop # ์ง์ ๋ ๋ฒ์์ ๋ฉค๋ฒ๋ฅผ ๋ฐํ (์ ์ ๊ธฐ์ค ๋ด๋ฆผ์ฐจ์) ZRANK key member # ํน์ ๋ฉค๋ฒ์ ์์๋ฅผ ๋ฐํ (์ค๋ฆ์ฐจ์) ZCARD key # ์ ๋ ฌ๋ ์ ์ ํฌ๊ธฐ(์ผ๋ช ์นด๋๋๋ฆฌํฐ) ๋ฐํ |
- ํ์ฉ์ฌ๋ก
- ๋ฆฌ๋๋ณด๋ (์ ์์ ๋ฐ๋ผ ์์๊ฐ ๋งค๊ฒจ์ง๋ ์์คํ )
- ์ฐ์ ์์ ํ
- ํ์์คํฌํ ๊ธฐ๋ฐ์ ๋ฐ์ดํฐ ์ ๋ ฌ
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ์ธํธ์ ์๋ก์ด ๊ฐ(๋ฉค๋ฒ) ์ ์ฅ
127.0.0.1:6379> ZADD leaderboard 100 "Alice"
(integer) 1
127.0.0.1:6379> ZADD leaderboard 72 "Bob"
(integer) 1
127.0.0.1:6379> ZADD leaderboard 88 "Charlie"
(integer) 1
# ๊ฐ(๋งด๋ฒ) ์กฐํ
127.0.0.1:6379> ZRANGE leaderboard 0 -1 # ์ค๋ฆ์ฐจ์์ผ๋ก ์ ์ฒด ๋ฒ์ ์กฐํ
1) "Bob"
2) "Charlie"
3) "Alice"
127.0.0.1:6379> ZREVRANGE leaderboard 0 -1 # ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ์ฒด ๋ฒ์ ์กฐํ
1) "Alice"
2) "Charlie"
3) "Bob"
# ํน์ ๋งด๋ฒ์ ๊ฐ ๋ฐํ
127.0.0.1:6379> ZSCORE leaderboard "Bob"
"72"
# ํน์ ๋งด๋ฒ์ ์์ ๋ฐํ
127.0.0.1:6379> ZRANK leaderboard "Charlie"
(integer) 1
# ์ ๋ ฌ๋ ์
์ ํฌ๊ธฐ ๋ฐํ
127.0.0.1:6379> ZCARD leaderboard
(integer) 3
# ๋งด๋ฒ์ ์ ์ ํจ๊ป ์กฐํ
127.0.0.1:6379> ZRANGE leaderboard 0 -1 WITHSCORES # ์ค๋ฆ์ฐจ์
1) "Bob"
2) "72"
3) "Charlie"
4) "88"
5) "Alice"
6) "100"
127.0.0.1:6379> ZREVRANGE leaderboard 0 -1 WITHSCORES # ๋ด๋ฆผ์ฐจ์
1) "Alice"
2) "100"
3) "Charlie"
4) "88"
5) "Bob"
6) "72"
# ๋งด๋ฒ ์ ๊ฑฐ
127.0.0.1:6379> ZREM leaderboard "Alice"
(integer) 1
127.0.0.1:6379> ZRANGE leaderboard 0 -1 WITHSCORES
1) "Bob"
2) "72"
3) "Charlie"
4) "88"
5. Hashes (ํด์)
- https://redis.io/docs/latest/develop/data-types/hashes/
Hash๋ ๊ฐ์ field-value ์์ ์ ์ฅํ๋ ๋ฐ์ดํฐ ํ์
์ด๋ค.
์ String ํ์
์์๋ JSON์ ์ ์ฅํ ์ ์์๋๋ฐ, Hash์ ๊ฒฝ์ฐ ๊ฐ๋ณํ๋์ ์ ๊ทผ์ด ๊ฐ๋ฅํ์ฌ ๋ถ๋ถ ์
๋ฐ์ดํธํ๋๋ฐ ๋ ์ฉ์ดํ๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
HSET key field value # ํ๋ ์ด์์ ํ๋์ ๊ฐ ์ค์ HGET key field # ์ฃผ์ด์ง ํ๋์ ๊ฐ ๋ฐํ HMGET key field1 field2 ... # ์ฌ๋ฌ ํ๋ ํ๋ฒ์ ์กฐํ HINCRBY key field increment # ์ฃผ์ด์ง ํ๋์ ๊ฐ์ ์ ๊ณต๋ ์ ์๋งํผ ์ฆ๊ฐ |
- ํ์ฉ์ฌ๋ก
- ์ฌ์ฉ์ ํ๋กํ ์ ์ฅ
- ์ค์ ์ ๋ณด ๊ด๋ฆฌ
- ์ํ ์ ๋ณด ์ ์ฅ
- ๋ณต์กํ ์ธ์ ๋ฐ์ดํฐ ์ ์ฅ
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ๋ฐ์ดํฐ ์ ์ฅ
127.0.0.1:6379> HSET user:user02 username "user02" email "user02@example.com" age "30"
(integer) 3
# ํน์ ํ๋ ์กฐํ
127.0.0.1:6379> HGET user:user02 username
"user02"
# ์ฌ๋ฌ ํ๋ ํ๋ฒ์ ์กฐํ
127.0.0.1:6379> HMGET user:user02 username email age
1) "user02"
2) "user02@example.com"
3) "30"
# ๋ชจ๋ field-value ์กฐํ
127.0.0.1:6379> HGETALL user:user02
1) "username"
2) "user02"
3) "email"
4) "user02@example.com"
5) "age"
6) "30"
# ํน์ ํ๋ ์กด์ฌ ์ฌ๋ถ ํ์ธ
127.0.0.1:6379> HEXISTS user:user02 email
(integer) 1
# ๋ชจ๋ ํ๋ ์ด๋ฆ ์กฐํ
127.0.0.1:6379> HKEYS user:user02
1) "username"
2) "email"
3) "age"
# ๋ชจ๋ ๊ฐ ์กฐํ
127.0.0.1:6379> HVALS user:user02
1) "user02"
2) "user02@example.com"
3) "30"
# ํ๋ ๊ฐ์ ์กฐํ
127.0.0.1:6379> HLEN user:user02
(integer) 3
# ์ซ์ ๊ฐ ์ฆ๊ฐ
127.0.0.1:6379> HINCRBY user:user02 age 2
(integer) 32
# ํน์ ํ๋ ๊ฐ ์์
127.0.0.1:6379> HSET user:user02 username "lina"
(integer) 0 # # ๊ธฐ์กด ํ๋ ์์ ์ 0 ๋ฐํ, ์๋ก์ด ํ๋ ์ถ๊ฐ์ 1 ๋ฐํ
# ํน์ ํ๋ ์ญ์ (ํน์ ํ๋ ์ ํ์ ์ผ๋ก ์ญ์ )
127.0.0.1:6379> HDEL user:user02 username
(integer) 1
# ํค ์์ฒด๋ฅผ ์ ๋ถ ์ญ์
127.0.0.1:6379> DEL user:user02
(integer) 0
HASH ํ์
์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ฅํ ๋ ๋ ๊ฐ์ง ์ธ์ฝ๋ฉ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
์ธ์ฝ๋ฉ์ ์ ํํด์ ์ฌ์ฉํ๋๊ฒ์ด ์๋๋ผ ์๋์ผ๋ก ์ค์ ๋๋ฉฐ,
์ค๊ฐ์ ์กฐ๊ฑด์ด ๋์ผ๋ฉด listpack์์ hashtable๋ก ์๋์ผ๋ก ์ ํ๋๋ค.
๊ตฌ๋ถ | ์ธ์ฝ๋ฉ | ์กฐ๊ฑด | ์ฅ์ |
์์ Hash | Ziplist listpack (7.0์ด์) |
ํ๋ ๊ฐ์๊ฐ 512๊ฐ ์ดํ ๋ชจ๋ ํ๋์ ๊ฐ์ ๊ธธ์ด๊ฐ 64๋ฐ์ดํธ ์ดํ (๋ ์กฐ๊ฑด ๋ชจ๋ ๋ง์กฑํด์ผ ํจ) |
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ ์ ์์ ๋ฐ์ดํฐ์ ์ ๊ทผ์ด ๋น ๋ฆ |
ํฐ Hash | Hashtable | ํ๋ ๊ฐ์๊ฐ 512๊ฐ ์ด๊ณผ ํ๋๋ ๊ฐ์ ๊ธธ์ด๊ฐ 64๋ฐ์ดํธ ์ด๊ณผ |
๋๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ํจ์จ์ ๊ฐ๋ณ ํ๋ ์ ๊ทผ์ด O(1)๋ก ๋งค์ฐ ๋น ๋ฆ ํ๋ ์ถ๊ฐ/์ญ์ ๊ฐ ์์ ๋ก์ ๋ฉ๋ชจ๋ฆฌ ํํธํ๊ฐ ์ ์ |
์ธ์ฝ๋ฉ ๋ฐฉ์์ ํ์ธํด๋ณด์.
# small hash
127.0.0.1:6379> HSET smallhash field1 "123123" field2 "this is data"
(integer) 1
127.0.0.1:6379> OBJECT ENCODING smallhash
"listpack"
# big hash
127.0.0.1:6379> HSET bighash description "This is a very long description that definitely exceeds 64 bytes. We need to make sure it's long enough to trigger the hashtable encoding in Redis. This should do it!"
(integer) 1
127.0.0.1:6379> OBJECT ENCODING bighash
"hashtable"
6. Streams (์คํธ๋ฆผ)
- https://redis.io/docs/latest/develop/data-types/streams/
Streams๋ ๋ก๊ทธ์ ๊ฐ์ ๋ฐ์ดํฐ ์ํ์ค๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ์ดํฐ ํ์
์ผ๋ก, ๋ฉ์์ง ํ์ ์ ์ฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
๊ฐ ๋ฉ์์ง๋ ๊ณ ์ ํ ID๋ฅผ ์์ฑํ๋ฉฐ, ID๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ด๋ ํญ๋ชฉ์ ๊ฒ์ํ๊ฑฐ๋ ํ์ํญ๋ชฉ์ ์ฝ๊ณ ์ฒ๋ฆฌํ ์ ์๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
XADD key ID field value # ์คํธ๋ฆผ์ ์ ๋ฉ์์ง ์ถ๊ฐ XREAD COUNT n STREAMS key ID # ์คํธ๋ฆผ์์ ๋ฉ์์ง ์ฝ๊ธฐ XRANGE # ๋ ID ์ฌ์ด์ ํญ๋ชฉ ๋ฒ์ ๋ฐํ XLEN key # ์คํธ๋ฆผ์ ๊ธธ์ด ๋ฐํ XDEL key ID # ์คํธ๋ฆผ์์ ๋ฉ์์ง ์ญ์ |
- ํ์ฉ์ฌ๋ก
- Pub/Sub
- ์ด๋ฒคํธ ์์ฑ: ์ฌ์ฉ์ ๋์ ํด๋ฆญ ๋ฑ ์ถ์
- ๋ก๊ทธ ์์ง: ์ค์๊ฐ ๋ก๊ทธ ๋ฐ์ดํฐ ์์ง ๋ฐ ๋ถ์ (์, ์ผ์ ๋ชจ๋ํฐ๋ง)
- ๋ฐ์ดํฐ ์คํธ๋ฆฌ๋ฐ: ์ค์๊ฐ ๋ฐ์ดํฐ ํผ๋ ๊ด๋ฆฌ
Redis๋ฅผ Pub/Sub์ผ๋ก ํ์ฉํ๋๊ฒ์ XGROUP ์ปค๋ฉ๋ Docs์์ ์์ธํ ๋ณผ ์ ์์ผ๋ฉฐ, ์๋๋ ๊ฐ๋จํ ์์์ด๋ค.
# ์คํธ๋ฆผ์ ๋ฐ์ดํฐ ์ถ๊ฐ
127.0.0.1:6379> XADD events * type "user_signup" user_id "123"
"1735318144850-0"
127.0.0.1:6379> XADD events * type "purchase" user_id "456" amount "99.99"
"1735318174147-0"
# Subscriber ๊ทธ๋ฃน ์์ฑ
127.0.0.1:6379> XGROUP CREATE events mygroup $ MKSTREAM
OK
# Subscriber ๋ฐ์ดํฐ ์๋น
127.0.0.1:6379> XREADGROUP GROUP mygroup consumer1 COUNT 0 STREAMS events > # ์ฝ์ง์์ ๋ฉ์ธ์ง ์ฝ๊ธฐ
1) 1) "events"
2) 1) 1) "1735318174147-0"
2) 1) "type"
2) "purchase"
3) "user_id"
4) "456"
5) "amount"
6) "99.99"
127.0.0.1:6379> XREADGROUP GROUP mygroup consumer1 COUNT 0 STREAMS events > # ์ฝ์ง ์์ ๋ฉ์ธ์ง ์์
(nil)
127.0.0.1:6379> XREADGROUP GROUP mygroup consumer1 COUNT 0 STREAMS events 0 # ํน์ ๋ฉ์ธ์ง ์ฝ๊ธฐ
1) 1) "events"
2) 1) 1) "1735318174147-0"
2) 1) "type"
2) "purchase"
3) "user_id"
4) "456"
5) "amount"
6) "99.99"
# ๋ฉ์ธ์ง ํ์ธ ์ฒ๋ฆฌ
127.0.0.1:6379> XREADGROUP GROUP mygroup consumer1 COUNT 0 STREAMS events 0
1) 1) "events"
2) 1) 1) "1735318174147-0"
2) 1) "type"
2) "purchase"
3) "user_id"
4) "456"
5) "amount"
6) "99.99"
127.0.0.1:6379> XACK events mygroup 1735318174147-0
(integer) 1
127.0.0.1:6379> XREADGROUP GROUP mygroup consumer1 COUNT 0 STREAMS events 0
1) 1) "events"
2) (empty array)
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ์คํธ๋ฆผ์ ์ ๋ฉ์ธ์ง ์ ์ฅ
127.0.0.1:6379> XADD user_clicks * user_id 1 action "click" page "home"
"1735316702887-0"
127.0.0.1:6379> XADD user_clicks * user_id 2 action "click" page "about"
"1735316712422-0"
127.0.0.1:6379> XADD user_clicks * user_id 1 action "click" page "contact"
"1735316719007-0"
127.0.0.1:6379> XADD user_clicks * user_id 2 action "click" page "log-in"
"1735316729574-0"
# ์คํธ๋ฆผ ๋ฉ์ธ์ง ์ฝ๊ธฐ
127.0.0.1:6379> XREAD COUNT 2 STREAMS user_clicks 0 # 0(์ฒ์)๋ถํฐ 2๊ฐ์ ๋ฉ์ธ์ง๋ฅผ ์ฝ๊ธฐ
1) 1) "user_clicks"
2) 1) 1) "1735316702887-0"
2) 1) "user_id"
2) "1"
3) "action"
4) "click"
5) "page"
6) "home"
2) 1) "1735316712422-0"
2) 1) "user_id"
2) "2"
3) "action"
4) "click"
5) "page"
6) "about"
# ๋ชจ๋ ๋ฉ์ธ์ง ์กฐํ
127.0.0.1:6379> XRANGE user_clicks - +
1) 1) "1735316702887-0"
2) 1) "user_id"
2) "1"
3) "action"
4) "click"
5) "page"
6) "home"
2) 1) "1735316712422-0"
2) 1) "user_id"
2) "2"
3) "action"
4) "click"
5) "page"
6) "about"
3) 1) "1735316719007-0"
2) 1) "user_id"
2) "1"
3) "action"
4) "click"
5) "page"
6) "contact"
4) 1) "1735316729574-0"
2) 1) "user_id"
2) "2"
3) "action"
4) "click"
5) "page"
6) "log-in"
# ์คํธ๋ฆผ ๊ธธ์ด ๋ฐํ
127.0.0.1:6379> XLEN user_clicks
(integer) 4
# ๋ฉ์ธ์ง ์ญ์
127.0.0.1:6379> XDEL user_clicks 1735316719007-0
(integer) 1
127.0.0.1:6379> XRANGE user_clicks - +
1) 1) "1735316702887-0"
2) 1) "user_id"
2) "1"
3) "action"
4) "click"
5) "page"
6) "home"
2) 1) "1735316712422-0"
2) 1) "user_id"
2) "2"
3) "action"
4) "click"
5) "page"
6) "about"
3) 1) "1735316729574-0"
2) 1) "user_id"
2) "2"
3) "action"
4) "click"
5) "page"
6) "log-in"
โ ๏ธ์ฃผ์์ฌํญโ ๏ธ 1. ๋ฐ์ดํฐ ๋ถ๋ฐฐ ์ ์ฅ
Redis Streams์์ ํน์ ํ๋ ๊ฐ์ผ๋ก ์ง์ ํํฐ๋งํ๋ ๊ธฐ๋ฅ์ ์๊ธฐ ๋๋ฌธ์, ์ ์ค์ต ์์๋๋ก ํ๋ก๋์
์ ๊ตฌํํ๋ฉด ํฐ์ผ๋ ์์๋ค.
์๋ง์ ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ์ ๊ฐ์ ธ์์ ์ ํ๋ฆฌ์ผ์ด์
์์ ํํฐ๋งํด์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ์ ์ ํ๊ฒ ๋ถ๋ฐฐํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ ์ฅํ๋๊ฒ์ ์ถ์ฒํ๋ค. (๋ฐ์ดํฐ ํํฐ์
๋ ํน์ ๋ณด์กฐ ์ธ๋ฑ์ค ์ฌ์ฉ์ด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ๋ ํ๋ค)
# ๊ถ์ฅํ์ง์์ : ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋์ ์คํธ๋ฆผ์ ์ ์ฅ
XADD user_clicks * user_id 1 action "click" page "home"
XADD user_clicks * user_id 2 action "click" page "about"
XADD user_clicks * user_id 1 action "click" page "contact"
# ๊ถ์ฅ : ์ ์ ํ ๋ณด์กฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ๋์ ์คํธ๋ฆผ์ ์ ์ฅ
XADD user_clicks:1 * action "click" page "home"
XADD user_clicks:2 * action "click" page "about"
XADD user_clicks:1 * action "click" page "contact"
โ ๏ธ์ฃผ์์ฌํญโ ๏ธ 2. ๋ฐ์ดํฐ ๋ด๊ตฌ์ฑ
์ List์์๋ ์ค๋ช
ํ์ง๋ง, ํ๋ฒ ๋ ๊ฐ์กฐํ๋ค.
Redis๋ ๋ฐ์ดํฐ์ ๋ด๊ตฌ์ฑ์ ๋ณด์ฅํ์ง ์์ผ๋ฏ๋ก(์บ์ฑ ํนํ), ๋ฐ์ดํฐ๊ฐ ์์ค๋ ์ ์์์ ์ธ์งํด์ผํ๋ค.
Redis๋ In-memory ๊ธฐ๋ฐ์ ๋ฐ์ดํฐ ์ ์ฅ์์ด๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋งค์ฐ ๋น ๋ฅด๊ณ , ๋น๊ต์ ๊ฐ๋จํ๊ฒ ํ๋ฅผ ๊ตฌํํ ์ ์๋ค.
ํ์ง๋ง ์๋ฒ๊ฐ ์ฌ์์๋๊ฑฐ๋ ์ฅ์ ๊ฐ ๋ฐ์ ์ ๋ฐ์ดํฐ๊ฐ ์์ค๋ ์ ์์ผ๋ฉฐ, ๋ฉ์์ง ๋ธ๋ก์ปค๋ก์์ ๊ณ ๊ธ ๊ธฐ๋ฅ(์ฌ์๋ ๋ฑ)๋ ๋ถ์กฑํ๋ค.
๋ฐ๋ผ์, Redis๋ ๋น ๋ฅธ ์ฒ๋ฆฌ ์๋๊ฐ ํ์ํ๊ณ ๋ฐ์ดํฐ ์์ค์ด ํฐ ๋ฌธ์ ๊ฐ ๋์ง ์๋ ๊ฒฝ์ฐ์ ์ ํฉํ๋ฉฐ, ๋ด๊ตฌ์ฑ์ด ์ค์ํ ๊ฒฝ์ฐ์๋ Kafka์ ๊ฐ์ ๋ค๋ฅธ ์๋ฃจ์
์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ข๋ค.
Redis Database Backup(RDB), Append Only File(AOF) ์ค์ ์ ์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ๋์คํฌ์ ์ฐ๋๋ก ๊ตฌ์ฑํ ์๋ ์์ง๋ง,
RDB์ค์ ์ ๋ง์ง๋ง ์ค๋
์ท ์ดํ์ ๋ฐ์ดํฐ๊ฐ ์์ค๋ ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์๊ณ , AOF๋ appendfsync always๋ฅผ ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ์ ์ํฅ์ ์ฃผ๊ณ appendfsync everysec๋ฅผ ์ฌ์ฉํ์ฌ 1์ด๋ง๋ค ์ ์ฅํ๊ฒ ์ค์ ํ๋๋ผ๋ ์ต๋ 1์ด์ ๋ฐ์ดํฐ ์์ค์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
์ฆ, ์๋ฌด๋ฆฌ ์ค์ ํด๋ ์ ํต์ ์ธ RDBMS์ฒ๋ผ ๋ฐ์ดํฐ ๋ด๊ตฌ์ฑ(Durability)์ ๋ณด์ฅํ์ง ์๋๋ค.
โบ Special Data Type
1. Beatmaps (๋นํธ๋งต)
https://redis.io/docs/latest/develop/data-types/bitmaps/
Bitmaps๋ Redis์ String ํ์
์ ์ฌ์ฉํ์ฌ ๋นํธ ๋จ์(0/1)์ ์กฐ์์ ์ง์ํ๋ ๋ฐ์ดํฐ ํ์
์ด๋ค.
ํจ์จ์ ์ธ ๋นํธ ์ฐ์ฐ์ ํตํด ๋๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋จํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
SETBIT key offset value # ํน์ ๋นํธ ์์น์ ๊ฐ์ ์ค์ GETBIT key offset # ํน์ ๋นํธ ์์น์ ๊ฐ์ ๋ฐํ BITCOUNT key [start end] # ๋นํธ๋งต์์ 1๋ก ์ค์ ๋ ๋นํธ์ ๊ฐ์ ๋ฐํ BITOP <AND | OR | XOR | NOT> destkey key [key ...]. # ๋นํธ ์ฐ์ฐ ์ํ (AND, OR, XOR, NOT) BITPOS key bit [start [end [BYTE | BIT]]] # ์ง์ ๋ ๊ฐ (0 ๋๋ 1)์ ๊ฐ๋ ์ฒซ ๋ฒ์งธ ๋นํธ ์ธํธ ๋ฐํ |
- ํ์ฉ์ฌ๋ก
- ํ๋๊ทธ ๊ด๋ฆฌ: ์ฌ์ฉ์์ ์ํ๋ ์ค์ ์ ๋นํธ๋ก ๊ด๋ฆฌ
- ์ ๋ํฌ ๋ฐฉ๋ฌธ์ ์ ๊ณ์ฐ: ํน์ ๊ธฐ๊ฐ ๋์์ ๋ฐฉ๋ฌธ์ ์ ํจ์จ์ ์ผ๋ก ๊ณ์ฐ
- ๋๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ: ๋๊ท๋ชจ ๋ฐ์ดํฐ์ ๊ฐ๋จํ ๋นํธ ๊ณ์ฐ
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ๋ฐ์ดํฐ ์
๋ ฅ (ํน์ ์ฌ์ฉ์๊ฐ ๋ฐฉ๋ฌธํ์์ ๊ธฐ๋ก)
127.0.0.1:6379> SETBIT day1:visitors 1 1
(integer) 0
127.0.0.1:6379> SETBIT day1:visitors 2 1
(integer) 0
127.0.0.1:6379> SETBIT day1:visitors 9 1
(integer) 0
# ๋ฐ์ดํฐ ์กฐํ (ํน์ ์ฌ์ฉ์ ๋ฐฉ๋ฌธํ๋์ง ํ์ธ)
127.0.0.1:6379> GETBIT day1:visitors 1
(integer) 1
127.0.0.1:6379> GETBIT day1:visitors 2
(integer) 1
127.0.0.1:6379> GETBIT day1:visitors 3
(integer) 0
# ์ด ์ ๋ํฌ ๋ฐฉ๋ฌธ์ ์ ๊ณ์ฐ
127.0.0.1:6379> BITCOUNT day1:visitors
(integer) 3
# OR ์ฐ์ฐ (Day1, Day2์ ๋ฐฉ๋ฌธํ ์ด ์ฌ์ฉ์)
127.0.0.1:6379> BITOP OR total_visitors day1:visitors day2:visitors
(integer) 2
127.0.0.1:6379> BITCOUNT total_visitors
(integer) 4
# AND ์ฐ์ฐ (Day1, Day2์ ๋ชจ๋ ๋ฐฉ๋ฌธํ ์ฌ์ฉ์)
127.0.0.1:6379> BITOP AND total_visitors day1:visitors day2:visitors
(integer) 2
127.0.0.1:6379> BITCOUNT total_visitors
(integer) 1
2. Geospatial (์ง๋ฆฌ๊ณต๊ฐ)
- https://redis.io/docs/latest/develop/data-types/geospatial/
Geospatial์ Redis์์ ์์น ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์ฒ๋ฆฌํ ์ ์๋ ๋ฐ์ดํฐ ํ์
์ด๋ฉฐ,
์๋์ ๊ฒฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฑฐ๋ฆฌ ๊ณ์ฐ, ๋ฐ๊ฒฝ ๋ด ์์น ๊ฒ์ ๋ฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
GEOADD key longitude latitude member # ์์น ์ ๋ณด๋ฅผ ์ถ๊ฐ GEOPOS key member # ํน์ ๋ฉค๋ฒ์ ์์น ๋ฐํ GEODIST key member1 member2 [unit] # ๋ ์์น ๊ฐ์ ๊ฑฐ๋ฆฌ ๋ฐํ GEORADIUS key longitude latitude radius [unit] # ๋ฐ๊ฒฝ ๋ด ์์น ๊ฒ์ GEORADIUSBYMEMBER key member radius [unit] # ํน์ ๋ฉค๋ฒ๋ฅผ ์ค์ฌ์ผ๋ก ๋ฐ๊ฒฝ ๋ด ์์น ๊ฒ์ |
- ํ์ฉ์ฌ๋ก
- ์์น ๊ธฐ๋ฐ ์๋น์ค: ์ฌ์ฉ์์ ํ์ฌ ์์น๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฃผ๋ณ ์ ๋ณด๋ฅผ ์ ๊ณต
- ๋ฌผ๋ฅ ๋ฐ ๋ฐฐ์ก ๊ด๋ฆฌ: ํน์ ์์น๋ฅผ ์ค์ฌ์ผ๋ก ๋ฐ๊ฒฝ ๋ด ๋ฐฐ์ก์ง ๊ฒ์
- ์ง๋ ๋ฐ ๋ด๋น๊ฒ์ด์ : ๊ฒฝ๋ก ํ์ ๋ฐ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ๋ฐ์ดํฐ ์
๋ ฅ (๋์ ์์น ์ ๋ณด ์
๋ ฅ)
127.0.0.1:6379> GEOADD cities 126.9784 37.5665 "Seoul"
(integer) 1
127.0.0.1:6379> GEOADD cities 129.0756 35.1796 "Busan"
(integer) 1
127.0.0.1:6379> GEOADD cities 116.4074 39.9042 "Beijing"
(integer) 1
127.0.0.1:6379> GEOADD cities 139.6917 35.6895 "Tokyo"
(integer) 1
127.0.0.1:6379> GEOADD cities -0.1276 51.5074 "London"
(integer) 1
127.0.0.1:6379> GEOADD cities -74.0060 40.7128 "New York"
(integer) 1
127.0.0.1:6379> GEOADD cities 2.3522 48.8566 "Paris"
(integer) 1
127.0.0.1:6379> GEOADD cities 151.2093 -33.8688 "Sydney"
(integer) 1
127.0.0.1:6379> GEOADD cities 13.4050 52.5200 "Berlin"
(integer) 1
127.0.0.1:6379> GEOADD cities 55.2708 25.2048 "Dubai"
(integer) 1
127.0.0.1:6379> GEOADD cities 37.6173 55.7558 "Moscow"
(integer) 1
127.0.0.1:6379> GEOADD cities -58.3816 -34.6037 "Buenos Aires"
(integer) 1
# ์กฐํ (์์ธ ์์น ๋ฐํ)
127.0.0.1:6379> GEOPOS cities "Seoul"
1) 1) "126.97840064764022827"
2) "37.5665003062872529"
# ๊ฑฐ๋ฆฌ ๋ฐํ (๋ ๋์ ๊ฐ์ ๊ฑฐ๋ฆฌ)
127.0.0.1:6379> GEODIST cities "Seoul" "Busan" km
"325.1823"
127.0.0.1:6379> GEODIST cities "Seoul" "New York" km
"11055.6856"
# ํน์ ์์น ์ค์ฌ์ ๋์ ๊ฒ์
127.0.0.1:6379> GEORADIUS cities 126.9784 37.5665 50 km
1) "Seoul"
# ํน์ ๋์ ์ค์ฌ์ผ๋ก ๋ฐ๊ฒฝ ๋ด ๊ฒ์
127.0.0.1:6379> GEORADIUSBYMEMBER cities "Paris" 500 km
1) "Paris"
2) "London"
127.0.0.1:6379> GEORADIUSBYMEMBER cities "Seoul" 500 km
1) "Seoul"
2) "Busan"
127.0.0.1:6379> GEORADIUSBYMEMBER cities "Seoul" 1000 km
1) "Beijing"
2) "Busan"
3) "Seoul"
3. HyperLogLog (HLL)
- https://redis.io/docs/latest/develop/data-types/probabilistic/hyperloglogs/
HyperLogLog๋ ๋๊ท๋ชจ ๋ฐ์ดํฐ์
์ ์ ๋ํฌ ์์ ์๋ฅผ ์ถ์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋ฐ์ดํฐ ํ์
์ด๋ค.
์ค์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ง ์๊ณ , ํด์๊ฐ์ ์ฌ์ฉํด์ ์ ๋ํฌ ์์์ ๊ฐ์๋ฅผ ์ถ์ ํ๋๋ฐ ํนํ๋์ด์๋ค.
์ค์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋๊ฒ์ด ์๋์ ์ฃผ์ํ์!
- ํน์ง
- ์ถ์ ๊ธฐ๋ฐ: ์ค์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ง ์๊ณ , ํด์ ๊ฐ์ ์ฌ์ฉํ์ฌ ์ ๋ํฌ ์์์ ๊ฐ์๋ฅผ ์ถ์ ํจ
- ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ฑ: ์ฝ 12KB์ ๊ณ ์ ๋ ๋ฉ๋ชจ๋ฆฌ๋ง ์ฌ์ฉํ์ฌ ์์ญ์ต ๊ฐ์ ์ ๋ํฌ ์์๋ฅผ ์ถ์ ํ ์ ์์
- ์ ํ๋: ์ฝ 0.81%์ ์ค์ฐจ ๋ฒ์ ๋ด์์ ์ ๋ํฌ ์์ ์๋ฅผ ์ถ์ ํจ
- ๊ธฐ๋ณธ ์ปค๋ฉ๋
PFADD key element [element ...] # ์์๋ฅผ HyperLogLog์ ์ถ๊ฐ PFCOUNT key [key ...] # ์ ๋ํฌ ์์์ ์ถ์ ๊ฐ์ ๋ฐํ PFMERGE destkey sourcekey [sourcekey ...] # ์ฌ๋ฌ HyperLogLog๋ฅผ ๋ณํฉ |
- ํ์ฉ์ฌ๋ก
- ์ ๋ํฌ ๋ฐฉ๋ฌธ์ ์ ๊ณ์ฐ: ์น์ฌ์ดํธ์ ์ผ์ผ ์ ๋ํฌ ๋ฐฉ๋ฌธ์ ์ ์ถ์
- ์ด๋ฒคํธ ์นด์ดํ : ๋๊ท๋ชจ ์ด๋ฒคํธ์ ์ ๋ํฌ ๋ฐ์ ํ์ ์ถ์
- ๋ฐ์ดํฐ ๋ถ์: ๋๋์ ๋ฐ์ดํฐ์์ ์ ๋ํฌ ์์ ์๋ฅผ ๋น ๋ฅด๊ฒ ์ถ์
๐๐ ์ค์ต์ ์๋ ๋๋ณด๊ธฐ ํด๋ฆญ ๐๐
# ๋ฐ์ดํฐ ์
๋ ฅ (์ฌ์ฉ์๊ฐ ๋
ธ๋๋ฅผ ์ฌ์ํ ๋๋ง๋ค HLL์ ์ถ๊ฐ)
127.0.0.1:6379> PFADD ROSE_APT "user1"
(integer) 1
127.0.0.1:6379> PFADD ROSE_APT "user2"
(integer) 1
127.0.0.1:6379> PFADD ROSE_APT "user3"
(integer) 1
127.0.0.1:6379> PFADD ROSE_APT "user1"
(integer) 0
# ์ ๋ํฌ ์ฌ์ฉ์ ์ ์ถ์
127.0.0.1:6379> PFCOUNT ROSE_APT
(integer) 3
# ์ฌ๋ฌ ๋
ธ๋์ ์ ๋ํฌ ์ฌ์ฉ์ ์ ๋ณํฉ
127.0.0.1:6379> PFADD AESPA_SUPERNOVA "user2"
(integer) 1
127.0.0.1:6379> PFADD AESPA_SUPERNOVA "user4"
(integer) 1
127.0.0.1:6379> PFMERGE K_POP ROSE_APT AESPA_SUPERNOVA
OK
127.0.0.1:6379> PFCOUNT K_POP
(integer) 4