Spring Data Redis์์ ์ ๊ณตํ๋ ๋ค์ํ ์๋ฃ๊ตฌ์กฐ๋ฅผ ํ์ฉํ๋ ์์ ํ๋ก์ ํธ์ ๋๋ค.
- String - ๊ธฐ๋ณธ์ ์ธ Key-Value ์ ์ฅ
- List - ์์๊ฐ ์๋ ๋ฆฌ์คํธ
- Set - ์ค๋ณต์ด ์๋ ์งํฉ
- Sorted Set - ์ ์๋ก ์ ๋ ฌ๋๋ ์งํฉ
- Hash - ํ๋-๊ฐ ์์ ๋งต (๊ฐ์ฒด ์ ์ฅ์ ์ ์ฉ)
- HyperLogLog - ๋์ฉ๋ ๊ณ ์ ๊ฐ ์นด์ดํ
- Geo - ์ง๋ฆฌ์ ์์น ๋ฐ์ดํฐ
- Java 17 ์ด์
- Gradle 8.5 ์ด์ (๋๋ Gradle Wrapper ์ฌ์ฉ)
- Redis ์๋ฒ (localhost:6379)
# 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 ์์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ ํ ๋ธ๋ผ์ฐ์ ์์ ์๋ URL์ ์ ์ํ์ธ์:
- Swagger UI: http://localhost:8080/swagger-ui.html
- OpenAPI JSON: http://localhost:8080/api-docs
Swagger UI์์ ๋ชจ๋ 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/*
# 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"# 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"# 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"# 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"# 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"# 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"# ์์น ์ ๋ณด ์ ์ฅ
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"# ํค ์กด์ฌ ์ฌ๋ถ ํ์ธ
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"- ์บ์ฑ (API ์๋ต, ์ธ์ ๋ฑ)
- ์นด์ดํฐ (์กฐํ์, ์ข์์ ์)
- ๋ถ์ฐ ๋ฝ
- ๋ฉ์์ง ํ
- ์ต๊ทผ ํ๋ ํผ๋
- ์์ ๋๊ธฐ์ด
- ํ๊ทธ ์์คํ
- ํ๋ก์/์น๊ตฌ ๊ด๊ณ
- ์ค๋ณต ์ ๊ฑฐ
- ๋ฆฌ๋๋ณด๋/๋ญํน
- ์๊ฐ ๊ธฐ๋ฐ ์ ๋ ฌ (ํ์๋ผ์ธ)
- ์ฐ์ ์์ ํ
- ์ฌ์ฉ์ ํ๋กํ
- ์ํ ์ ๋ณด
- ์ธ์ ์ ์ฅ
- ์ ๋ฐฉ๋ฌธ์ ์ (UV)
- ๊ณ ์ ์ด๋ฒคํธ ์นด์ดํ
- ๋์ฉ๋ ์ค๋ณต ์ ๊ฑฐ
- ์ฃผ๋ณ ๊ฒ์ (์์์ , ๋งค์ฅ ๋ฑ)
- ๋ฐฐ๋ฌ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
- ์์น ๊ธฐ๋ฐ ์๋น์ค
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
# ๋ชจ๋ ํค ํ์ธ
KEYS *
# ํน์ ํค์ ํ์
ํ์ธ
TYPE mykey
# String ์กฐํ
GET mykey
# List ์กฐํ
LRANGE mylist 0 -1
# Set ์กฐํ
SMEMBERS myset
# Hash ์กฐํ
HGETALL user:1
# Sorted Set ์กฐํ
ZRANGE leaderboard 0 -1 WITHSCORESio.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๋ฅผ ์ฐธ๊ณ ํ์ธ์.