Skip to content

johnycho/redis-sample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

1 Commit
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Spring Redis ์ž๋ฃŒ๊ตฌ์กฐ ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ

Spring Data Redis์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‹ค์–‘ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.

๐Ÿ“‹ ์ง€์›ํ•˜๋Š” Redis ์ž๋ฃŒ๊ตฌ์กฐ

  1. String - ๊ธฐ๋ณธ์ ์ธ Key-Value ์ €์žฅ
  2. List - ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ
  3. Set - ์ค‘๋ณต์ด ์—†๋Š” ์ง‘ํ•ฉ
  4. Sorted Set - ์ ์ˆ˜๋กœ ์ •๋ ฌ๋˜๋Š” ์ง‘ํ•ฉ
  5. Hash - ํ•„๋“œ-๊ฐ’ ์Œ์˜ ๋งต (๊ฐ์ฒด ์ €์žฅ์— ์œ ์šฉ)
  6. HyperLogLog - ๋Œ€์šฉ๋Ÿ‰ ๊ณ ์œ  ๊ฐ’ ์นด์šดํŒ…
  7. Geo - ์ง€๋ฆฌ์  ์œ„์น˜ ๋ฐ์ดํ„ฐ

๐Ÿš€ ์‹œ์ž‘ํ•˜๊ธฐ

ํ•„์š” ์‚ฌํ•ญ

  • Java 17 ์ด์ƒ
  • Gradle 8.5 ์ด์ƒ (๋˜๋Š” Gradle Wrapper ์‚ฌ์šฉ)
  • Redis ์„œ๋ฒ„ (localhost:6379)

Redis ์„œ๋ฒ„ ์‹คํ–‰

# Docker๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
docker run -d --name redis -p 6379:6379 redis:latest

# ๋˜๋Š” ๋กœ์ปฌ์— ์„ค์น˜๋œ Redis ์‹คํ–‰
redis-server

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰

# Gradle Wrapper๋กœ ๋นŒ๋“œ ๋ฐ ์‹คํ–‰
./gradlew clean build
./gradlew bootRun

# ๋˜๋Š” ๋นŒ๋“œ๋œ JAR ์‹คํ–‰
./gradlew bootJar
java -jar build/libs/redis-sample-1.0.0.jar

์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋˜๋ฉด http://localhost:8080 ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“– Swagger UI๋กœ API ๋ฌธ์„œ ๋ณด๊ธฐ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•œ ํ›„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์•„๋ž˜ URL์— ์ ‘์†ํ•˜์„ธ์š”:

Swagger UI์—์„œ ๋ชจ๋“  API๋ฅผ ์‰ฝ๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๊ณ  ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐ŸŽ‰

๐Ÿ“š API ์‚ฌ์šฉ ์˜ˆ์ œ

์ž๋ฃŒ๊ตฌ์กฐ๋ณ„๋กœ ๋ถ„๋ฆฌ๋œ 8๊ฐœ์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

  • String: /api/redis/string/*
  • List: /api/redis/list/*
  • Set: /api/redis/set/*
  • Sorted Set: /api/redis/sortedset/*
  • Hash: /api/redis/hash/*
  • HyperLogLog: /api/redis/hyperloglog/*
  • Geo: /api/redis/geo/*
  • ๊ณตํ†ต ์ž‘์—…: /api/redis/key/*

1. String ์ž๋ฃŒ๊ตฌ์กฐ

# String ์ €์žฅ
curl -X POST "http://localhost:8080/api/redis/string?key=mykey&value=hello"

# String ์กฐํšŒ
curl -X GET "http://localhost:8080/api/redis/string/mykey"

# TTL๊ณผ ํ•จ๊ป˜ String ์ €์žฅ (60์ดˆ ํ›„ ๋งŒ๋ฃŒ)
curl -X POST "http://localhost:8080/api/redis/string/expire?key=tempkey&value=temporary&seconds=60"

# ์ˆซ์ž ์ฆ๊ฐ€
curl -X POST "http://localhost:8080/api/redis/string/increment/counter"

2. List ์ž๋ฃŒ๊ตฌ์กฐ

# List์— ํ•ญ๋ชฉ ์ถ”๊ฐ€
curl -X POST "http://localhost:8080/api/redis/list/mylist" \
  -H "Content-Type: application/json" \
  -d '["ํ•ญ๋ชฉ1", "ํ•ญ๋ชฉ2", "ํ•ญ๋ชฉ3"]'

# List ์กฐํšŒ
curl -X GET "http://localhost:8080/api/redis/list/mylist"

# List์—์„œ ํ•ญ๋ชฉ ๊บผ๋‚ด๊ธฐ (LPOP)
curl -X DELETE "http://localhost:8080/api/redis/list/mylist/pop"

3. Set ์ž๋ฃŒ๊ตฌ์กฐ

# Set์— ํ•ญ๋ชฉ ์ถ”๊ฐ€
curl -X POST "http://localhost:8080/api/redis/set/myset" \
  -H "Content-Type: application/json" \
  -d '["apple", "banana", "orange", "apple"]'

# Set ์กฐํšŒ (์ค‘๋ณต ์ œ๊ฑฐ๋จ)
curl -X GET "http://localhost:8080/api/redis/set/myset"

# Set ๋ฉค๋ฒ„์‹ญ ํ™•์ธ
curl -X GET "http://localhost:8080/api/redis/set/myset/contains?value=apple"

# ๋‘ Set์˜ ๊ต์ง‘ํ•ฉ
curl -X GET "http://localhost:8080/api/redis/set/intersect?key1=set1&key2=set2"

# ๋‘ Set์˜ ํ•ฉ์ง‘ํ•ฉ
curl -X GET "http://localhost:8080/api/redis/set/union?key1=set1&key2=set2"

4. Sorted Set ์ž๋ฃŒ๊ตฌ์กฐ (์ ์ˆ˜ ๊ธฐ๋ฐ˜ ์ •๋ ฌ)

# Sorted Set์— ํ•ญ๋ชฉ ์ถ”๊ฐ€ (์ ์ˆ˜์™€ ํ•จ๊ป˜)
curl -X POST "http://localhost:8080/api/redis/sortedset/leaderboard?value=player1&score=100"
curl -X POST "http://localhost:8080/api/redis/sortedset/leaderboard?value=player2&score=200"
curl -X POST "http://localhost:8080/api/redis/sortedset/leaderboard?value=player3&score=150"

# ์ ์ˆ˜ ์ˆœ์œผ๋กœ ์กฐํšŒ (์˜ค๋ฆ„์ฐจ์ˆœ)
curl -X GET "http://localhost:8080/api/redis/sortedset/leaderboard/range?start=0&end=9"

# ์ ์ˆ˜ ์ˆœ์œผ๋กœ ์กฐํšŒ (๋‚ด๋ฆผ์ฐจ์ˆœ)
curl -X GET "http://localhost:8080/api/redis/sortedset/leaderboard/reverse?start=0&end=9"

# ํŠน์ • ํ•ญ๋ชฉ์˜ ์ˆœ์œ„์™€ ์ ์ˆ˜ ์กฐํšŒ
curl -X GET "http://localhost:8080/api/redis/sortedset/leaderboard/rank?value=player2"

5. Hash ์ž๋ฃŒ๊ตฌ์กฐ (๊ฐ์ฒด ์ €์žฅ)

# Hash ํ•„๋“œ ์ €์žฅ
curl -X POST "http://localhost:8080/api/redis/hash/myuser/field?field=name&value=ํ™๊ธธ๋™"

# ์‚ฌ์šฉ์ž ๊ฐ์ฒด ์ „์ฒด ์ €์žฅ
curl -X POST "http://localhost:8080/api/redis/hash/user:1/user" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "1",
    "name": "๊น€์ฒ ์ˆ˜",
    "email": "kim@example.com",
    "age": 30
  }'

# Hash ์ „์ฒด ์กฐํšŒ
curl -X GET "http://localhost:8080/api/redis/hash/user:1"

# Hash ํŠน์ • ํ•„๋“œ ์กฐํšŒ
curl -X GET "http://localhost:8080/api/redis/hash/user:1/field?field=name"

# Hash์˜ ๋ชจ๋“  ํ‚ค ์กฐํšŒ
curl -X GET "http://localhost:8080/api/redis/hash/user:1/keys"

6. HyperLogLog (๊ณ ์œ  ๋ฐฉ๋ฌธ์ž ์นด์šดํŒ…)

# HyperLogLog์— ๋ฐฉ๋ฌธ์ž ์ถ”๊ฐ€
curl -X POST "http://localhost:8080/api/redis/hyperloglog/unique-visitors" \
  -H "Content-Type: application/json" \
  -d '["user1", "user2", "user3", "user1"]'

# ๊ณ ์œ  ๋ฐฉ๋ฌธ์ž ์ˆ˜ ์กฐํšŒ (์ค‘๋ณต ์ œ๊ฑฐ๋œ ์นด์šดํŠธ)
curl -X GET "http://localhost:8080/api/redis/hyperloglog/unique-visitors/count"

7. Geo (์ง€๋ฆฌ์  ์œ„์น˜ ๋ฐ์ดํ„ฐ)

# ์œ„์น˜ ์ •๋ณด ์ €์žฅ
curl -X POST "http://localhost:8080/api/redis/geo/cities" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "์„œ์šธ",
    "longitude": 126.9780,
    "latitude": 37.5665
  }'

curl -X POST "http://localhost:8080/api/redis/geo/cities" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "๋ถ€์‚ฐ",
    "longitude": 129.0756,
    "latitude": 35.1796
  }'

# ๋‘ ์ง€์  ๊ฐ„ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ
curl -X GET "http://localhost:8080/api/redis/geo/cities/distance?member1=์„œ์šธ&member2=๋ถ€์‚ฐ"

# ํŠน์ • ์ขŒํ‘œ ์ฃผ๋ณ€ 10km ์ด๋‚ด์˜ ์œ„์น˜ ๊ฒ€์ƒ‰
curl -X GET "http://localhost:8080/api/redis/geo/cities/radius?longitude=126.9780&latitude=37.5665&radius=10"

# ํŠน์ • ์œ„์น˜ ์ฃผ๋ณ€์˜ ๋‹ค๋ฅธ ์œ„์น˜ ๊ฒ€์ƒ‰
curl -X GET "http://localhost:8080/api/redis/geo/cities/radius/member?member=์„œ์šธ&radius=100"

8. ๊ณตํ†ต ์ž‘์—…

# ํ‚ค ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
curl -X GET "http://localhost:8080/api/redis/key/mykey/exists"

# ํ‚ค์— TTL ์„ค์ • (60์ดˆ)
curl -X POST "http://localhost:8080/api/redis/key/mykey/expire?seconds=60"

# ํ‚ค์˜ ๋‚จ์€ TTL ์กฐํšŒ
curl -X GET "http://localhost:8080/api/redis/key/mykey/ttl"

# ํ‚ค ์‚ญ์ œ
curl -X DELETE "http://localhost:8080/api/redis/key/mykey"

๐ŸŽฏ ์‹ค์ „ ํ™œ์šฉ ์‚ฌ๋ก€

String

  • ์บ์‹ฑ (API ์‘๋‹ต, ์„ธ์…˜ ๋“ฑ)
  • ์นด์šดํ„ฐ (์กฐํšŒ์ˆ˜, ์ข‹์•„์š” ์ˆ˜)
  • ๋ถ„์‚ฐ ๋ฝ

List

  • ๋ฉ”์‹œ์ง€ ํ
  • ์ตœ๊ทผ ํ™œ๋™ ํ”ผ๋“œ
  • ์ž‘์—… ๋Œ€๊ธฐ์—ด

Set

  • ํƒœ๊ทธ ์‹œ์Šคํ…œ
  • ํŒ”๋กœ์›Œ/์นœ๊ตฌ ๊ด€๊ณ„
  • ์ค‘๋ณต ์ œ๊ฑฐ

Sorted Set

  • ๋ฆฌ๋”๋ณด๋“œ/๋žญํ‚น
  • ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์ •๋ ฌ (ํƒ€์ž„๋ผ์ธ)
  • ์šฐ์„ ์ˆœ์œ„ ํ

Hash

  • ์‚ฌ์šฉ์ž ํ”„๋กœํ•„
  • ์ƒํ’ˆ ์ •๋ณด
  • ์„ธ์…˜ ์ €์žฅ

HyperLogLog

  • ์ˆœ ๋ฐฉ๋ฌธ์ž ์ˆ˜ (UV)
  • ๊ณ ์œ  ์ด๋ฒคํŠธ ์นด์šดํŒ…
  • ๋Œ€์šฉ๋Ÿ‰ ์ค‘๋ณต ์ œ๊ฑฐ

Geo

  • ์ฃผ๋ณ€ ๊ฒ€์ƒ‰ (์Œ์‹์ , ๋งค์žฅ ๋“ฑ)
  • ๋ฐฐ๋‹ฌ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ
  • ์œ„์น˜ ๊ธฐ๋ฐ˜ ์„œ๋น„์Šค

๐Ÿ›  ์„ค์ •

src/main/resources/application.yml์—์„œ Redis ์—ฐ๊ฒฐ ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

spring:
  data:
    redis:
      host: localhost
      port: 6379
      password: yourpassword  # ํ•„์š”์‹œ

๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

src/main/java/com/sample/redis/
โ”œโ”€โ”€ RedisSampleApplication.java          # ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
โ”œโ”€โ”€ config/
โ”‚   โ”œโ”€โ”€ RedisConfig.java               # Redis ์„ค์ •
โ”‚   โ””โ”€โ”€ SwaggerConfig.java             # Swagger ์„ค์ •
โ”œโ”€โ”€ controller/
โ”‚   โ”œโ”€โ”€ StringRedisController.java     # String ์ž๋ฃŒ๊ตฌ์กฐ API
โ”‚   โ”œโ”€โ”€ ListRedisController.java       # List ์ž๋ฃŒ๊ตฌ์กฐ API
โ”‚   โ”œโ”€โ”€ SetRedisController.java        # Set ์ž๋ฃŒ๊ตฌ์กฐ API
โ”‚   โ”œโ”€โ”€ SortedSetRedisController.java  # Sorted Set ์ž๋ฃŒ๊ตฌ์กฐ API
โ”‚   โ”œโ”€โ”€ HashRedisController.java       # Hash ์ž๋ฃŒ๊ตฌ์กฐ API
โ”‚   โ”œโ”€โ”€ HyperLogLogRedisController.java # HyperLogLog ์ž๋ฃŒ๊ตฌ์กฐ API
โ”‚   โ”œโ”€โ”€ GeoRedisController.java        # Geo ์ž๋ฃŒ๊ตฌ์กฐ API
โ”‚   โ””โ”€โ”€ CommonRedisController.java     # ๊ณตํ†ต ์ž‘์—… API
โ”œโ”€โ”€ service/
โ”‚   โ””โ”€โ”€ RedisDataStructureService.java # ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
โ””โ”€โ”€ model/
    โ”œโ”€โ”€ User.java                      # ์‚ฌ์šฉ์ž ๋ชจ๋ธ
    โ””โ”€โ”€ Location.java                  # ์œ„์น˜ ๋ชจ๋ธ

๐Ÿ’ก ์ถ”๊ฐ€ ๊ธฐ๋Šฅ

  • ๋ชจ๋“  API๋Š” RESTful ๋ฐฉ์‹์œผ๋กœ ์„ค๊ณ„
  • Lombok์„ ์‚ฌ์šฉํ•œ ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ
  • ๋กœ๊น…์„ ํ†ตํ•œ ๋””๋ฒ„๊น… ์ง€์›
  • JSON ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ์ง€์›

๐Ÿ” Redis CLI๋กœ ํ™•์ธํ•˜๊ธฐ

# Redis CLI ์ ‘์†
redis-cli

# ๋ชจ๋“  ํ‚ค ํ™•์ธ
KEYS *

# ํŠน์ • ํ‚ค์˜ ํƒ€์ž… ํ™•์ธ
TYPE mykey

# String ์กฐํšŒ
GET mykey

# List ์กฐํšŒ
LRANGE mylist 0 -1

# Set ์กฐํšŒ
SMEMBERS myset

# Hash ์กฐํšŒ
HGETALL user:1

# Sorted Set ์กฐํšŒ
ZRANGE leaderboard 0 -1 WITHSCORES

๐Ÿ”ง ๋ฌธ์ œ ํ•ด๊ฒฐ

โŒ MOVED ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ

io.lettuce.core.RedisCommandExecutionException: MOVED 6918 127.0.0.1:6380

์›์ธ: Redis๊ฐ€ Cluster ๋ชจ๋“œ๋กœ ์‹คํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• (์ž๋™):

./fix-redis.sh

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• (์ˆ˜๋™):

# 1. ๊ธฐ์กด Redis ์ค‘์ง€
docker stop redis-sample && docker rm redis-sample

# 2. ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋กœ ์žฌ์‹œ์ž‘
docker-compose up -d

# 3. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์žฌ์‹œ์ž‘
./gradlew bootRun

์ƒ์„ธํ•œ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ฐ€์ด๋“œ๋Š” TROUBLESHOOTING.md๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

๐Ÿ“– ์ฐธ๊ณ  ์ž๋ฃŒ

About

Redis Sample

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published